DefaultJavaxMailConfigurer.java

1
package fr.sii.ogham.email.builder.javaxmail;
2
3
import static fr.sii.ogham.core.builder.configuration.MayOverride.overrideIfNotSet;
4
import static fr.sii.ogham.email.JavaxMailConstants.DEFAULT_JAVAX_MAIL_CONFIGURER_PRIORITY;
5
import static fr.sii.ogham.email.builder.javaxmail.JavaxMailConsistencyChecker.checkDataHandlersAvailable;
6
import static fr.sii.ogham.email.builder.javaxmail.JavaxMailConsistencyChecker.checkMailProvidersAvailable;
7
import static java.nio.charset.StandardCharsets.UTF_8;
8
import static java.util.Arrays.asList;
9
10
import fr.sii.ogham.core.exception.configurer.*;
11
12
import fr.sii.ogham.core.builder.MessagingBuilder;
13
import fr.sii.ogham.core.builder.configurer.ConfigurerFor;
14
import fr.sii.ogham.core.builder.configurer.MessagingConfigurer;
15
import fr.sii.ogham.core.builder.context.BuildContext;
16
import fr.sii.ogham.core.util.ClasspathUtils;
17
import fr.sii.ogham.email.builder.javaxmail.JavaxMailConsistencyChecker.JavaxMailConsistencyException;
18
import fr.sii.ogham.email.sender.impl.javaxmail.UsernamePasswordAuthenticator;
19
20
import javax.mail.Provider;
21
import javax.mail.Session;
22
import java.util.*;
23
24
/**
25
 * Default JavaMail configurer that is automatically applied every time a
26
 * {@link MessagingBuilder} instance is created through
27
 * {@link MessagingBuilder#standard()}.
28
 * 
29
 * <p>
30
 * The configurer has a priority of 50000 in order to be applied after
31
 * templating configurers.
32
 * </p>
33
 * 
34
 * This configurer is applied only if {@code javax.mail.Transport} and
35
 * {@code javax.mail.internet.MimeMessage} are present in the classpath. If not
36
 * present, JavaMail implementation is not registered at all.
37
 * 
38
 * <p>
39
 * This configurer inherits environment configuration (see
40
 * {@link BuildContext}).
41
 * </p>
42
 * 
43
 * <p>
44
 * This configurer applies the following configuration:
45
 * <ul>
46
 * <li>Configures host and port:
47
 * <ul>
48
 * <li>It uses one of "ogham.email.javamail.host", "mail.smtp.host" or
49
 * "mail.hofromst" property if defined for mail server host address (IP or
50
 * hostname)</li>
51
 * <li>It uses one of "ogham.email.javamail.port", "mail.smtp.port" or
52
 * "mail.port" property if defined for mail server port. Default port is 25</li>
53
 * </ul>
54
 * </li>
55
 * <li>Configures authentication:
56
 * <ul>
57
 * <li>If property "ogham.email.javamail.authenticator.username" and
58
 * "ogham.email.javamail.authenticator.password" are defined, then an
59
 * {@link UsernamePasswordAuthenticator} is used to handle username/password
60
 * authentication</li>
61
 * </ul>
62
 * </li>
63
 * <li>Configures encoding:
64
 * <ul>
65
 * <li>It uses "ogham.email.javamail.body.charset" property value as charset for
66
 * email body if defined. Default charset is UTF-8</li>
67
 * </ul>
68
 * </li>
69
 * <li>Configures mimetype detection:
70
 * <ul>
71
 * <li>Uses Apache Tika to detect mimetype</li>
72
 * <li>Explicitly use "text/html" mimetype instead of more specific ones like
73
 * "application/xhtml" (XHTML)</li>
74
 * </ul>
75
 * </li>
76
 * </ul>
77
 * 
78
 * @author Aurélien Baudet
79
 *
80
 */
