Skip to content

Commit d288175

Browse files
committed
#279: Add support for extra Session properties configured through simplejavamail.properties
1 parent b64f999 commit d288175

File tree

4 files changed

+76
-4
lines changed

4 files changed

+76
-4
lines changed

Diff for: modules/core-module/src/main/java/org/simplejavamail/config/ConfigLoader.java

+38-1
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,20 @@
1313
import java.io.FileNotFoundException;
1414
import java.io.IOException;
1515
import java.io.InputStream;
16+
import java.util.Collection;
1617
import java.util.HashMap;
18+
import java.util.HashSet;
1719
import java.util.Map;
1820
import java.util.Properties;
21+
import java.util.Set;
22+
import java.util.regex.Matcher;
23+
import java.util.regex.Pattern;
1924

2025
import static java.util.Collections.unmodifiableMap;
26+
import static java.util.regex.Pattern.compile;
2127
import static org.simplejavamail.internal.util.MiscUtil.checkArgumentNotEmpty;
2228
import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty;
29+
import static org.simplejavamail.internal.util.Preconditions.assumeTrue;
2330

2431
/**
2532
* Contains list of possible properties names and can produce a map of property values, if provided as file {@value #DEFAULT_CONFIG_FILENAME} on the
@@ -92,6 +99,11 @@ public final class ConfigLoader {
9299
*/
93100
public static final String DEFAULT_CONFIG_FILENAME = "simplejavamail.properties";
94101

102+
/**
103+
* This pattern recognizes extra property lines that should be loaded directly into JavaMail on the Session object.
104+
*/
105+
private static final Pattern EXTRA_PROPERTY_PATTERN = compile("^simplejavamail\\.extraproperties\\.(?<actualProperty>.*)");
106+
95107
/**
96108
* Initially try to load properties from "{@value #DEFAULT_CONFIG_FILENAME}".
97109
*
@@ -166,7 +178,8 @@ public enum Property {
166178
EMBEDDEDIMAGES_DYNAMICRESOLUTION_OUTSIDE_BASE_DIR("simplejavamail.embeddedimages.dynamicresolution.outside.base.dir"),
167179
EMBEDDEDIMAGES_DYNAMICRESOLUTION_OUTSIDE_BASE_URL("simplejavamail.embeddedimages.dynamicresolution.outside.base.classpath"),
168180
EMBEDDEDIMAGES_DYNAMICRESOLUTION_OUTSIDE_BASE_CLASSPATH("simplejavamail.embeddedimages.dynamicresolution.outside.base.url"),
169-
EMBEDDEDIMAGES_DYNAMICRESOLUTION_MUSTBESUCCESFUL("simplejavamail.embeddedimages.dynamicresolution.mustbesuccesful");
181+
EMBEDDEDIMAGES_DYNAMICRESOLUTION_MUSTBESUCCESFUL("simplejavamail.embeddedimages.dynamicresolution.mustbesuccesful"),
182+
EXTRA_PROPERTIES("simplejavamail.extraproperties.*");
170183

171184
private final String key;
172185

@@ -373,13 +386,37 @@ private static Map<Property, Object> readProperties(final @NotNull Properties fi
373386
}
374387
}
375388

389+
final Map<String, String> extraProperties = new HashMap<>();
390+
extraProperties.putAll(filterExtraJavaMailProperties(null, System.getProperties().entrySet()));
391+
//noinspection unchecked,rawtypes
392+
extraProperties.putAll(filterExtraJavaMailProperties(null, (Set) System.getenv().entrySet()));
393+
extraProperties.putAll(filterExtraJavaMailProperties(filePropertiesLeft, fileProperties.entrySet()));
394+
resolvedProps.put(Property.EXTRA_PROPERTIES, extraProperties);
395+
376396
if (!filePropertiesLeft.isEmpty()) {
377397
throw new IllegalArgumentException("unknown properties provided " + filePropertiesLeft);
378398
}
379399

380400
return resolvedProps;
381401
}
382402

403+
private static Map<String, String> filterExtraJavaMailProperties(@Nullable final Properties filePropertiesLeft, final Set<Map.Entry<Object, Object>> entries) {
404+
final Map<String, String> extraProperties = new HashMap<>();
405+
for (Map.Entry<Object, Object> propertyKey : entries) {
406+
if (propertyKey.getKey() instanceof String) {
407+
final Matcher matcher = EXTRA_PROPERTY_PATTERN.matcher((String) propertyKey.getKey());
408+
if (matcher.matches()) {
409+
assumeTrue(propertyKey.getValue() instanceof String, "Simple Java Mail property value can only be of type String");
410+
extraProperties.put(matcher.group("actualProperty"), (String) propertyKey.getValue());
411+
if (filePropertiesLeft != null) {
412+
filePropertiesLeft.remove(propertyKey.getKey());
413+
}
414+
}
415+
}
416+
}
417+
return extraProperties;
418+
}
419+
383420
/**
384421
* @return The property value in boolean, integer or as original string value.
385422
*/

