Skip to content

Commit

Permalink
#70 Added defensive null/empty checks to Fail Fast (http://wiki.c2.co…
Browse files Browse the repository at this point in the history
  • Loading branch information
bbottema committed Mar 11, 2017
1 parent 1885c69 commit a99f74c
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 46 deletions.
32 changes: 21 additions & 11 deletions src/main/java/org/simplejavamail/converter/EmailConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.simplejavamail.converter.internal.mimemessage.MimeMessageHelper.produceMimeMessage;
import static org.simplejavamail.internal.util.MiscUtil.extractCID;
import static org.simplejavamail.internal.util.Preconditions.checkNonEmptyArgument;

/**
* Utility to help convert {@link org.simplejavamail.email.Email} instances to other formats (MimeMessage, EML etc.) and vice versa.
Expand All @@ -47,7 +48,7 @@ private EmailConverter() {
public static Email mimeMessageToEmail(@Nonnull final MimeMessage mimeMessage) {
final Email email = new Email(false);
try {
fillEmailFromMimeMessage(email, mimeMessage);
fillEmailFromMimeMessage(email, checkNonEmptyArgument(mimeMessage, "mimeMessage"));
} catch (MessagingException | IOException e) {
throw new EmailConverterException(format(EmailConverterException.PARSE_ERROR_MIMEMESSAGE, e.getMessage()), e);
}
Expand All @@ -59,7 +60,8 @@ public static Email mimeMessageToEmail(@Nonnull final MimeMessage mimeMessage) {
*/
public static Email outlookMsgToEmail(@Nonnull final String msgData) {
final Email email = new Email(false);
fillEmailFromOutlookMessage(email, OutlookMessageParser.parseOutlookMsg(msgData));
OutlookMessage outlookMessage = OutlookMessageParser.parseOutlookMsg(checkNonEmptyArgument(msgData, "msgData"));
fillEmailFromOutlookMessage(email, outlookMessage);
return email;
}

