Skip to content

Commit 50dc02e

Browse files
committed
Porting commons-email module from Jooby 1.x
1 parent 7ecee0c commit 50dc02e

File tree

10 files changed

+388
-0
lines changed

10 files changed

+388
-0
lines changed

modules/jooby-bom/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<bucket4j-core.version>4.10.0</bucket4j-core.version>
2727
<caffeine.version>2.8.5</caffeine.version>
2828
<checkstyle.version>8.33</checkstyle.version>
29+
<commons-email.version>1.5</commons-email.version>
2930
<commons-io.version>2.7</commons-io.version>
3031
<compile-testing.version>0.18</compile-testing.version>
3132
<config.version>1.4.0</config.version>
@@ -800,6 +801,12 @@
800801
<version>${jfiglet.version}</version>
801802
<type>jar</type>
802803
</dependency>
804+
<dependency>
805+
<groupId>org.apache.commons</groupId>
806+
<artifactId>commons-email</artifactId>
807+
<version>${commons-email.version}</version>
808+
<type>jar</type>
809+
</dependency>
803810
<dependency>
804811
<groupId>org.jboss.modules</groupId>
805812
<artifactId>jboss-modules</artifactId>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4.0.0.xsd">
5+
6+
<parent>
7+
<groupId>io.jooby</groupId>
8+
<artifactId>modules</artifactId>
9+
<version>2.9.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<modelVersion>4.0.0</modelVersion>
13+
<artifactId>jooby-commons-email</artifactId>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>com.google.code.findbugs</groupId>
18+
<artifactId>jsr305</artifactId>
19+
<scope>provided</scope>
20+
</dependency>
21+
22+
<dependency>
23+
<groupId>io.jooby</groupId>
24+
<artifactId>jooby</artifactId>
25+
<version>${jooby.version}</version>
26+
</dependency>
27+
28+
<!-- commons email -->
29+
<dependency>
30+
<groupId>org.apache.commons</groupId>
31+
<artifactId>commons-email</artifactId>
32+
</dependency>
33+
34+
<!-- Test dependencies -->
35+
<dependency>
36+
<groupId>org.junit.jupiter</groupId>
37+
<artifactId>junit-jupiter-engine</artifactId>
38+
<scope>test</scope>
39+
</dependency>
40+
41+
<dependency>
42+
<groupId>org.jacoco</groupId>
43+
<artifactId>org.jacoco.agent</artifactId>
44+
<classifier>runtime</classifier>
45+
<scope>test</scope>
46+
</dependency>
47+
48+
<dependency>
49+
<groupId>org.mockito</groupId>
50+
<artifactId>mockito-core</artifactId>
51+
</dependency>
52+
</dependencies>
53+
</project>
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/**
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package io.jooby.email;
7+
8+
import com.typesafe.config.Config;
9+
import com.typesafe.config.ConfigFactory;
10+
import io.jooby.Extension;
11+
import io.jooby.Jooby;
12+
import io.jooby.ServiceKey;
13+
import io.jooby.ServiceRegistry;
14+
import io.jooby.internal.email.HtmlEmailProvider;
15+
import io.jooby.internal.email.ImageHtmlEmailProvider;
16+
import io.jooby.internal.email.MultiPartEmailProvider;
17+
import io.jooby.internal.email.SimpleEmailProvider;
18+
import org.apache.commons.mail.Email;
19+
import org.apache.commons.mail.HtmlEmail;
20+
import org.apache.commons.mail.ImageHtmlEmail;
21+
import org.apache.commons.mail.MultiPartEmail;
22+
import org.apache.commons.mail.SimpleEmail;
23+
24+
import javax.annotation.Nonnull;
25+
import javax.inject.Provider;
26+
27+
import java.util.HashMap;
28+
import java.util.Map;
29+
30+
import static java.util.Objects.requireNonNull;
31+
32+
/**
33+
* <h1>commons email</h1>
34+
* <p>
35+
* Small but helpful module that provides access to {@link Email} instances via
36+
* the service registry and {@link Config}.
37+
* </p>
38+
*
39+
* <h1>usage</h1>
40+
*
41+
* application.conf:
42+
*
43+
* <pre>
44+
* mail.hostName = smtp.googlemail.com
45+
* mail.ssl.onConnect = true
46+
* mail.username = username
47+
* mail.password = password
48+
* mail.from = user&#64;gmail.com
49+
* mail.subject = TestMail
50+
* </pre>
51+
*
52+
* <pre>
53+
* {
54+
* install(new CommonsEmailModule());
55+
*
56+
* get("/send", ctx {@literal ->} {
57+
* require(SimpleEmail.class)
58+
* .setMsg("you got an email!")
59+
* .setTo("foo&#64;bar.com")
60+
* .send();
61+
* });
62+
* }
63+
* </pre>
64+
*
65+
* <p>
66+
* That's all it does! Every time you require an email, it creates one and setup properties from
67+
* <code>mail.*</code>.
68+
* </p>
69+
*
70+
* @author edgar
71+
* @since 2.8.9
72+
*/
73+
public class CommonsEmailModule implements Extension {
74+
75+
private final String name;
76+
77+
/**
78+
* Creates a {@link CommonsEmailModule}.
79+
*
80+
* @param name Name of the property who has the mail information. Default is: <code>mail.*</code>.
81+
*/
82+
public CommonsEmailModule(String name) {
83+
this.name = requireNonNull(name, "Mail name is required.");
84+
}
85+
86+
/**
87+
* Creates a {@link CommonsEmailModule}.
88+
*/
89+
public CommonsEmailModule() {
90+
this("mail");
91+
}
92+
93+
@Override
94+
public void install(@Nonnull Jooby application) throws Exception {
95+
Config appConfig = application.getConfig();
96+
97+
Config mail = appConfig.getConfig(name)
98+
.withFallback(appConfig.getConfig("mail"))
99+
.withFallback(defaults(appConfig));
100+
101+
ServiceRegistry services = application.getServices();
102+
103+
register(services, SimpleEmail.class, new SimpleEmailProvider(mail));
104+
register(services, HtmlEmail.class, new HtmlEmailProvider(mail));
105+
register(services, MultiPartEmail.class, new MultiPartEmailProvider(mail));
106+
register(services, ImageHtmlEmail.class, new ImageHtmlEmailProvider(mail));
107+
}
108+
109+
private <T> void register(ServiceRegistry services, Class<T> clazz, Provider<T> provider) {
110+
services.putIfAbsent(clazz, provider);
111+
services.put(ServiceKey.key(clazz, name), provider);
112+
}
113+
114+
private Config defaults(Config appConfig) {
115+
final Map<String, Object> defaults = new HashMap<>();
116+
defaults.put("charset", appConfig.getString("application.charset"));
117+
return ConfigFactory.parseMap(defaults, CommonsEmailModule.class.getSimpleName() + "#defaults(...)");
118+
}
119+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package io.jooby.internal.email;
7+
8+
import com.typesafe.config.Config;
9+
import org.apache.commons.mail.Email;
10+
import org.apache.commons.mail.HtmlEmail;
11+
12+
import javax.mail.internet.AddressException;
13+
import javax.mail.internet.InternetAddress;
14+
import java.util.ArrayList;
15+
import java.util.List;
16+
import java.util.concurrent.TimeUnit;
17+
18+
import static java.util.Collections.singletonList;
19+
import static java.util.Objects.requireNonNull;
20+
21+
public class EmailFactory {
22+
23+
private interface EmailSetter {
24+
void apply(String p) throws Exception;
25+
}
26+
27+
private final Config mail;
28+
29+
public EmailFactory(final Config mail) {
30+
this.mail = requireNonNull(mail, "Mail config is required.");
31+
}
32+
33+
public <T extends Email> T newEmail(final T email) {
34+
try {
35+
ifset("username", p -> email.setAuthentication(mail.getString(p), mail.getString("password")));
36+
37+
ifset("bcc", p -> email.setBcc(address(strList(p))));
38+
ifset("bounceAddress", p -> email.setBounceAddress(mail.getString(p)));
39+
ifset("cc", p -> email.setCc(address(strList(p))));
40+
email.setCharset(mail.getString("charset"));
41+
ifset("debug", p -> email.setDebug(mail.getBoolean(p)));
42+
ifset("from", p -> email.setFrom(mail.getString(p)));
43+
ifset("hostName", p -> email.setHostName(mail.getString(p)));
44+
ifset("msg", p -> {
45+
if (email instanceof HtmlEmail) {
46+
((HtmlEmail) email).setHtmlMsg(mail.getString(p));
47+
} else {
48+
email.setMsg(mail.getString(p));
49+
}
50+
});
51+
ifset("replyTo", p -> email.setReplyTo(address(mail.getStringList(p))));
52+
ifset("sendPartial", p -> email.setSendPartial(mail.getBoolean(p)));
53+
ifset("smtpPort", p -> email.setSmtpPort(mail.getInt(p)));
54+
ifset("socketConnectionTimeout",
55+
p -> email.setSocketConnectionTimeout((int) mail.getDuration(p, TimeUnit.MILLISECONDS)));
56+
ifset("socketTimeout",
57+
p -> email.setSocketTimeout((int) mail.getDuration(p, TimeUnit.MILLISECONDS)));
58+
ifset("ssl.checkServerIdentity", p -> email.setSSLCheckServerIdentity(mail.getBoolean(p)));
59+
ifset("ssl.onConnect", p -> email.setSSLOnConnect(mail.getBoolean(p)));
60+
ifset("ssl.smtpPort", p -> email.setSslSmtpPort(mail.getString(p)));
61+
ifset("startTLSEnabled", p -> email.setStartTLSEnabled(mail.getBoolean(p)));
62+
ifset("startTLSRequired", p -> email.setStartTLSRequired(mail.getBoolean(p)));
63+
ifset("subject", p -> email.setSubject(mail.getString(p)));
64+
ifset("to", p -> email.setTo(address(strList(p))));
65+
66+
return email;
67+
} catch (Exception ex) {
68+
throw new IllegalArgumentException(ex);
69+
}
70+
}
71+
72+
private List<String> strList(final String p) {
73+
Object list = mail.getAnyRef(p);
74+
if (list instanceof String) {
75+
return singletonList(list.toString());
76+
}
77+
return mail.getStringList(p);
78+
}
79+
80+
private List<InternetAddress> address(final List<String> list) throws AddressException {
81+
List<InternetAddress> addresses = new ArrayList<>(list.size());
82+
for (String addr : list) {
83+
addresses.add(new InternetAddress(addr));
84+
}
85+
return addresses;
86+
}
87+
88+
private void ifset(final String key, final EmailSetter setter) throws Exception {
89+
if (mail.hasPath(key)) {
90+
setter.apply(key);
91+
}
92+
}
93+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package io.jooby.internal.email;
7+
8+
import javax.inject.Provider;
9+
10+
import org.apache.commons.mail.HtmlEmail;
11+
12+
import com.typesafe.config.Config;
13+
14+
public class HtmlEmailProvider implements Provider<HtmlEmail> {
15+
16+
private final EmailFactory factory;
17+
18+
public HtmlEmailProvider(final Config mail) {
19+
factory = new EmailFactory(mail);
20+
}
21+
22+
@Override
23+
public HtmlEmail get() {
24+
return factory.newEmail(new HtmlEmail());
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package io.jooby.internal.email;
7+
8+
import javax.inject.Provider;
9+
10+
import org.apache.commons.mail.ImageHtmlEmail;
11+
12+
import com.typesafe.config.Config;
13+
14+
public class ImageHtmlEmailProvider implements Provider<ImageHtmlEmail> {
15+
16+
private final EmailFactory factory;
17+
18+
public ImageHtmlEmailProvider(final Config mail) {
19+
factory = new EmailFactory(mail);
20+
}
21+
22+
@Override
23+
public ImageHtmlEmail get() {
24+
return factory.newEmail(new ImageHtmlEmail());
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package io.jooby.internal.email;
7+
8+
import javax.inject.Provider;
9+
10+
import org.apache.commons.mail.MultiPartEmail;
11+
12+
import com.typesafe.config.Config;
13+
14+
public class MultiPartEmailProvider implements Provider<MultiPartEmail> {
15+
16+
private final EmailFactory factory;
17+
18+
public MultiPartEmailProvider(final Config mail) {
19+
factory = new EmailFactory(mail);
20+
}
21+
22+
@Override
23+
public MultiPartEmail get() {
24+
return factory.newEmail(new MultiPartEmail());
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package io.jooby.internal.email;
7+
8+
import javax.inject.Provider;
9+
10+
import org.apache.commons.mail.SimpleEmail;
11+
12+
import com.typesafe.config.Config;
13+
14+
public class SimpleEmailProvider implements Provider<SimpleEmail> {
15+
16+
private final EmailFactory factory;
17+
18+
public SimpleEmailProvider(final Config mail) {
19+
factory = new EmailFactory(mail);
20+
}
21+
22+
@Override
23+
public SimpleEmail get() {
24+
return factory.newEmail(new SimpleEmail());
25+
}
26+
}

0 commit comments

Comments
 (0)