81
public final class DefaultJavaxMailConfigurer {
82
	private static final int DEFAULT_SMTP_PORT = 25;
83
84
	@ConfigurerFor(targetedBuilder = "standard", priority = DEFAULT_JAVAX_MAIL_CONFIGURER_PRIORITY)
85
	public static class JavaxMailConfigurer implements MessagingConfigurer {
86
		@Override
87
		public void configure(MessagingBuilder msgBuilder) throws ConfigureException {
88 1 1. configure : removed call to fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::checkCanUseJavaMail → RUN_ERROR
			checkCanUseJavaMail();
89
90
			JavaxMailBuilder builder = msgBuilder.email().sender(JavaxMailBuilder.class);
91
			// @formatter:off
92
			builder
93
				.host().properties("${ogham.email.javamail.host}", "${mail.smtp.host}", "${mail.host}").and()
94
				.port().properties("${ogham.email.javamail.port}", "${mail.smtp.port}", "${mail.port}").defaultValue(overrideIfNotSet(DEFAULT_SMTP_PORT)).and()
95
				.authenticator()
96
					.username().properties("${ogham.email.javamail.authenticator.username}").and()
97
					.password().properties("${ogham.email.javamail.authenticator.password}").and()
98
					.and()
99
				.charset().properties("${ogham.email.javamail.body.charset}").defaultValue(overrideIfNotSet(UTF_8)).and()
100
				.mimetype()
101
					.tika()
102
						.failIfOctetStream().defaultValue(overrideIfNotSet(false)).and()
103
						.and()
104
					.replace()
105
						// the distinction between xhtml and html can be useful in some cases
106
						// most email clients don't understand xhtml mimetype
107
						// for emails, this distinction must not be done
108
						.pattern("application/xhtml[^;]*(;.*)?", "text/html$1");
109
			// @formatter:on
110
		}
111
112
		private static void checkCanUseJavaMail() throws ConfigureException {
113 1 1. checkCanUseJavaMail : negated conditional → RUN_ERROR
			if (!isJavaxMailApiPresent()) {
114
				throw new MissingImplementationException("Can't send Email through javax.mail because javax.mail API is not present in the classpath", "javax.mail.Transport", "javax.mail.internet.MimeMessage", "javax.mail.Session");
115
			}
116 1 1. checkCanUseJavaMail : negated conditional → RUN_ERROR
			if (!isJavaxActivationPresent()) {
117
				throw new MissingImplementationException("Can't send Email through javax.mail because javax.activation API is not present in the classpath", "javax.activation.DataHandler");
118
			}
119 1 1. checkCanUseJavaMail : negated conditional → RUN_ERROR
			if (!isSunMailPresent()) {
120
				throw new MissingImplementationException("Can't send Email through javax.mail because javax.mail API is present in the classpath but it requires the class 'com.sun.mail.util.MailLogger' which is not present in the classpath", "com.sun.mail.util.MailLogger");
121
			}
122
			try {
123
				checkMailProvidersAvailable();
124
			} catch (JavaxMailConsistencyException e) {
125
				throw new ClasspathConsistencyException(e.getMessage(), e);
126
			}
127
			try {
128
				checkDataHandlersAvailable();
129
			} catch (JavaxMailConsistencyException e) {
130
				throw new ClasspathConsistencyException(e.getMessage(), e);
131
			}
132
		}
133
134
		private static boolean isJavaxMailApiPresent() {
135 2 1. isJavaxMailApiPresent : negated conditional → RUN_ERROR
2. isJavaxMailApiPresent : replaced boolean return with true for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isJavaxMailApiPresent → RUN_ERROR
			return ClasspathUtils.exists("javax.mail.Transport")
136 1 1. isJavaxMailApiPresent : negated conditional → RUN_ERROR
					&& ClasspathUtils.exists("javax.mail.internet.MimeMessage")
137 1 1. isJavaxMailApiPresent : negated conditional → RUN_ERROR
					&& ClasspathUtils.exists("javax.mail.Session");
138
		}
139
140
		private static boolean isJavaxActivationPresent() {
141 2 1. isJavaxActivationPresent : replaced boolean return with false for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isJavaxActivationPresent → RUN_ERROR
2. isJavaxActivationPresent : replaced boolean return with true for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isJavaxActivationPresent → RUN_ERROR
			return ClasspathUtils.exists("javax.activation.DataHandler");
142
		}
143
144
		private static boolean isSunMailPresent() {
145
			// javax.mail <= 1.6.7 has direct dependency to com.sun.mail (which is stupid by the way)
146
			// but it can't work if this class is not present
147 2 1. isSunMailPresent : replaced boolean return with true for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isSunMailPresent → RUN_ERROR
2. isSunMailPresent : replaced boolean return with false for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isSunMailPresent → RUN_ERROR
			return ClasspathUtils.exists("com.sun.mail.util.MailLogger");
148
		}
149
150
	}
151
152
	private DefaultJavaxMailConfigurer() {
153
		super();
154
	}
155
}

Mutations

88

1.1
Location : configure
Killed by :
removed call to fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::checkCanUseJavaMail → RUN_ERROR

113

1.1
Location : checkCanUseJavaMail
Killed by :
negated conditional → RUN_ERROR

116

1.1
Location : checkCanUseJavaMail
Killed by :
negated conditional → RUN_ERROR

119

1.1
Location : checkCanUseJavaMail
Killed by :
negated conditional → RUN_ERROR

135

1.1
Location : isJavaxMailApiPresent
Killed by :
negated conditional → RUN_ERROR

2.2
Location : isJavaxMailApiPresent
Killed by :
replaced boolean return with true for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isJavaxMailApiPresent → RUN_ERROR

136

1.1
Location : isJavaxMailApiPresent
Killed by :
negated conditional → RUN_ERROR

137

1.1
Location : isJavaxMailApiPresent
Killed by :
negated conditional → RUN_ERROR

141

1.1
Location : isJavaxActivationPresent
Killed by :
replaced boolean return with false for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isJavaxActivationPresent → RUN_ERROR

2.2
Location : isJavaxActivationPresent
Killed by :
replaced boolean return with true for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isJavaxActivationPresent → RUN_ERROR

147

1.1
Location : isSunMailPresent
Killed by :
replaced boolean return with true for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isSunMailPresent → RUN_ERROR

2.2
Location : isSunMailPresent
Killed by :
replaced boolean return with false for fr/sii/ogham/email/builder/javaxmail/DefaultJavaxMailConfigurer$JavaxMailConfigurer::isSunMailPresent → RUN_ERROR

Active mutators

Tests examined


Report generated by PIT 1.13.1