Skip to content

Commit 7faefe9

Browse files
committed
#29 Restructured packages
#30 Better demonstration test class
1 parent 93d7e95 commit 7faefe9

12 files changed

+416
-468
lines changed

README.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@ Simple Java Mail is available in Maven Central:
1616
<dependency>
1717
<groupId>org.codemonkey.simplejavamail</groupId>
1818
<artifactId>simple-java-mail</artifactId>
19-
<version>2.5.1</version>
19+
<version>3.0.0</version>
2020
</dependency>
2121
```
2222

2323
### Latest Progress ###
2424

25+
v3.0.0
26+
27+
* [#22](https://github.com/bbottema/simple-java-mail/issues/22): Added conversion to and from MimeMessage. You can now consume and produce MimeMessage objects with simple-java-mail
28+
* [#28](https://github.com/bbottema/simple-java-mail/issues/28): Re-added improved email validation facility
29+
* [#29](https://github.com/bbottema/simple-java-mail/issues/29): The package has been restructured for future maintenance, breaking backwards compatibility
30+
2531
v2.5.1
2632

27-
* [#25](https://github.com/bbottema/simple-java-mail/issues/25): Added finally clausule that will always close socket properly in case of an exception
33+
* [#25](https://github.com/bbottema/simple-java-mail/issues/25): Added finally clause that will always close socket properly in case of an exception
2834

2935
v2.5
3036

RELEASE.txt

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@ https://github.com/bbottema/simple-java-mail/
33
<dependency>
44
<groupId>org.codemonkey.simplejavamail</groupId>
55
<artifactId>simple-java-mail</artifactId>
6-
<version>2.5.1</version>
6+
<version>3.0.0</version>
77
</dependency>
88

99
RELEASE NOTES Java Simple Mail
1010

11+
v3.0.0
12+
13+
- #22: Added conversion to and from MimeMessage. You can now consume and produce MimeMessage objects with simple-java-mail
14+
- #28: Re-added improved email validation facility
15+
- #29: The package has been restructured for future maintenance, breaking backwards compatibility
16+
17+
1118
v2.5.1
1219

1320
- #25: Added finally clausule that will always close socket properly in case of an exception
@@ -18,7 +25,7 @@ v2.5
1825

1926
v2.4
2027

21-
- #21: Builder API uses CC and BCC recepient types incorrectly
28+
- #21: Builder API uses CC and BCC recipient types incorrectly
2229

2330

2431
v2.3

pom.xml

+9
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@
6868

6969
<build>
7070
<plugins>
71+
<plugin>
72+
<groupId>org.apache.maven.plugins</groupId>
73+
<artifactId>maven-compiler-plugin</artifactId>
74+
<version>3.5.1</version>
75+
<configuration>
76+
<source>1.6</source>
77+
<target>1.6</target>
78+
</configuration>
79+
</plugin>
7180
<plugin>
7281
<artifactId>maven-release-plugin</artifactId>
7382
<version>2.5.2</version>

src/main/java/MailTest.java

+40-30
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,51 @@
1-
import javax.mail.Message.RecipientType;
2-
3-
import org.codemonkey.simplejavamail.Email;
41
import org.codemonkey.simplejavamail.Mailer;
52
import org.codemonkey.simplejavamail.TransportStrategy;
3+
import org.codemonkey.simplejavamail.email.Email;
4+
5+
import javax.mail.Message.RecipientType;
6+
import javax.mail.MessagingException;
7+
import javax.mail.Session;
8+
import javax.mail.internet.MimeMessage;
9+
import javax.mail.util.ByteArrayDataSource;
10+
import java.io.IOException;
11+
import java.util.Base64;
12+
import java.util.Properties;
613

714
/**
815
* Demonstration program for the Simple Java Mail framework.
9-
* <p>
10-
* <b>IMPORTANT</b>: <br>
11-
* This testclass was designed to run from the commandline (or by Ant) and expects some system properties to be present. See
12-
* <b>Readme.txt</b> for instructions. Alternatively, you can assign the host, username and password a hard value and ignore the system
13-
* properties altogether.
14-
*
16+
*
1517
* @author Benny Bottema
1618
*/
1719
public class MailTest {
1820

19-
/**
20-
* Just run as Java application, but remember to set the JVM arguments first.
21-
*
22-
* @param args should be empty, this demo uses JVM arguments only (-Dhost=value etc.).
23-
*/
24-
public static void main(final String[] args) {
25-
final Email email = new Email();
26-
email.setFromAddress("lollypop", "[email protected]");
27-
email.addRecipient("C.Cane", "[email protected]", RecipientType.TO);
28-
email.setText("We should meet up!");
29-
email.setTextHTML("<b>We should meet up!</b>");
30-
email.setSubject("hey");
31-
sendMail(email);
32-
}
21+
public static void main(final String[] args) throws IOException, MessagingException {
22+
final Email emailNormal = new Email();
23+
emailNormal.setFromAddress("lollypop", "[email protected]");
24+
// don't forget to add your own address here ->
25+
emailNormal.addRecipient("C.Cane", "[email protected]", RecipientType.TO);
26+
emailNormal.setText("We should meet up!");
27+
emailNormal.setTextHTML("<b>We should meet up!</b><img src='cid:winksmiley'>");
28+
emailNormal.setSubject("hey");
29+
30+
// add two text files in different ways and a black thumbs up embedded image ->
31+
emailNormal.addAttachment("dresscode.txt", new ByteArrayDataSource("Black Tie Optional", "text/plain"));
32+
emailNormal.addAttachment("location.txt", "On the moon!".getBytes(), "text/plain");
33+
String base64String = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABeElEQVRYw2NgoAAYGxu3GxkZ7TY1NZVloDcAWq4MxH+B+D8Qv3FwcOCgtwM6oJaDMTAUXOhmuYqKCjvQ0pdoDrCnmwNMTEwakC0H4u8GBgYC9Ap6DSD+iewAoIPm0ctyLqBlp9F8/x+YE4zpYT8T0LL16JYD8U26+B7oyz4sloPwenpYno3DchCeROsUbwa05A8eB3wB4kqgIxOAuArIng7EW4H4EhC/B+JXQLwDaI4ryZaDSjeg5mt4LCcFXyIn1fdSyXJQVt1OtMWGhoai0OD8T0W8GohZifE1PxD/o7LlsPLiFNAKRrwOABWptLAcqc6QGDAHQEOAYaAc8BNotsJAOgAUAosG1AFA/AtUoY3YEFhKMAvS2AE7iC1+WaG1H6gY3gzE36hUFJ8mqzbU1dUVBBqQBzTgIDQRkWo5qCZdpaenJ0Zx1aytrc0DDB0foIG1oAYKqC0IZK8D4n1AfA6IzwPxXpCFoGoZVEUDaRGGUTAKRgEeAAA2eGJC+ETCiAAAAABJRU5ErkJggg==";
34+
emailNormal.addEmbeddedImage("winksmiley", Base64.getDecoder().decode(base64String), "image/png");
35+
36+
// let's try producing and then consuming a MimeMessage ->
37+
final MimeMessage mimeMessage = Mailer.produceMimeMessage(emailNormal, Session.getDefaultInstance(new Properties()));
38+
final Email emailFromMimeMessage = new Email(mimeMessage);
39+
40+
sendMail(emailNormal);
41+
sendMail(emailFromMimeMessage); // should produce the exact same result as emailNormal!
42+
}
3343

34-
private static void sendMail(final Email email) {
35-
final String host = System.getProperty("host") != null ? System.getProperty("host") : "";
36-
final int port = System.getProperty("port") != null ? Integer.parseInt(System.getProperty("port")) : 25;
37-
final String username = System.getProperty("username") != null ? System.getProperty("username") : "";
38-
final String password = System.getProperty("password") != null ? System.getProperty("password") : "";
39-
new Mailer(host, port, username, password, TransportStrategy.SMTP_SSL).sendMail(email);
40-
}
44+
private static void sendMail(final Email email) {
45+
final String host = System.getProperty("host") != null ? System.getProperty("host") : "";
46+
final int port = System.getProperty("port") != null ? Integer.parseInt(System.getProperty("port")) : 25;
47+
final String username = System.getProperty("username") != null ? System.getProperty("username") : "";
48+
final String password = System.getProperty("password") != null ? System.getProperty("password") : "";
49+
new Mailer(host, port, username, password, TransportStrategy.SMTP_SSL).sendMail(email);
50+
}
4151
}

src/main/java/org/codemonkey/simplejavamail/MailException.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ public final class MailException extends RuntimeException {
2121
protected static final String MISSING_RECIPIENT = "Email is not valid: missing recipients";
2222
protected static final String MISSING_SUBJECT = "Email is not valid: missing subject";
2323
protected static final String MISSING_CONTENT = "Email is not valid: missing content body";
24-
protected static final String PARSE_MIMEMESSAGE_ERROR = "Error parsing MimeMessage: %s";
2524

2625
protected MailException(final String message) {
2726
super(message);
2827
}
2928

30-
protected MailException(final String message, final Exception cause) {
29+
public MailException(final String message, final Exception cause) {
3130
super(message, cause);
3231
}
3332
}

src/main/java/org/codemonkey/simplejavamail/Mailer.java

+14-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
import javax.mail.internet.MimeMultipart;
2323
import javax.mail.internet.MimeUtility;
2424

25+
import org.codemonkey.simplejavamail.email.AttachmentResource;
26+
import org.codemonkey.simplejavamail.email.Email;
27+
import org.codemonkey.simplejavamail.email.Recipient;
28+
import org.codemonkey.simplejavamail.util.EmailAddressValidationCriteria;
29+
import org.codemonkey.simplejavamail.util.EmailValidationUtil;
2530
import org.slf4j.Logger;
2631
import org.slf4j.LoggerFactory;
2732

@@ -68,7 +73,7 @@
6873
*/
6974
public class Mailer {
7075

71-
private static final Logger logger = LoggerFactory.getLogger(Mailer.class);
76+
private static final Logger LOGGER = LoggerFactory.getLogger(Mailer.class);
7277

7378
/**
7479
* Encoding used for setting body text, email address, headers, reply-to fields etc. ({@value #CHARACTER_ENCODING}).
@@ -159,15 +164,15 @@ public Mailer(final String host, final Integer port, final String username, fina
159164
*/
160165
protected Session createMailSession(final String host, final Integer port, final String username, final String password) {
161166
if (transportStrategy == null) {
162-
logger.warn("Transport Strategy not set, using plain SMTP strategy instead!");
167+
LOGGER.warn("Transport Strategy not set, using plain SMTP strategy instead!");
163168
transportStrategy = TransportStrategy.SMTP_PLAIN;
164169
}
165170
Properties props = transportStrategy.generateProperties();
166171
props.put(transportStrategy.propertyNameHost(), host);
167172
if (port != null) {
168173
props.put(transportStrategy.propertyNamePort(), String.valueOf(port));
169174
} else {
170-
// let JavaMail's Transport objects determine deault port base don the used protocol
175+
// let JavaMail's Transport objects determine default port base don the used protocol
171176
}
172177

173178
if (username != null) {
@@ -205,8 +210,8 @@ public Mailer(final String host, final Integer port, final String username, fina
205210
* let us know why you are needing this on https://github.com/bbottema/simple-java-mail/issues.
206211
*/
207212
public Session getSession() {
208-
logger.warn("Providing access to Session instance for emergency fall-back scenario. Please let us know why you need it.");
209-
logger.warn("\t>https://github.com/bbottema/simple-java-mail/issues");
213+
LOGGER.warn("Providing access to Session instance for emergency fall-back scenario. Please let us know why you need it.");
214+
LOGGER.warn("\t>https://github.com/bbottema/simple-java-mail/issues");
210215
return session;
211216
}
212217

@@ -263,10 +268,10 @@ public final void sendMail(final Email email)
263268
transport.close();
264269
}
265270
} catch (final UnsupportedEncodingException e) {
266-
logger.error(e.getMessage(), e);
271+
LOGGER.error(e.getMessage(), e);
267272
throw new MailException(String.format(MailException.INVALID_ENCODING, e.getMessage()));
268273
} catch (final MessagingException e) {
269-
logger.error(e.getMessage(), e);
274+
LOGGER.error(e.getMessage(), e);
270275
throw new MailException(String.format(MailException.GENERIC_ERROR, e.getMessage()), e);
271276
}
272277
}
@@ -286,7 +291,7 @@ private void logSession(Session session, TransportStrategy transportStrategy) {
286291
} else {
287292
specifics = properties.toString();
288293
}
289-
logger.debug(String.format("starting mail session (%s)", specifics));
294+
LOGGER.debug(String.format("starting mail session (%s)", specifics));
290295
}
291296

292297
/**
@@ -537,7 +542,7 @@ private static class MimeEmailMessageWrapper {
537542
multipartRelated.addBodyPart(contentAlternativeMessages);
538543
contentAlternativeMessages.setContent(multipartAlternativeMessages);
539544
} catch (final MessagingException e) {
540-
logger.error(e.getMessage(), e);
545+
LOGGER.error(e.getMessage(), e);
541546
throw new RuntimeException(e.getMessage(), e);
542547
}
543548
}
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,50 @@
1-
package org.codemonkey.simplejavamail;
2-
3-
import javax.activation.DataSource;
4-
5-
/**
6-
* A named immutable email attachment information object. The name can be a simple name, a filename or a named embedded
7-
* image (eg. &lt;cid:footer&gt;). Contains a {@link DataSource} that is compatible with the javax.mail API.
8-
*
9-
* @author Benny Bottema
10-
* @see DataSource
11-
*/
12-
final class AttachmentResource {
13-
14-
/**
15-
* @see #AttachmentResource(String, DataSource)
16-
*/
17-
private final String name;
18-
19-
/**
20-
* @see #AttachmentResource(String, DataSource)
21-
*/
22-
private final DataSource dataSource;
23-
24-
/**
25-
* Constructor; initializes the attachment resource with a name and data.
26-
*
27-
* @param name The name of the attachment which can be a simple name, a filename or a named embedded image (eg.
28-
* &lt;cid:footer&gt;)
29-
* @param dataSource The attachment data.
30-
* @see DataSource
31-
*/
32-
public AttachmentResource(final String name, final DataSource dataSource) {
33-
this.name = name;
34-
this.dataSource = dataSource;
35-
}
36-
37-
/**
38-
* Bean getter for {@link #dataSource}.
39-
*/
40-
public DataSource getDataSource() {
41-
return dataSource;
42-
}
43-
44-
/**
45-
* Bean getter for {@link #name}.
46-
*/
47-
public String getName() {
48-
return name;
49-
}
1+
package org.codemonkey.simplejavamail.email;
2+
3+
import javax.activation.DataSource;
4+
5+
/**
6+
* A named immutable email attachment information object. The name can be a simple name, a filename or a named embedded
7+
* image (eg. &lt;cid:footer&gt;). Contains a {@link DataSource} that is compatible with the javax.mail API.
8+
*
9+
* @author Benny Bottema
10+
* @see DataSource
11+
*/
12+
public class AttachmentResource {
13+
14+
/**
15+
* @see #AttachmentResource(String, DataSource)
16+
*/
17+
private final String name;
18+
19+
/**
20+
* @see #AttachmentResource(String, DataSource)
21+
*/
22+
private final DataSource dataSource;
23+
24+
/**
25+
* Constructor; initializes the attachment resource with a name and data.
26+
*
27+
* @param name The name of the attachment which can be a simple name, a filename or a named embedded image (eg.
28+
* &lt;cid:footer&gt;)
29+
* @param dataSource The attachment data.
30+
* @see DataSource
31+
*/
32+
public AttachmentResource(final String name, final DataSource dataSource) {
33+
this.name = name;
34+
this.dataSource = dataSource;
35+
}
36+
37+
/**
38+
* Bean getter for {@link #dataSource}.
39+
*/
40+
public DataSource getDataSource() {
41+
return dataSource;
42+
}
43+
44+
/**
45+
* Bean getter for {@link #name}.
46+
*/
47+
public String getName() {
48+
return name;
49+
}
5050
}

0 commit comments

Comments
 (0)