- * IMPORTANT:
- * someone@[192.168.1.100] or
- * The RFC says these are valid email addresses, but most people don't like allowing them. If you don't want to allow them,
- * and only want to allow valid domain names (RFC 1035, x.y.z.com, etc),
- * change this constant to false.
- *
- * Its default value is true to remain RFC 2822 compliant, but you should set it depending on what you need for your
- * application.
- * "John Smith" <john.smith@somewhere.com>
- *
- * The RFC says this is a valid mailbox. If you don't want to allow this, because for example, you only want users to enter
- * in a raw address (john.smith@somewhere.com - no quotes or angle brackets), then change this constant to
- * false.
- *
- * Its default value is true to remain RFC 2822 compliant, but you should set it depending on what you need for your
- * application.
+ * someone@[192.168.1.100] or
+ * The RFC says these are valid email addresses, but most people don't like allowing them. If you don't want to allow them,
+ * and only want to allow valid domain names (RFC 1035, x.y.z.com, etc),
+ * change this constant to false.
+ *
+ * Its default value is true to remain RFC 2822 compliant, but you should set it depending on what you need for your
+ * application.
+ * "John Smith" <john.smith@somewhere.com>
+ *
+ * The RFC says this is a valid mailbox. If you don't want to allow this, because for example, you only want users to enter
+ * in a raw address (john.smith@somewhere.com - no quotes or angle brackets), then change this constant to
+ * false.
+ *
+ * Its default value is true to remain RFC 2822 compliant, but you should set it depending on what you need for your
+ * application.
- * From the original author:
- * Code sanitized by Benny Bottema (kept validation 100% in tact).
- *
- * @author Les Hazlewood, Benny Bottema
- * @see EmailAddressValidationCriteria
- */
-public final class EmailValidationUtil {
-
- /**
- * Private constructor; this is a utility class with static methods only, not designed for extension.
- */
- private EmailValidationUtil() {
- //
- }
-
- /**
- * Validates an e-mail with default validation flags that remains
+ * From the original author:
+ * Code sanitized by Benny Bottema (kept validation 100% in tact).
+ *
+ * @author Les Hazlewood, Benny Bottema
+ * @see EmailAddressValidationCriteria
+ */
+public final class EmailValidationUtil {
+
+ /**
+ * Private constructor; this is a utility class with static methods only, not designed for extension.
+ */
+ private EmailValidationUtil() {
+ //
+ }
+
+ /**
+ * Validates an e-mail with default validation flags that remains
- * This testclass was designed to run from the commandline (or by Ant) and expects some system properties to be present. See
- * Readme.txt for instructions. Alternatively, you can assign the host, username and password a hard value and ignore the system
- * properties altogether.
- *
+ *
* @author Benny Bottema
*/
public class MailTest {
- /**
- * Just run as Java application, but remember to set the JVM arguments first.
- *
- * @param args should be empty, this demo uses JVM arguments only (-Dhost=value etc.).
- */
- public static void main(final String[] args) {
- final Email email = new Email();
- email.setFromAddress("lollypop", "lol.pop@somemail.com");
- email.addRecipient("C.Cane", "candycane@candyshop.org", RecipientType.TO);
- email.setText("We should meet up!");
- email.setTextHTML("We should meet up!");
- email.setSubject("hey");
- sendMail(email);
- }
+ public static void main(final String[] args) throws IOException, MessagingException {
+ final Email emailNormal = new Email();
+ emailNormal.setFromAddress("lollypop", "lol.pop@somemail.com");
+ // don't forget to add your own address here ->
+ emailNormal.addRecipient("C.Cane", "candycane@candyshop.org", RecipientType.TO);
+ emailNormal.setText("We should meet up!");
+ emailNormal.setTextHTML("We should meet up!");
+ emailNormal.setSubject("hey");
+
+ // add two text files in different ways and a black thumbs up embedded image ->
+ emailNormal.addAttachment("dresscode.txt", new ByteArrayDataSource("Black Tie Optional", "text/plain"));
+ emailNormal.addAttachment("location.txt", "On the moon!".getBytes(), "text/plain");
+ String base64String = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABeElEQVRYw2NgoAAYGxu3GxkZ7TY1NZVloDcAWq4MxH+B+D8Qv3FwcOCgtwM6oJaDMTAUXOhmuYqKCjvQ0pdoDrCnmwNMTEwakC0H4u8GBgYC9Ap6DSD+iewAoIPm0ctyLqBlp9F8/x+YE4zpYT8T0LL16JYD8U26+B7oyz4sloPwenpYno3DchCeROsUbwa05A8eB3wB4kqgIxOAuArIng7EW4H4EhC/B+JXQLwDaI4ryZaDSjeg5mt4LCcFXyIn1fdSyXJQVt1OtMWGhoai0OD8T0W8GohZifE1PxD/o7LlsPLiFNAKRrwOABWptLAcqc6QGDAHQEOAYaAc8BNotsJAOgAUAosG1AFA/AtUoY3YEFhKMAvS2AE7iC1+WaG1H6gY3gzE36hUFJ8mqzbU1dUVBBqQBzTgIDQRkWo5qCZdpaenJ0Zx1aytrc0DDB0foIG1oAYKqC0IZK8D4n1AfA6IzwPxXpCFoGoZVEUDaRGGUTAKRgEeAAA2eGJC+ETCiAAAAABJRU5ErkJggg==";
+ emailNormal.addEmbeddedImage("winksmiley", Base64.getDecoder().decode(base64String), "image/png");
+
+ // let's try producing and then consuming a MimeMessage ->
+ final MimeMessage mimeMessage = Mailer.produceMimeMessage(emailNormal, Session.getDefaultInstance(new Properties()));
+ final Email emailFromMimeMessage = new Email(mimeMessage);
+
+ sendMail(emailNormal);
+ sendMail(emailFromMimeMessage); // should produce the exact same result as emailNormal!
+ }
- private static void sendMail(final Email email) {
- final String host = System.getProperty("host") != null ? System.getProperty("host") : "";
- final int port = System.getProperty("port") != null ? Integer.parseInt(System.getProperty("port")) : 25;
- final String username = System.getProperty("username") != null ? System.getProperty("username") : "";
- final String password = System.getProperty("password") != null ? System.getProperty("password") : "";
- new Mailer(host, port, username, password, TransportStrategy.SMTP_SSL).sendMail(email);
- }
+ private static void sendMail(final Email email) {
+ final String host = System.getProperty("host") != null ? System.getProperty("host") : "";
+ final int port = System.getProperty("port") != null ? Integer.parseInt(System.getProperty("port")) : 25;
+ final String username = System.getProperty("username") != null ? System.getProperty("username") : "";
+ final String password = System.getProperty("password") != null ? System.getProperty("password") : "";
+ new Mailer(host, port, username, password, TransportStrategy.SMTP_SSL).sendMail(email);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/codemonkey/simplejavamail/MailException.java b/src/main/java/org/codemonkey/simplejavamail/MailException.java
index 82afcde20..607c1bd86 100644
--- a/src/main/java/org/codemonkey/simplejavamail/MailException.java
+++ b/src/main/java/org/codemonkey/simplejavamail/MailException.java
@@ -21,13 +21,12 @@ public final class MailException extends RuntimeException {
protected static final String MISSING_RECIPIENT = "Email is not valid: missing recipients";
protected static final String MISSING_SUBJECT = "Email is not valid: missing subject";
protected static final String MISSING_CONTENT = "Email is not valid: missing content body";
- protected static final String PARSE_MIMEMESSAGE_ERROR = "Error parsing MimeMessage: %s";
protected MailException(final String message) {
super(message);
}
- protected MailException(final String message, final Exception cause) {
+ public MailException(final String message, final Exception cause) {
super(message, cause);
}
}
\ No newline at end of file
diff --git a/src/main/java/org/codemonkey/simplejavamail/Mailer.java b/src/main/java/org/codemonkey/simplejavamail/Mailer.java
index 34cd9788f..1d3d8610a 100644
--- a/src/main/java/org/codemonkey/simplejavamail/Mailer.java
+++ b/src/main/java/org/codemonkey/simplejavamail/Mailer.java
@@ -22,6 +22,11 @@
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
+import org.codemonkey.simplejavamail.email.AttachmentResource;
+import org.codemonkey.simplejavamail.email.Email;
+import org.codemonkey.simplejavamail.email.Recipient;
+import org.codemonkey.simplejavamail.util.EmailAddressValidationCriteria;
+import org.codemonkey.simplejavamail.util.EmailValidationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -68,7 +73,7 @@
*/
public class Mailer {
- private static final Logger logger = LoggerFactory.getLogger(Mailer.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(Mailer.class);
/**
* Encoding used for setting body text, email address, headers, reply-to fields etc. ({@value #CHARACTER_ENCODING}).
@@ -159,7 +164,7 @@ public Mailer(final String host, final Integer port, final String username, fina
*/
protected Session createMailSession(final String host, final Integer port, final String username, final String password) {
if (transportStrategy == null) {
- logger.warn("Transport Strategy not set, using plain SMTP strategy instead!");
+ LOGGER.warn("Transport Strategy not set, using plain SMTP strategy instead!");
transportStrategy = TransportStrategy.SMTP_PLAIN;
}
Properties props = transportStrategy.generateProperties();
@@ -167,7 +172,7 @@ protected Session createMailSession(final String host, final Integer port, final
if (port != null) {
props.put(transportStrategy.propertyNamePort(), String.valueOf(port));
} else {
- // let JavaMail's Transport objects determine deault port base don the used protocol
+ // let JavaMail's Transport objects determine default port base don the used protocol
}
if (username != null) {
@@ -205,8 +210,8 @@ public Mailer(final String host, final Integer port, final String username, fina
* let us know why you are needing this on https://github.com/bbottema/simple-java-mail/issues.
*/
public Session getSession() {
- logger.warn("Providing access to Session instance for emergency fall-back scenario. Please let us know why you need it.");
- logger.warn("\t>https://github.com/bbottema/simple-java-mail/issues");
+ LOGGER.warn("Providing access to Session instance for emergency fall-back scenario. Please let us know why you need it.");
+ LOGGER.warn("\t>https://github.com/bbottema/simple-java-mail/issues");
return session;
}
@@ -263,10 +268,10 @@ public final void sendMail(final Email email)
transport.close();
}
} catch (final UnsupportedEncodingException e) {
- logger.error(e.getMessage(), e);
+ LOGGER.error(e.getMessage(), e);
throw new MailException(String.format(MailException.INVALID_ENCODING, e.getMessage()));
} catch (final MessagingException e) {
- logger.error(e.getMessage(), e);
+ LOGGER.error(e.getMessage(), e);
throw new MailException(String.format(MailException.GENERIC_ERROR, e.getMessage()), e);
}
}
@@ -286,7 +291,7 @@ private void logSession(Session session, TransportStrategy transportStrategy) {
} else {
specifics = properties.toString();
}
- logger.debug(String.format("starting mail session (%s)", specifics));
+ LOGGER.debug(String.format("starting mail session (%s)", specifics));
}
/**
@@ -537,7 +542,7 @@ private static class MimeEmailMessageWrapper {
multipartRelated.addBodyPart(contentAlternativeMessages);
contentAlternativeMessages.setContent(multipartAlternativeMessages);
} catch (final MessagingException e) {
- logger.error(e.getMessage(), e);
+ LOGGER.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
diff --git a/src/main/java/org/codemonkey/simplejavamail/AttachmentResource.java b/src/main/java/org/codemonkey/simplejavamail/email/AttachmentResource.java
similarity index 90%
rename from src/main/java/org/codemonkey/simplejavamail/AttachmentResource.java
rename to src/main/java/org/codemonkey/simplejavamail/email/AttachmentResource.java
index 25626e2c8..1c4b4b939 100644
--- a/src/main/java/org/codemonkey/simplejavamail/AttachmentResource.java
+++ b/src/main/java/org/codemonkey/simplejavamail/email/AttachmentResource.java
@@ -1,50 +1,50 @@
-package org.codemonkey.simplejavamail;
-
-import javax.activation.DataSource;
-
-/**
- * A named immutable email attachment information object. The name can be a simple name, a filename or a named embedded
- * image (eg. <cid:footer>). Contains a {@link DataSource} that is compatible with the javax.mail API.
- *
- * @author Benny Bottema
- * @see DataSource
- */
-final class AttachmentResource {
-
- /**
- * @see #AttachmentResource(String, DataSource)
- */
- private final String name;
-
- /**
- * @see #AttachmentResource(String, DataSource)
- */
- private final DataSource dataSource;
-
- /**
- * Constructor; initializes the attachment resource with a name and data.
- *
- * @param name The name of the attachment which can be a simple name, a filename or a named embedded image (eg.
- * <cid:footer>)
- * @param dataSource The attachment data.
- * @see DataSource
- */
- public AttachmentResource(final String name, final DataSource dataSource) {
- this.name = name;
- this.dataSource = dataSource;
- }
-
- /**
- * Bean getter for {@link #dataSource}.
- */
- public DataSource getDataSource() {
- return dataSource;
- }
-
- /**
- * Bean getter for {@link #name}.
- */
- public String getName() {
- return name;
- }
+package org.codemonkey.simplejavamail.email;
+
+import javax.activation.DataSource;
+
+/**
+ * A named immutable email attachment information object. The name can be a simple name, a filename or a named embedded
+ * image (eg. <cid:footer>). Contains a {@link DataSource} that is compatible with the javax.mail API.
+ *
+ * @author Benny Bottema
+ * @see DataSource
+ */
+public class AttachmentResource {
+
+ /**
+ * @see #AttachmentResource(String, DataSource)
+ */
+ private final String name;
+
+ /**
+ * @see #AttachmentResource(String, DataSource)
+ */
+ private final DataSource dataSource;
+
+ /**
+ * Constructor; initializes the attachment resource with a name and data.
+ *
+ * @param name The name of the attachment which can be a simple name, a filename or a named embedded image (eg.
+ * <cid:footer>)
+ * @param dataSource The attachment data.
+ * @see DataSource
+ */
+ public AttachmentResource(final String name, final DataSource dataSource) {
+ this.name = name;
+ this.dataSource = dataSource;
+ }
+
+ /**
+ * Bean getter for {@link #dataSource}.
+ */
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ /**
+ * Bean getter for {@link #name}.
+ */
+ public String getName() {
+ return name;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/codemonkey/simplejavamail/Email.java b/src/main/java/org/codemonkey/simplejavamail/email/Email.java
similarity index 96%
rename from src/main/java/org/codemonkey/simplejavamail/Email.java
rename to src/main/java/org/codemonkey/simplejavamail/email/Email.java
index cc212f820..79867e446 100644
--- a/src/main/java/org/codemonkey/simplejavamail/Email.java
+++ b/src/main/java/org/codemonkey/simplejavamail/email/Email.java
@@ -1,4 +1,7 @@
-package org.codemonkey.simplejavamail;
+package org.codemonkey.simplejavamail.email;
+
+import org.codemonkey.simplejavamail.MailException;
+import org.codemonkey.simplejavamail.util.MimeMessageParser;
import java.io.IOException;
import java.util.ArrayList;
@@ -8,7 +11,6 @@
import java.util.Map;
import javax.activation.DataSource;
-import javax.mail.Address;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
@@ -305,8 +307,6 @@ public static class Builder {
*/
private final Maptrue
.
- *
- * @author Benny Bottema
- * @see #EmailAddressValidationCriteria(boolean, boolean)
- */
-public class EmailAddressValidationCriteria {
-
- private final boolean allowDomainLiterals;
- private final boolean allowQuotedIdentifiers;
-
- /**
- * Criteria which is most RFC 2822 compliant and allows all compiant address forms, including the more exotic ones.
- *
- * @see #EmailAddressValidationCriteria(boolean, boolean)
- */
- public static final EmailAddressValidationCriteria RFC_COMPLIANT = new EmailAddressValidationCriteria(true, true);
-
- /**
- * @param allowDomainLiterals
- *
- * @param allowQuotedIdentifiers
- * john.doe@[23:33:A2:22:16:1F] or
- * me@[my computer]
- *
- *
- */
- public EmailAddressValidationCriteria(boolean allowDomainLiterals, boolean allowQuotedIdentifiers) {
- this.allowDomainLiterals = allowDomainLiterals;
- this.allowQuotedIdentifiers = allowQuotedIdentifiers;
- }
-
- public final boolean isAllowDomainLiterals() {
- return allowDomainLiterals;
- }
-
- public final boolean isAllowQuotedIdentifiers() {
- return allowQuotedIdentifiers;
- }
+package org.codemonkey.simplejavamail.util;
+
+/**
+ * Defines a set of restriction flags for email address validation. To remain completely true to RFC 2822, all flags should be set to
+ * true
.
+ *
+ * @author Benny Bottema
+ * @see #EmailAddressValidationCriteria(boolean, boolean)
+ */
+public class EmailAddressValidationCriteria {
+
+ private final boolean allowDomainLiterals;
+ private final boolean allowQuotedIdentifiers;
+
+ /**
+ * Criteria which is most RFC 2822 compliant and allows all compiant address forms, including the more exotic ones.
+ *
+ * @see #EmailAddressValidationCriteria(boolean, boolean)
+ */
+ public static final EmailAddressValidationCriteria RFC_COMPLIANT = new EmailAddressValidationCriteria(true, true);
+
+ /**
+ * @param allowDomainLiterals
+ *
+ * @param allowQuotedIdentifiers
+ * john.doe@[23:33:A2:22:16:1F] or
+ * me@[my computer]
+ *
+ *
+ */
+ public EmailAddressValidationCriteria(boolean allowDomainLiterals, boolean allowQuotedIdentifiers) {
+ this.allowDomainLiterals = allowDomainLiterals;
+ this.allowQuotedIdentifiers = allowQuotedIdentifiers;
+ }
+
+ public final boolean isAllowDomainLiterals() {
+ return allowDomainLiterals;
+ }
+
+ public final boolean isAllowQuotedIdentifiers() {
+ return allowQuotedIdentifiers;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/codemonkey/simplejavamail/EmailValidationUtil.java b/src/main/java/org/codemonkey/simplejavamail/util/EmailValidationUtil.java
similarity index 97%
rename from src/main/java/org/codemonkey/simplejavamail/EmailValidationUtil.java
rename to src/main/java/org/codemonkey/simplejavamail/util/EmailValidationUtil.java
index 026494d3f..cc368b543 100644
--- a/src/main/java/org/codemonkey/simplejavamail/EmailValidationUtil.java
+++ b/src/main/java/org/codemonkey/simplejavamail/util/EmailValidationUtil.java
@@ -1,107 +1,107 @@
-/*
- * Copyright 2008 Les Hazlewood 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.codemonkey.simplejavamail;
-
-import java.util.regex.Pattern;
-
-/**
- * Validates an email address according to RFC 2822, using regular expressions.
- *
- * If you use this code, please keep the author information in tact and reference my site at leshazlewood.com. Thanks!
- * true
to RFC 2822. This means allowing both domain
- * literals and quoted identifiers.
- *
- * @param email A complete email address.
- * @return Whether the e-mail address is compliant with RFC 2822.
- * @see EmailAddressValidationCriteria#RFC_COMPLIANT
- */
- public static boolean isValid(final String email) {
- return isValid(email, EmailAddressValidationCriteria.RFC_COMPLIANT);
- }
-
- /**
- * Validates an e-mail with given validation flags.
- *
- * @param email A complete email address.
- * @param emailAddressValidationCriteria A set of flags that restrict or relax RFC 2822 compliance.
- * @return Whether the e-mail address is compliant with RFC 2822, configured using the passed in {@link EmailAddressValidationCriteria}.
- * @see EmailAddressValidationCriteria#RFC_COMPLIANT
- */
- public static boolean isValid(final String email, final EmailAddressValidationCriteria emailAddressValidationCriteria) {
- return buildValidEmailPattern(emailAddressValidationCriteria).matcher(email).matches();
- }
-
- protected static Pattern buildValidEmailPattern(EmailAddressValidationCriteria parameterObject) {
- // RFC 2822 2.2.2 Structured Header Field Bodies
- final String wsp = "[ \\t]"; // space or tab
- final String fwsp = wsp + "*";
- // RFC 2822 3.2.1 Primitive tokens
- final String dquote = "\\\"";
- // ASCII Control characters excluding white space:
- final String noWsCtl = "\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F";
- // all ASCII characters except CR and LF:
- final String asciiText = "[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F]";
- // RFC 2822 3.2.2 Quoted characters:
- // single backslash followed by a text char
- final String quotedPair = "(\\\\" + asciiText + ")";
- // RFC 2822 3.2.4 Atom:
- final String atext = "[a-zA-Z0-9\\!\\#\\$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~]";
- final String atom = fwsp + atext + "+" + fwsp;
- final String dotAtomText = atext + "+" + "(" + "\\." + atext + "+)*";
- final String dotAtom = fwsp + "(" + dotAtomText + ")" + fwsp;
- // RFC 2822 3.2.5 Quoted strings:
- // noWsCtl and the rest of ASCII except the doublequote and backslash characters:
- final String qtext = "[" + noWsCtl + "\\x21\\x23-\\x5B\\x5D-\\x7E]";
- final String qcontent = "(" + qtext + "|" + quotedPair + ")";
- final String quotedString = dquote + "(" + fwsp + qcontent + ")*" + fwsp + dquote;
- // RFC 2822 3.2.6 Miscellaneous tokens
- final String word = "((" + atom + ")|(" + quotedString + "))";
- final String phrase = word + "+"; // one or more words.
- // RFC 1035 tokens for domain names:
- final String letter = "[a-zA-Z]";
- final String letDig = "[a-zA-Z0-9]";
- final String letDigHyp = "[a-zA-Z0-9-]";
- final String rfcLabel = letDig + "(" + letDigHyp + "{0,61}" + letDig + ")?";
- final String rfc1035DomainName = rfcLabel + "(\\." + rfcLabel + ")*\\." + letter + "{2,6}";
- // RFC 2822 3.4 Address specification
- // domain text - non white space controls and the rest of ASCII chars not including [, ], or \:
- final String dtext = "[" + noWsCtl + "\\x21-\\x5A\\x5E-\\x7E]";
- final String dcontent = dtext + "|" + quotedPair;
- final String domainLiteral = "\\[" + "(" + fwsp + dcontent + "+)*" + fwsp + "\\]";
- final String rfc2822Domain = "(" + dotAtom + "|" + domainLiteral + ")";
- final String domain = parameterObject.isAllowDomainLiterals() ? rfc2822Domain : rfc1035DomainName;
- final String localPart = "((" + dotAtom + ")|(" + quotedString + "))";
- final String addrSpec = localPart + "@" + domain;
- final String angleAddr = "<" + addrSpec + ">";
- final String nameAddr = "(" + phrase + ")?" + fwsp + angleAddr;
- final String mailbox = nameAddr + "|" + addrSpec;
- // now compile a pattern for efficient re-use:
- // if we're allowing quoted identifiers or not:
- final String patternString = parameterObject.isAllowQuotedIdentifiers() ? mailbox : addrSpec;
- return Pattern.compile(patternString);
- }
+/*
+ * Copyright 2008 Les Hazlewood 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.codemonkey.simplejavamail.util;
+
+import java.util.regex.Pattern;
+
+/**
+ * Validates an email address according to RFC 2822, using regular expressions.
+ *
+ * If you use this code, please keep the author information in tact and reference my site at leshazlewood.com. Thanks!
+ * true
to RFC 2822. This means allowing both domain
+ * literals and quoted identifiers.
+ *
+ * @param email A complete email address.
+ * @return Whether the e-mail address is compliant with RFC 2822.
+ * @see EmailAddressValidationCriteria#RFC_COMPLIANT
+ */
+ public static boolean isValid(final String email) {
+ return isValid(email, EmailAddressValidationCriteria.RFC_COMPLIANT);
+ }
+
+ /**
+ * Validates an e-mail with given validation flags.
+ *
+ * @param email A complete email address.
+ * @param emailAddressValidationCriteria A set of flags that restrict or relax RFC 2822 compliance.
+ * @return Whether the e-mail address is compliant with RFC 2822, configured using the passed in {@link EmailAddressValidationCriteria}.
+ * @see EmailAddressValidationCriteria#RFC_COMPLIANT
+ */
+ public static boolean isValid(final String email, final EmailAddressValidationCriteria emailAddressValidationCriteria) {
+ return buildValidEmailPattern(emailAddressValidationCriteria).matcher(email).matches();
+ }
+
+ protected static Pattern buildValidEmailPattern(EmailAddressValidationCriteria parameterObject) {
+ // RFC 2822 2.2.2 Structured Header Field Bodies
+ final String wsp = "[ \\t]"; // space or tab
+ final String fwsp = wsp + "*";
+ // RFC 2822 3.2.1 Primitive tokens
+ final String dquote = "\\\"";
+ // ASCII Control characters excluding white space:
+ final String noWsCtl = "\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F";
+ // all ASCII characters except CR and LF:
+ final String asciiText = "[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F]";
+ // RFC 2822 3.2.2 Quoted characters:
+ // single backslash followed by a text char
+ final String quotedPair = "(\\\\" + asciiText + ")";
+ // RFC 2822 3.2.4 Atom:
+ final String atext = "[a-zA-Z0-9\\!\\#\\$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~]";
+ final String atom = fwsp + atext + "+" + fwsp;
+ final String dotAtomText = atext + "+" + "(" + "\\." + atext + "+)*";
+ final String dotAtom = fwsp + "(" + dotAtomText + ")" + fwsp;
+ // RFC 2822 3.2.5 Quoted strings:
+ // noWsCtl and the rest of ASCII except the doublequote and backslash characters:
+ final String qtext = "[" + noWsCtl + "\\x21\\x23-\\x5B\\x5D-\\x7E]";
+ final String qcontent = "(" + qtext + "|" + quotedPair + ")";
+ final String quotedString = dquote + "(" + fwsp + qcontent + ")*" + fwsp + dquote;
+ // RFC 2822 3.2.6 Miscellaneous tokens
+ final String word = "((" + atom + ")|(" + quotedString + "))";
+ final String phrase = word + "+"; // one or more words.
+ // RFC 1035 tokens for domain names:
+ final String letter = "[a-zA-Z]";
+ final String letDig = "[a-zA-Z0-9]";
+ final String letDigHyp = "[a-zA-Z0-9-]";
+ final String rfcLabel = letDig + "(" + letDigHyp + "{0,61}" + letDig + ")?";
+ final String rfc1035DomainName = rfcLabel + "(\\." + rfcLabel + ")*\\." + letter + "{2,6}";
+ // RFC 2822 3.4 Address specification
+ // domain text - non white space controls and the rest of ASCII chars not including [, ], or \:
+ final String dtext = "[" + noWsCtl + "\\x21-\\x5A\\x5E-\\x7E]";
+ final String dcontent = dtext + "|" + quotedPair;
+ final String domainLiteral = "\\[" + "(" + fwsp + dcontent + "+)*" + fwsp + "\\]";
+ final String rfc2822Domain = "(" + dotAtom + "|" + domainLiteral + ")";
+ final String domain = parameterObject.isAllowDomainLiterals() ? rfc2822Domain : rfc1035DomainName;
+ final String localPart = "((" + dotAtom + ")|(" + quotedString + "))";
+ final String addrSpec = localPart + "@" + domain;
+ final String angleAddr = "<" + addrSpec + ">";
+ final String nameAddr = "(" + phrase + ")?" + fwsp + angleAddr;
+ final String mailbox = nameAddr + "|" + addrSpec;
+ // now compile a pattern for efficient re-use:
+ // if we're allowing quoted identifiers or not:
+ final String patternString = parameterObject.isAllowQuotedIdentifiers() ? mailbox : addrSpec;
+ return Pattern.compile(patternString);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/codemonkey/simplejavamail/MimeMessageParser.java b/src/main/java/org/codemonkey/simplejavamail/util/MimeMessageParser.java
similarity index 77%
rename from src/main/java/org/codemonkey/simplejavamail/MimeMessageParser.java
rename to src/main/java/org/codemonkey/simplejavamail/util/MimeMessageParser.java
index 9a8503f69..a677bdc3a 100644
--- a/src/main/java/org/codemonkey/simplejavamail/MimeMessageParser.java
+++ b/src/main/java/org/codemonkey/simplejavamail/util/MimeMessageParser.java
@@ -15,55 +15,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.codemonkey.simplejavamail;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+package org.codemonkey.simplejavamail.util;
import javax.activation.DataHandler;
import javax.activation.DataSource;
-import javax.mail.Address;
-import javax.mail.Header;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Part;
-import javax.mail.internet.ContentType;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.InternetHeaders;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimePart;
-import javax.mail.internet.MimeUtility;
-import javax.mail.internet.ParseException;
+import javax.mail.*;
+import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
+import java.io.*;
+import java.util.*;
/**
* heavily modified version based on org.apache.commons.mail.util.MimeMessageParser.html
* Parses a MimeMessage and stores the individual parts such a plain text,
* HTML text and attachments.
*
- * @version $Id: MimeMessageParser.java 1632031 2014-10-15 13:51:18Z ggregory $
- * @since 1.3
+ * @version current: MimeMessageParser.java 2016-02-25 Benny Bottema
*/
-class MimeMessageParser {
+public class MimeMessageParser {
private static final List