Diff for: modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerImpl.java

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.simplejavamail.api.mailer.config.ProxyConfig;
1111
import org.simplejavamail.api.mailer.config.ServerConfig;
1212
import org.simplejavamail.api.mailer.config.TransportStrategy;
13+
import org.simplejavamail.config.ConfigLoader;
1314
import org.simplejavamail.internal.modules.ModuleLoader;
1415
import org.simplejavamail.mailer.MailerHelper;
1516
import org.simplejavamail.mailer.internal.util.SmtpAuthenticator;
@@ -21,11 +22,13 @@
2122
import javax.mail.Session;
2223
import java.util.EnumSet;
2324
import java.util.List;
25+
import java.util.Map;
2426
import java.util.Properties;
2527
import java.util.concurrent.Future;
2628
import java.util.concurrent.atomic.AtomicInteger;
2729

2830
import static org.simplejavamail.api.mailer.config.TransportStrategy.findStrategyForSession;
31+
import static org.simplejavamail.config.ConfigLoader.Property.EXTRA_PROPERTIES;
2932
import static org.simplejavamail.internal.util.ListUtil.getFirst;
3033
import static org.simplejavamail.internal.util.Preconditions.assumeNonNull;
3134
import static org.simplejavamail.internal.util.Preconditions.checkNonEmptyArgument;
@@ -130,6 +133,8 @@ public class MailerImpl implements Mailer {
130133
* <em>"mail.smtp.host"</em> for SMTP and <em>"mail.smtps.host"</em> for SMTPS)</li> </ol>
131134
* <p>
132135
* Furthermore adds proxy SOCKS properties if a proxy configuration was provided, overwriting any SOCKS properties already present.
136+
* <p>Finally, if there are extra properties in the properties file (ie. <em>simplejavamail.extraproperties.thisisextra=value</em>), then these
137+
* are loaded directly on the internal Session instance. This Java equivalent of this is: <code>mailer.getSession().getProperties().setProperty(..)</code>.
133138
*
134139
* @param serverConfig Remote SMTP server details.
135140
* @param transportStrategy The transport protocol strategy enum that actually handles the session configuration. Session configuration meaning
@@ -158,6 +163,9 @@ public static Session createMailSession(@NotNull final ServerConfig serverConfig
158163
} else if (serverConfig.getCustomSSLFactoryClass() != null) {
159164
props.put("mail.smtp.ssl.socketFactory.class", serverConfig.getCustomSSLFactoryClass());
160165
}
166+
if (ConfigLoader.hasProperty(EXTRA_PROPERTIES)) {
167+
props.putAll(ConfigLoader.<Map<?, ?>>getProperty(EXTRA_PROPERTIES));
168+
}
161169