Expand All @@ -68,7 +70,8 @@ public static Email outlookMsgToEmail(@Nonnull final String msgData) {
*/
public static Email outlookMsgToEmail(@Nonnull final File msgfile) {
final Email email = new Email(false);
fillEmailFromOutlookMessage(email, OutlookMessageParser.parseOutlookMsg(msgfile));
OutlookMessage outlookMessage = OutlookMessageParser.parseOutlookMsg(checkNonEmptyArgument(msgfile, "msgfile"));
fillEmailFromOutlookMessage(email, outlookMessage);
return email;
}

Expand All @@ -77,12 +80,15 @@ public static Email outlookMsgToEmail(@Nonnull final File msgfile) {
*/
public static Email outlookMsgToEmail(@Nonnull final InputStream msgInputStream) {
final Email email = new Email(false);
fillEmailFromOutlookMessage(email, OutlookMessageParser.parseOutlookMsg(msgInputStream));
OutlookMessage outlookMessage = OutlookMessageParser.parseOutlookMsg(checkNonEmptyArgument(msgInputStream, "msgInputStream"));
fillEmailFromOutlookMessage(email, outlookMessage);
return email;
}

private static void fillEmailFromMimeMessage(@Nonnull final Email email, @Nonnull final MimeMessage mimeMessage)
throws MessagingException, IOException {
checkNonEmptyArgument(email, "email");
checkNonEmptyArgument(mimeMessage, "mimeMessage");
final MimeMessageParser parser = new MimeMessageParser(mimeMessage).parse();
final InternetAddress from = parser.getFrom();
email.setFromAddress(from.getPersonal(), from.getAddress());
Expand Down Expand Up @@ -113,6 +119,8 @@ private static void fillEmailFromMimeMessage(@Nonnull final Email email, @Nonnul
}

private static void fillEmailFromOutlookMessage(@Nonnull final Email email, @Nonnull final OutlookMessage outlookMessage) {
checkNonEmptyArgument(email, "email");
checkNonEmptyArgument(outlookMessage, "outlookMessage");
email.setFromAddress(outlookMessage.getFromName(), outlookMessage.getFromEmail());
if (!MiscUtil.valueNullOrEmpty(outlookMessage.getReplyToEmail())) {
email.setReplyToAddress(outlookMessage.getReplyToName(), outlookMessage.getReplyToEmail());
Expand Down Expand Up @@ -145,15 +153,15 @@ private static void fillEmailFromOutlookMessage(@Nonnull final Email email, @Non
* @see #emailToMimeMessage(Email, Session)
*/
public static MimeMessage emailToMimeMessage(@Nonnull final Email email) {
return emailToMimeMessage(email, createDummySession());
return emailToMimeMessage(checkNonEmptyArgument(email, "email"), createDummySession());
}

/**
* Refer to {@link MimeMessageHelper#produceMimeMessage(Email, Session)}
*/
public static MimeMessage emailToMimeMessage(@Nonnull final Email email, @Nonnull final Session session) {
try {
return produceMimeMessage(email, session);
return produceMimeMessage(checkNonEmptyArgument(email, "email"), checkNonEmptyArgument(session, "session"));
} catch (UnsupportedEncodingException | MessagingException e) {
// this should never happen, so we don't acknowledge this exception (and simply bubble up)
throw new RuntimeException(e.getMessage(), e);
Expand All @@ -163,10 +171,10 @@ public static MimeMessage emailToMimeMessage(@Nonnull final Email email, @Nonnul
/**
* @return The result of {@link MimeMessage#writeTo(OutputStream)} which should be in the standard EML format.
*/
public static String mimeMessageToEML(@Nonnull final MimeMessage message) {
public static String mimeMessageToEML(@Nonnull final MimeMessage mimeMessage) {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
message.writeTo(os);
checkNonEmptyArgument(mimeMessage, "mimeMessage").writeTo(os);
return os.toString(UTF_8.name());
} catch (IOException | MessagingException e) {
// this should never happen, so we don't acknowledge this exception (and simply bubble up)
Expand All @@ -180,7 +188,7 @@ public static String mimeMessageToEML(@Nonnull final MimeMessage message) {
* @see #emailToMimeMessage(Email, Session)
*/
public static String emailToEML(@Nonnull final Email email) {
return mimeMessageToEML(emailToMimeMessage(email));
return mimeMessageToEML(emailToMimeMessage(checkNonEmptyArgument(email, "email")));
}

/**
Expand All @@ -189,13 +197,15 @@ public static String emailToEML(@Nonnull final Email email) {
* @see #emailToMimeMessage(Email, Session)
*/
public static MimeMessage emlToMimeMessage(@Nonnull final String eml) {
return emlToMimeMessage(createDummySession(), eml);
return emlToMimeMessage(createDummySession(), checkNonEmptyArgument(eml, "eml"));
}

/**
* Relies on JavaMail's native parser of EML data, {@link MimeMessage#MimeMessage(Session, InputStream)}.
*/
public static MimeMessage emlToMimeMessage(@Nonnull final Session session, @Nonnull final String eml) {
checkNonEmptyArgument(session, "session");
checkNonEmptyArgument(eml, "eml");
try {
return new MimeMessage(session, new ByteArrayInputStream(eml.getBytes(UTF_8)));
} catch (final MessagingException e) {
Expand All @@ -208,7 +218,7 @@ public static MimeMessage emlToMimeMessage(@Nonnull final Session session, @Nonn
* #mimeMessageToEmail(MimeMessage)};
*/
public static Email emlToEmail(@Nonnull final String eml) {
final MimeMessage mimeMessage = emlToMimeMessage(createDummySession(), eml);
final MimeMessage mimeMessage = emlToMimeMessage(createDummySession(), checkNonEmptyArgument(eml, "eml"));
return mimeMessageToEmail(mimeMessage);
}

Expand Down
33 changes: 24 additions & 9 deletions src/main/java/org/simplejavamail/email/Email.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.*;

import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty;
import static org.simplejavamail.internal.util.Preconditions.checkNonEmptyArgument;
import static org.simplejavamail.util.ConfigLoader.Property.*;
import static org.simplejavamail.util.ConfigLoader.getProperty;
import static org.simplejavamail.util.ConfigLoader.hasProperty;
Expand Down Expand Up @@ -117,9 +118,9 @@ public Email(final boolean readFromDefaults) {
@SuppressWarnings("WeakerAccess")
public void signWithDomainKey(@Nonnull final File dkimPrivateKeyFile, @Nonnull final String signingDomain, @Nonnull final String selector) {
this.applyDKIMSignature = true;
this.dkimPrivateKeyFile = dkimPrivateKeyFile;
this.signingDomain = signingDomain;
this.selector = selector;
this.dkimPrivateKeyFile = checkNonEmptyArgument(dkimPrivateKeyFile, "dkimPrivateKeyFile");
this.signingDomain = checkNonEmptyArgument(signingDomain, "signingDomain");
this.selector = checkNonEmptyArgument(selector, "selector");
}

/**
Expand All @@ -140,9 +141,9 @@ public void signWithDomainKey(@Nonnull final File dkimPrivateKeyFile, @Nonnull f
@SuppressWarnings("WeakerAccess")
public void signWithDomainKey(@Nonnull final InputStream dkimPrivateKeyInputStream, @Nonnull final String signingDomain, @Nonnull final String selector) {
this.applyDKIMSignature = true;
this.dkimPrivateKeyInputStream = dkimPrivateKeyInputStream;
this.signingDomain = signingDomain;
this.selector = selector;
this.dkimPrivateKeyInputStream = checkNonEmptyArgument(dkimPrivateKeyInputStream, "dkimPrivateKeyInputStream");
this.signingDomain = checkNonEmptyArgument(signingDomain, "signingDomain");
this.selector = checkNonEmptyArgument(selector, "selector");
}

/**
Expand All @@ -152,7 +153,7 @@ public void signWithDomainKey(@Nonnull final InputStream dkimPrivateKeyInputStre
* @param fromAddress The sender's email address.
*/
public void setFromAddress(@Nullable final String name, @Nonnull final String fromAddress) {
fromRecipient = new Recipient(name, fromAddress, null);
fromRecipient = new Recipient(name, checkNonEmptyArgument(fromAddress, "fromAddress"), null);
}

/**
Expand All @@ -162,14 +163,14 @@ public void setFromAddress(@Nullable final String name, @Nonnull final String fr
* @param replyToAddress The replied-to-receiver email address.
*/
public void setReplyToAddress(@Nullable final String name, @Nonnull final String replyToAddress) {
replyToRecipient = new Recipient(name, replyToAddress, null);
replyToRecipient = new Recipient(name, checkNonEmptyArgument(replyToAddress, "replyToAddress"), null);
}

/**
* Bean setter for {@link #subject}.
*/
public void setSubject(@Nonnull final String subject) {
this.subject = subject;
this.subject = checkNonEmptyArgument(subject, "subject");
}

/**
Expand Down Expand Up @@ -197,6 +198,8 @@ public void setTextHTML(@Nullable final String textHTML) {
* @see RecipientType
*/
public void addRecipient(@Nullable final String name, @Nonnull final String address, @Nonnull final RecipientType type) {
checkNonEmptyArgument(address, "address");
checkNonEmptyArgument(type, "type");
recipients.add(new Recipient(name, address, type));
}

Expand All @@ -211,6 +214,9 @@ public void addRecipient(@Nullable final String name, @Nonnull final String addr
* @see #addEmbeddedImage(String, DataSource)
*/
public void addEmbeddedImage(@Nonnull final String name, @Nonnull final byte[] data, @Nonnull final String mimetype) {
checkNonEmptyArgument(name, "name");
checkNonEmptyArgument(data, "data");
checkNonEmptyArgument(mimetype, "mimetype");
final ByteArrayDataSource dataSource = new ByteArrayDataSource(data, mimetype);
dataSource.setName(name);
addEmbeddedImage(name, dataSource);
Expand All @@ -224,6 +230,7 @@ public void addEmbeddedImage(@Nonnull final String name, @Nonnull final byte[] d
*/
@SuppressWarnings("WeakerAccess")
public void addEmbeddedImage(@Nullable final String name, @Nonnull final DataSource imagedata) {
checkNonEmptyArgument(imagedata, "imagedata");
if (valueNullOrEmpty(name) && valueNullOrEmpty(imagedata.getName())) {
throw new EmailException(EmailException.NAME_MISSING_FOR_EMBEDDED_IMAGE);
}
Expand All @@ -239,6 +246,8 @@ public void addEmbeddedImage(@Nullable final String name, @Nonnull final DataSou
*/
@SuppressWarnings("WeakerAccess")
public void addHeader(@Nonnull final String name, @Nonnull final Object value) {
checkNonEmptyArgument(name, "name");
checkNonEmptyArgument(value, "value");
headers.put(name, String.valueOf(value));
}

Expand All @@ -253,6 +262,10 @@ public void addHeader(@Nonnull final String name, @Nonnull final Object value) {
* @see #addAttachment(String, DataSource)
*/
public void addAttachment(@Nonnull final String name, @Nonnull final byte[] data, @Nonnull final String mimetype) {
checkNonEmptyArgument(name, "name");
checkNonEmptyArgument(data, "data");
checkNonEmptyArgument(mimetype, "mimetype");

final ByteArrayDataSource dataSource = new ByteArrayDataSource(data, mimetype);
dataSource.setName(MiscUtil.encodeText(name));
addAttachment(MiscUtil.encodeText(name), dataSource);
Expand All @@ -265,6 +278,7 @@ public void addAttachment(@Nonnull final String name, @Nonnull final byte[] data
* @param filedata The attachment data.
*/
public void addAttachment(@Nullable final String name, @Nonnull final DataSource filedata) {
checkNonEmptyArgument(filedata, "filedata");
attachments.add(new AttachmentResource(MiscUtil.encodeText(name), filedata));
}

Expand Down Expand Up @@ -383,6 +397,7 @@ public String toString() {
* @param builder The builder from which to create the email.
*/
Email(@Nonnull final EmailBuilder builder) {
checkNonEmptyArgument(builder, "builder");
recipients = builder.getRecipients();
embeddedImages = builder.getEmbeddedImages();
attachments = builder.getAttachments();
Expand Down
Loading

0 comments on commit a99f74c

Please sign in to comment.