162170
if (serverConfig.getPassword() != null) {
163171
props.put(transportStrategy.propertyNameAuthenticate(), "true");

Diff for: modules/simple-java-mail/src/test/java/org/simplejavamail/config/ConfigLoaderTest.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import testutil.ConfigLoaderTestHelper;
88

99
import java.io.ByteArrayInputStream;
10+
import java.util.AbstractMap;
11+
import java.util.AbstractMap.SimpleEntry;
1012
import java.util.HashMap;
1113
import java.util.Map;
1214
import java.util.Properties;
@@ -28,6 +30,7 @@
2830
import static org.simplejavamail.config.ConfigLoader.Property.EMBEDDEDIMAGES_DYNAMICRESOLUTION_BASE_CLASSPATH;
2931
import static org.simplejavamail.config.ConfigLoader.Property.EMBEDDEDIMAGES_DYNAMICRESOLUTION_BASE_DIR;
3032
import static org.simplejavamail.config.ConfigLoader.Property.EMBEDDEDIMAGES_DYNAMICRESOLUTION_BASE_URL;
33+
import static org.simplejavamail.config.ConfigLoader.Property.EXTRA_PROPERTIES;
3134
import static org.simplejavamail.config.ConfigLoader.Property.JAVAXMAIL_DEBUG;
3235
import static org.simplejavamail.config.ConfigLoader.Property.PROXY_HOST;
3336
import static org.simplejavamail.config.ConfigLoader.Property.PROXY_PASSWORD;
@@ -256,6 +259,8 @@ public void loadPropertiesFromProperties() {
256259
source.put("simplejavamail.smtp.username", "username");
257260
source.put("simplejavamail.smtp.password", "password");
258261
source.put("simplejavamail.custom.sslfactory.class", "teh_class");
262+
source.put("simplejavamail.extraproperties.a", "A");
263+
source.put("simplejavamail.extraproperties.b", "B");
259264

260265
ConfigLoader.loadProperties(source, false);
261266
assertThat(ConfigLoader.getProperty(JAVAXMAIL_DEBUG)).isEqualTo(true);
@@ -265,6 +270,8 @@ public void loadPropertiesFromProperties() {
265270
assertThat(ConfigLoader.getProperty(SMTP_USERNAME)).isEqualTo("username");
266271
assertThat(ConfigLoader.getProperty(SMTP_PASSWORD)).isEqualTo("password");
267272
assertThat(ConfigLoader.getProperty(CUSTOM_SSLFACTORY_CLASS)).isEqualTo("teh_class");
273+
assertThat(ConfigLoader.<Map<String, String>>getProperty(EXTRA_PROPERTIES))
274+
.containsExactly(new SimpleEntry<>("a", "A"), new SimpleEntry<>("b", "B"));
268275
}
269276

270277
@Test
@@ -299,5 +306,4 @@ public void loadPropertiesFileMalformed() {
299306
ConfigLoader.loadProperties("malformed.properties", false);
300307
// error: unknown properties should cause an illegal argument exception
301308
}
302-
303309
}

Diff for: modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/MailerTest.java

+23-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.IOException;
2727
import java.util.AbstractMap.SimpleEntry;
2828
import java.util.GregorianCalendar;
29+
import java.util.HashMap;
2930
import java.util.Properties;
3031
import java.util.UUID;
3132

@@ -40,6 +41,7 @@
4041
import static org.mockito.Mockito.verifyNoMoreInteractions;
4142
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTPS;
4243
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTP_TLS;
44+
import static org.simplejavamail.config.ConfigLoader.Property.EXTRA_PROPERTIES;
4345
import static org.simplejavamail.config.ConfigLoader.Property.OPPORTUNISTIC_TLS;
4446

4547
@SuppressWarnings("unused")
@@ -60,8 +62,10 @@ public void restoreOriginalStaticProperties() {
6062
+ "simplejavamail.proxy.username=username proxy\n"
6163
+ "simplejavamail.proxy.password=password proxy\n"
6264
+ "simplejavamail.proxy.socks5bridge.port=1081\n"
63-
+ "simplejavamail.defaults.trustedhosts=192.168.1.122;mymailserver.com;ix55432y";
64-
65+
+ "simplejavamail.defaults.trustedhosts=192.168.1.122;mymailserver.com;ix55432y\n"
66+
+ "simplejavamail.extraproperties.extra-properties-property1=value1\n"
67+
+ "simplejavamail.extraproperties.extra-properties-property2=value2";
68+
6569
ConfigLoader.loadProperties(new ByteArrayInputStream(s.getBytes()), false);
6670
}
6771

@@ -90,6 +94,12 @@ public void createMailSession_MinimalConstructor_WithoutConfig() {
9094
assertThat(session.getProperty("mail.smtp.socks.host")).isNull();
9195
assertThat(session.getProperty("mail.smtp.socks.port")).isNull();
9296

97+
assertThat(session.getProperty("extra1")).isNull();
98+
assertThat(session.getProperty("extra2")).isNull();
99+
100+
assertThat(session.getProperty("extra-properties-property1")).isNull();
101+
assertThat(session.getProperty("extra-properties-property2")).isNull();
102+
93103
assertThat(mailer.getOperationalConfig().getClusterKey()).isEqualTo(clusterKey);
94104

95105
// all constructors, providing the same minimal information
@@ -123,6 +133,8 @@ public void createMailSession_AnonymousProxyConstructor_WithoutConfig() {
123133
assertThat(session.getProperty("mail.smtp.socks.port")).isEqualTo("1080");
124134
assertThat(session.getProperty("extra1")).isEqualTo("value1");
125135
assertThat(session.getProperty("extra2")).isEqualTo("value2");
136+
assertThat(session.getProperty("extra-properties-property1")).isNull();
137+
assertThat(session.getProperty("extra-properties-property2")).isNull();
126138
}
127139

128140
@Test
@@ -147,6 +159,8 @@ public void createMailSession_MaximumConstructor_WithoutConfig() {
147159
assertThat(session.getProperty("mail.smtp.socks.port")).isEqualTo("999");
148160
assertThat(session.getProperty("extra1")).isEqualTo("value1");
149161
assertThat(session.getProperty("extra2")).isEqualTo("value2");
162+
assertThat(session.getProperty("extra-properties-property1")).isNull();
163+
assertThat(session.getProperty("extra-properties-property2")).isNull();
150164
}
151165

152166
@Test
@@ -169,12 +183,17 @@ public void createMailSession_MinimalConstructor_WithConfig() {
169183
// the following two are because authentication is needed, otherwise proxy would be straightworward
170184
assertThat(session.getProperty("mail.smtp.socks.host")).isEqualTo("localhost");
171185
assertThat(session.getProperty("mail.smtp.socks.port")).isEqualTo("1081");
186+
assertThat(session.getProperty("extra1")).isNull();
187+
assertThat(session.getProperty("extra2")).isNull();
188+
assertThat(session.getProperty("extra-properties-property1")).isEqualTo("value1");
189+
assertThat(session.getProperty("extra-properties-property2")).isEqualTo("value2");
172190
}
173191

174192
@Test
175193
public void createMailSession_MinimalConstructor_WithConfig_OPPORTUNISTIC_TLS() {
176194
Properties properties = new Properties();
177195
properties.setProperty(OPPORTUNISTIC_TLS.key(), "false");
196+
properties.setProperty("simplejavamail.extraproperties.extra-properties-property2", "override");
178197
ConfigLoader.loadProperties(properties, true);
179198

180199
Mailer mailer = MailerBuilder.withTransportStrategy(TransportStrategy.SMTP).buildMailer();
@@ -194,6 +213,8 @@ public void createMailSession_MinimalConstructor_WithConfig_OPPORTUNISTIC_TLS()
194213
// the following two are because authentication is needed, otherwise proxy would be straightworward
195214
assertThat(session.getProperty("mail.smtp.socks.host")).isEqualTo("localhost");
196215
assertThat(session.getProperty("mail.smtp.socks.port")).isEqualTo("1081");
216+
assertThat(session.getProperty("extra-properties-property1")).isNull();
217+
assertThat(session.getProperty("extra-properties-property2")).isEqualTo("override");
197218
}
198219

199220
@Test

0 commit comments

Comments
 (0)