JavaxMailBuilder.java

1
package fr.sii.ogham.email.builder.javaxmail;
2
3
import fr.sii.ogham.core.builder.ActivableAtRuntime;
4
import fr.sii.ogham.core.builder.Builder;
5
import fr.sii.ogham.core.builder.MessagingBuilder;
6
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilder;
7
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilderHelper;
8
import fr.sii.ogham.core.builder.configurer.Configurer;
9
import fr.sii.ogham.core.builder.context.BuildContext;
10
import fr.sii.ogham.core.builder.context.DefaultBuildContext;
11
import fr.sii.ogham.core.builder.env.EnvironmentBuilder;
12
import fr.sii.ogham.core.builder.mimetype.MimetypeDetectionBuilder;
13
import fr.sii.ogham.core.builder.mimetype.MimetypeDetectionBuilderDelegate;
14
import fr.sii.ogham.core.builder.mimetype.SimpleMimetypeDetectionBuilder;
15
import fr.sii.ogham.core.charset.CharsetDetector;
16
import fr.sii.ogham.core.charset.FixedCharsetDetector;
17
import fr.sii.ogham.core.condition.Condition;
18
import fr.sii.ogham.core.convert.Converter;
19
import fr.sii.ogham.core.env.FirstExistingPropertiesResolver;
20
import fr.sii.ogham.core.env.JavaPropertiesResolver;
21
import fr.sii.ogham.core.env.PropertiesBridge;
22
import fr.sii.ogham.core.env.PropertyResolver;
23
import fr.sii.ogham.core.fluent.AbstractParent;
24
import fr.sii.ogham.core.message.Message;
25
import fr.sii.ogham.core.message.content.MayHaveStringContent;
26
import fr.sii.ogham.core.message.content.MultiContent;
27
import fr.sii.ogham.core.mimetype.MimeTypeProvider;
28
import fr.sii.ogham.core.resource.FileResource;
29
import fr.sii.ogham.core.resource.LookupResource;
30
import fr.sii.ogham.core.resource.NamedResource;
31
import fr.sii.ogham.core.resource.OverrideNameWrapper;
32
import fr.sii.ogham.email.attachment.Attachment;
33
import fr.sii.ogham.email.builder.EmailBuilder;
34
import fr.sii.ogham.email.exception.handler.AttachmentResourceHandlerException;
35
import fr.sii.ogham.email.exception.handler.UnresolvableAttachmentResourceHandlerException;
36
import fr.sii.ogham.email.message.Email;
37
import fr.sii.ogham.email.message.content.ContentWithAttachments;
38
import fr.sii.ogham.email.sender.impl.JavaxMailSender;
39
import fr.sii.ogham.email.sender.impl.javaxmail.*;
40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42
43
import javax.mail.Authenticator;
44
import javax.mail.internet.MimeBodyPart;
45
import javax.mail.internet.MimeMessage;
46
import javax.mail.internet.MimeMultipart;
47
import java.io.InputStream;
48
import java.nio.charset.Charset;
49
import java.nio.file.Files;
50
import java.util.Map;
51
import java.util.Map.Entry;
52
import java.util.Properties;
53
import java.util.Set;
54
import java.util.function.BiFunction;
55
56
import static fr.sii.ogham.core.condition.fluent.MessageConditions.requiredProperty;
57
58
/**
59
 * Configures how Java Mail implementation will send {@link Email}s.
60
 * 
61
 * <p>
62
 * To send {@link Email} using Java Mail, you need to register this builder into
63
 * a {@link MessagingBuilder} like this:
64
 * 
65
 * <pre>
66
 * <code>
67
 * MessagingBuilder msgBuilder = ...
68
 * msgBuilder.email()
69
 *    .sender(JavaMailBuilder.class)    // registers the builder and accesses to that builder for configuring it
70
 * </code>
71
 * </pre>
72
 * 
73
 * Once the builder is registered, sending email through Java Mail requires at
74
 * least host of the SMTP server. You can define it using:
75
 * 
76
 * <pre>
77
 * <code>
78
 * msgBuilder.email()
79
 *    .sender(JavaMailBuilder.class)    // registers the builder and accesses to that builder for configuring it
80
 *       .host("localhost")
81
 * </code>
82
 * </pre>
83
 * 
84
 * Or you can also use property keys (using interpolation):
85
 * 
86
 * <pre>
87
 * <code>
88
 * msgBuilder
89
 * .environment()
90
 *    .properties()
91
 *       .set("custom.property.for.host", "localhost")
92
 *       .and()
93
 *    .and()
94
 * .email()
95
 *    .sender(JavaMailBuilder.class)    // registers the builder and accesses to that builder for configuring it
96
 *       .host()
97
 *       	.properties("${custom.property.for.host}")
98
 * </code>
99
 * </pre>
100
 * 
101
 * You can do the same with port of the SMTP server.
102
 * 
103
 * 
104
 * <p>
105
 * SMTP server may require authentication. In most cases, authentication is done
106
 * using username/password. You can use this builder to quickly provide your
107
 * username and password:
108
 * 
109
 * <pre>
110
 * <code>
111
 * .sender(JavaMailBuilder.class)
112
 *    .authenticator()
113
 *        .username("foo")
114
 *        .password("bar")
115
 * </code>
116
 * </pre>
117
 * 
118
 * If you need another authentication mechanism, you can directly provide your
119
 * own {@link Authenticator} implementation:
120
 * 
121
 * <pre>
122
 * <code>
123
 * .sender(JavaMailBuilder.class)
124
 *    .authenticator(new MyCustomAuthenticator())
125
 * </code>
126
 * </pre>
127
 * 
128
 * 
129
 * <p>
130
 * Finally, Ogham will transform general {@link Email} object into
131
 * {@link MimeMessage}, {@link MimeMultipart}, {@link MimeBodyPart} objects.
132
 * This transformation will fit almost all use cases but you may need to
133
 * customize a part of the javax.mail message. Instead of doing again the same
134
 * work Ogham does, this builder allows you to intercept the message to modify
135
 * it just before sending it:
136
 * 
137
 * <pre>
138
 * <code>
139
 * .sender(JavaMailBuilder.class)
140
 *    .intercept(new MyCustomInterceptor())
141
 * </code>
142
 * </pre>
143
 * 
144
 * See {@link JavaMailInterceptor} for more information.
145
 * 
146
 * 
147
 * @author Aurélien Baudet
148
 *
149
 */
150
public class JavaxMailBuilder extends AbstractParent<EmailBuilder> implements Builder<JavaxMailSender>, ActivableAtRuntime {
151
	private static final Logger LOG = LoggerFactory.getLogger(JavaxMailBuilder.class);
152
153
	private final BuildContext buildContext;
154
	private final ConfigurationValueBuilderHelper<JavaxMailBuilder, String> hostValueBuilder;
155
	private final ConfigurationValueBuilderHelper<JavaxMailBuilder, Integer> portValueBuilder;
156
	private final ConfigurationValueBuilderHelper<JavaxMailBuilder, Charset> charsetValueBuilder;
157
	private final Properties additionalProperties;
158
	private Authenticator authenticator;
159
	private UsernamePasswordAuthenticatorBuilder authenticatorBuilder;
160
	private JavaMailInterceptor interceptor;
161
	private MimetypeDetectionBuilder<JavaxMailBuilder> mimetypeBuilder;
162
	private CharsetDetector charsetDetector;
163
164
	/**
165
	 * Default constructor when using JavaMail sender without all Ogham work.
166
	 * 
167
	 * <strong>WARNING: use is only if you know what you are doing !</strong>
168
	 */
169
	public JavaxMailBuilder() {
170
		this(null, new DefaultBuildContext());
171
		mimetype();
172
	}
173
174
	/**
175
	 * Constructor that is called when using Ogham builder:
176
	 * 
177
	 * <pre>
178
	 * MessagingBuilder msgBuilder = ...
179
	 * msgBuilder
180
	 * .email()
181
	 *    .sender(JavaMailBuilder.class)
182
	 * </pre>
183
	 * 
184
	 * <p>
185
	 * Initializes the builder with the parent instance (used by the
186
	 * {@link #and()} method) and the {@link EnvironmentBuilder}. The
187
	 * {@link EnvironmentBuilder} is used to evaluate property values when
188
	 * {@link #build()} is called.
189
	 * 
190
	 * @param parent
191
	 *            the parent builder instance for fluent chaining
192
	 * @param buildContext
193
	 *            used to evaluate property values
194
	 */
195
	public JavaxMailBuilder(EmailBuilder parent, BuildContext buildContext) {
196
		super(parent);
197
		this.buildContext = buildContext;
198
		hostValueBuilder = buildContext.newConfigurationValueBuilder(this, String.class);
199
		portValueBuilder = buildContext.newConfigurationValueBuilder(this, Integer.class);
200
		charsetValueBuilder = buildContext.newConfigurationValueBuilder(this, Charset.class);
201
		additionalProperties = new Properties();
202
	}
203
204
	/**
205
	 * Set the mail server address host (IP or hostname).
206
	 * 
207
	 * <p>
208
	 * The value set using this method takes precedence over any property and
209
	 * default value configured using {@link #host()}.
210
	 * 
211
	 * <pre>
212
	 * .host("smtp.gmail.com")
213
	 * .host()
214
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
215
	 *   .defaultValue("localhost")
216
	 * </pre>
217
	 * 
218
	 * <pre>
219
	 * .host("smtp.gmail.com")
220
	 * .host()
221
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
222
	 *   .defaultValue("localhost")
223
	 * </pre>
224
	 * 
225
	 * In both cases, {@code host("smtp.gmail.com")} is used.
226
	 * 
227
	 * <p>
228
	 * If this method is called several times, only the last value is used.
229
	 * 
230
	 * <p>
231
	 * If {@code null} value is set, it is like not setting a value at all. The
232
	 * property/default value configuration is applied.
233
	 * 
234
	 * @param host
235
	 *            the host of the mail server
236
	 * @return this instance for fluent chaining
237
	 */
238
	public JavaxMailBuilder host(String host) {
239 1 1. host : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE
		hostValueBuilder.setValue(host);
240 1 1. host : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::host → NO_COVERAGE
		return this;
241
	}
242
243
	/**
244
	 * Set the mail server address host (IP or hostname).
245
	 * 
246
	 * <p>
247
	 * This method is mainly used by {@link Configurer}s to register some
248
	 * property keys and/or a default value. The aim is to let developer be able
249
	 * to externalize its configuration (using system properties, configuration
250
	 * file or anything else). If the developer doesn't configure any value for
251
	 * the registered properties, the default value is used (if set).
252
	 * 
253
	 * <pre>
254
	 * .host()
255
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
256
	 *   .defaultValue("localhost")
257
	 * </pre>
258
	 * 
259
	 * <p>
260
	 * Non-null value set using {@link #host(String)} takes precedence over
261
	 * property values and default value.
262
	 * 
263
	 * <pre>
264
	 * .host("smtp.gmail.com")
265
	 * .host()
266
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
267
	 *   .defaultValue("localhost")
268
	 * </pre>
269
	 * 
270
	 * The value {@code "smtp.gmail.com"} is used regardless of the value of the
271
	 * properties and default value.
272
	 * 
273
	 * <p>
274
	 * See {@link ConfigurationValueBuilder} for more information.
275
	 * 
276
	 * 
277
	 * @return the builder to configure property keys/default value
278
	 */
279
	public ConfigurationValueBuilder<JavaxMailBuilder, String> host() {
280 1 1. host : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::host → NO_COVERAGE
		return hostValueBuilder;
281
	}
282
283
	/**
284
	 * Set the mail server port.
285
	 * 
286
	 * <p>
287
	 * The value set using this method takes precedence over any property and
288
	 * default value configured using {@link #port()}.
289
	 * 
290
	 * <pre>
291
	 * .port(10025)
292
	 * .port()
293
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
294
	 *   .defaultValue(25)
295
	 * </pre>
296
	 * 
297
	 * <pre>
298
	 * .port(10025)
299
	 * .port()
300
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
301
	 *   .defaultValue(25)
302
	 * </pre>
303
	 * 
304
	 * In both cases, {@code port(10025)} is used.
305
	 * 
306
	 * <p>
307
	 * If this method is called several times, only the last value is used.
308
	 * 
309
	 * <p>
310
	 * If {@code null} value is set, it is like not setting a value at all. The
311
	 * property/default value configuration is applied.
312
	 * 
313
	 * @param port
314
	 *            the port of mail server
315
	 * @return this instance for fluent chaining
316
	 */
317
	public JavaxMailBuilder port(Integer port) {
318 1 1. port : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE
		portValueBuilder.setValue(port);
319 1 1. port : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::port → NO_COVERAGE
		return this;
320
	}
321
322
	/**
323
	 * Set the mail server port
324
	 * 
325
	 * <p>
326
	 * This method is mainly used by {@link Configurer}s to register some
327
	 * property keys and/or a default value. The aim is to let developer be able
328
	 * to externalize its configuration (using system properties, configuration
329
	 * file or anything else). If the developer doesn't configure any value for
330
	 * the registered properties, the default value is used (if set).
331
	 * 
332
	 * <pre>
333
	 * .port()
334
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
335
	 *   .defaultValue(25)
336
	 * </pre>
337
	 * 
338
	 * <p>
339
	 * Non-null value set using {@link #port(Integer)} takes precedence over
340
	 * property values and default value.
341
	 * 
342
	 * <pre>
343
	 * .port(10025)
344
	 * .port()
345
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
346
	 *   .defaultValue(25)
347
	 * </pre>
348
	 * 
349
	 * The value {@code 10025} is used regardless of the value of the properties
350
	 * and default value.
351
	 * 
352
	 * <p>
353
	 * See {@link ConfigurationValueBuilder} for more information.
354
	 * 
355
	 * 
356
	 * @return the builder to configure property keys/default value
357
	 */
358
	public ConfigurationValueBuilder<JavaxMailBuilder, Integer> port() {
359 1 1. port : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::port → NO_COVERAGE
		return portValueBuilder;
360
	}
361
362
	/**
363
	 * Set charset to use for email body.
364
	 * 
365
	 * <p>
366
	 * The value set using this method takes precedence over any property and
367
	 * default value configured using {@link #charset()}.
368
	 * 
369
	 * <pre>
370
	 * .charset(StandardCharsets.UTF_16)
371
	 * .charset()
372
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
373
	 *   .defaultValue(StandardCharsets.UTF_8)
374
	 * </pre>
375
	 * 
376
	 * <pre>
377
	 * .charset(StandardCharsets.UTF_16)
378
	 * .charset()
379
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
380
	 *   .defaultValue(StandardCharsets.UTF_8)
381
	 * </pre>
382
	 * 
383
	 * In both cases, {@code charset(StandardCharsets.UTF_16)} is used.
384
	 * 
385
	 * <p>
386
	 * If this method is called several times, only the last value is used.
387
	 * 
388
	 * <p>
389
	 * If {@code null} value is set, it is like not setting a value at all. The
390
	 * property/default value configuration is applied.
391
	 * 
392
	 * @param charset
393
	 *            the charset to use for email body
394
	 * @return this instance for fluent chaining
395
	 */
396
	public JavaxMailBuilder charset(Charset charset) {
397 1 1. charset : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE
		charsetValueBuilder.setValue(charset);
398 1 1. charset : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::charset → NO_COVERAGE
		return this;
399
	}
400
401
	/**
402
	 * Set charset to use for email body
403
	 * 
404
	 * <p>
405
	 * This method is mainly used by {@link Configurer}s to register some
406
	 * property keys and/or a default value. The aim is to let developer be able
407
	 * to externalize its configuration (using system properties, configuration
408
	 * file or anything else). If the developer doesn't configure any value for
409
	 * the registered properties, the default value is used (if set).
410
	 * 
411
	 * <pre>
412
	 * .charset()
413
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
414
	 *   .defaultValue(StandardCharsets.UTF_8)
415
	 * </pre>
416
	 * 
417
	 * <p>
418
	 * Non-null value set using {@link #charset(Charset)} takes precedence over
419
	 * property values and default value.
420
	 * 
421
	 * <pre>
422
	 * .charset(StandardCharsets.UTF_16)
423
	 * .charset()
424
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
425
	 *   .defaultValue(StandardCharsets.UTF_8)
426
	 * </pre>
427
	 * 
428
	 * The value {@code StandardCharsets.UTF_16} is used regardless of the value
429
	 * of the properties and default value.
430
	 * 
431
	 * <p>
432
	 * See {@link ConfigurationValueBuilder} for more information.
433
	 * 
434
	 * 
435
	 * @return the builder to configure property keys/default value
436
	 */
437
	public ConfigurationValueBuilder<JavaxMailBuilder, Charset> charset() {
438 1 1. charset : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::charset → NO_COVERAGE
		return charsetValueBuilder;
439
	}
440
441
	/**
442
	 * Defines a custom detector that will indicate which charset corresponds
443
	 * for a particular string.
444
	 * 
445
	 * This value preempts any other value defined by calling
446
	 * {@link #charset(Charset)} method.
447
	 * 
448
	 * If this method is called several times, only the last provider is used.
449
	 * 
450
	 * @param charsetDetector
451
	 *            the provider used to detect charset of a string
452
	 * @return this instance for fluent chaining
453
	 */
454
	public JavaxMailBuilder charset(CharsetDetector charsetDetector) {
455
		this.charsetDetector = charsetDetector;
456 1 1. charset : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::charset → NO_COVERAGE
		return this;
457
	}
458
459
	/**
460
	 * SMTP server may require authentication. In most cases, authentication is
461
	 * done using username/password. You can use this builder to quickly provide
462
	 * your username and password:
463
	 * 
464
	 * <pre>
465
	 * .sender(JavaMailBuilder.class)
466
	 *    .authenticator()
467
	 *        .username("foo")
468
	 *        .password("bar")
469
	 * </pre>
470
	 * 
471
	 * @return the builder to configure username/password authentication
472
	 */
473
	public UsernamePasswordAuthenticatorBuilder authenticator() {
474 1 1. authenticator : negated conditional → NO_COVERAGE
		if (authenticatorBuilder == null) {
475
			authenticatorBuilder = new UsernamePasswordAuthenticatorBuilder(this, buildContext);
476
		}
477 1 1. authenticator : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::authenticator → NO_COVERAGE
		return authenticatorBuilder;
478
	}
479
480
	/**
481
	 * SMTP server may require authentication. In most cases, authentication is
482
	 * done using username/password. However, if you need another authentication
483
	 * mechanism, you can directly provide your own {@link Authenticator}
484
	 * implementation:
485
	 * 
486
	 * <pre>
487
	 * .sender(JavaMailBuilder.class)
488
	 *    .authenticator(new MyCustomAuthenticator())
489
	 * </pre>
490
	 * 
491
	 * @param authenticator
492
	 *            the custom authenticator implementation
493
	 * @return the builder to configure username/password authentication
494
	 */
495
	public JavaxMailBuilder authenticator(Authenticator authenticator) {
496
		this.authenticator = authenticator;
497 1 1. authenticator : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::authenticator → NO_COVERAGE
		return this;
498
	}
499
500
	/**
501
	 * Ogham will transform general {@link Email} object into
502
	 * {@link MimeMessage}, {@link MimeMultipart}, {@link MimeBodyPart} objects.
503
	 * This transformation will fit almost all use cases but you may need to
504
	 * customize a part of the javax.mail message. Instead of doing again the
505
	 * same work Ogham does, this builder allows you to intercept the message to
506
	 * modify it just before sending it:
507
	 * 
508
	 * <pre>
509
	 * .sender(JavaMailBuilder.class)
510
	 *    .intercept(new MyCustomInterceptor())
511
	 * </pre>
512
	 * 
513
	 * See {@link JavaMailInterceptor} for more information.
514
	 * 
515
	 * @param interceptor
516
	 *            the custom interceptor used to modify {@link MimeMessage}
517
	 * @return this instance for fluent chaining
518
	 */
519
	public JavaxMailBuilder intercept(JavaMailInterceptor interceptor) {
520
		this.interceptor = interceptor;
521 1 1. intercept : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::intercept → NO_COVERAGE
		return this;
522
	}
523
524
	/**
525
	 * Builder that configures mimetype detection. Detection is used here to
526
	 * detect mimetype of {@link Attachment}s.
527
	 * 
528
	 * There exists several implementations to provide the mimetype:
529
	 * <ul>
530
	 * <li>Using Java {@link javax.activation.MimetypesFileTypeMap}</li>
531
	 * <li>Using Java 7 {@link Files#probeContentType(java.nio.file.Path)}</li>
532
	 * <li>Using <a href="http://tika.apache.org/">Apache Tika</a></li>
533
	 * <li>Using
534
	 * <a href="https://github.com/arimus/jmimemagic">JMimeMagic</a></li>
535
	 * </ul>
536
	 * 
537
	 * <p>
538
	 * Both implementations provided by Java are based on file extensions. This
539
	 * can't be used in most cases as we often handle {@link InputStream}s.
540
	 * </p>
541
	 * 
542
	 * <p>
543
	 * In previous version of Ogham, JMimeMagic was used and was working quite
544
	 * well. Unfortunately, the library is no more maintained.
545
	 * </p>
546
	 * 
547
	 * <p>
548
	 * You can configure how Tika will detect mimetype:
549
	 * 
550
	 * <pre>
551
	 * .mimetype()
552
	 *    .tika()
553
	 *       ...
554
	 * </pre>
555
	 * 
556
	 * <p>
557
	 * This builder allows to use several providers. It will chain them until
558
	 * one can find a valid mimetype. If none is found, you can explicitly
559
	 * provide the default one:
560
	 * 
561
	 * <pre>
562
	 * .mimetype()
563
	 *    .defaultMimetype("text/html")
564
	 * </pre>
565
	 * 
566
	 * <p>
567
	 * If no mimetype detector was previously defined, it creates a new one.
568
	 * Then each time you call {@link #mimetype()}, the same instance is used.
569
	 * </p>
570
	 * 
571
	 * @return the builder to configure mimetype detection
572
	 */
573
	public MimetypeDetectionBuilder<JavaxMailBuilder> mimetype() {
574 1 1. mimetype : negated conditional → NO_COVERAGE
		if (mimetypeBuilder == null) {
575
			mimetypeBuilder = new SimpleMimetypeDetectionBuilder<>(this, buildContext);
576
		}
577 1 1. mimetype : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::mimetype → NO_COVERAGE
		return mimetypeBuilder;
578
	}
579
580
	/**
581
	 * NOTE: this is mostly for advance usage (when creating a custom module).
582
	 * 
583
	 * Inherits mimetype configuration from another builder. This is useful for
584
	 * configuring independently different parts of Ogham but keeping a whole
585
	 * coherence.
586
	 * 
587
	 * The same instance is shared meaning that all changes done here will also
588
	 * impact the other builder.
589
	 * 
590
	 * <p>
591
	 * If a previous builder was defined (by calling {@link #mimetype()} for
592
	 * example), the new builder will override it.
593
	 * 
594
	 * @param builder
595
	 *            the builder to inherit
596
	 * @return this instance for fluent chaining
597
	 */
598
	public JavaxMailBuilder mimetype(MimetypeDetectionBuilder<?> builder) {
599
		mimetypeBuilder = new MimetypeDetectionBuilderDelegate<>(this, builder);
600 1 1. mimetype : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::mimetype → NO_COVERAGE
		return this;
601
	}
602
603
	/**
604
	 * Register additional properties that are used by JavaMail session.
605
	 * 
606
	 * <p>
607
	 * If a key was previously registered, it is replaced by the new value.
608
	 * 
609
	 * <p>
610
	 * If the value is {@code null}, the key is removed.
611
	 * 
612
	 * @param props
613
	 *            the properties to register
614
	 * @return this instance for fluent chaining
615
	 */
616
	public JavaxMailBuilder properties(Properties props) {
617 1 1. properties : removed call to fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::updateProperties → NO_COVERAGE
		updateProperties(props.entrySet());
618 1 1. properties : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::properties → NO_COVERAGE
		return this;
619
	}
620
621
	/**
622
	 * Register additional properties that are used by JavaMail session.
623
	 * 
624
	 * <p>
625
	 * If a key was previously registered, it is replaced by the new value.
626
	 * 
627
	 * <p>
628
	 * If the value is {@code null}, the key is removed.
629
	 * 
630
	 * 
631
	 * @param props
632
	 *            the properties to register
633
	 * @return this instance for fluent chaining
634
	 */
635
	public JavaxMailBuilder properties(Map<String, String> props) {
636 1 1. properties : removed call to fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::updateProperties → NO_COVERAGE
		updateProperties(props.entrySet());
637 1 1. properties : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::properties → NO_COVERAGE
		return this;
638
	}
639
640
	@Override
641
	public JavaxMailSender build() {
642
		Properties props = buildProperties();
643
		MimeTypeProvider mimetypeProvider = mimetype().build();
644
		LOG.info("Sending email using JavaMail API is registered");
645
		LOG.debug("SMTP server address: {}:{}", props.getProperty("mail.host"), props.getProperty("mail.port"));
646
		JavaMailAttachmentHandler attachmentHandler = buildAttachmentHandler(mimetypeProvider);
647 1 1. build : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::build → NO_COVERAGE
		return buildContext.register(new JavaxMailSender(props, buildContentHandler(mimetypeProvider, attachmentHandler), attachmentHandler, buildAuthenticator(), interceptor));
648
	}
649
650
	@Override
651
	public Condition<Message> getCondition() {
652
		PropertyResolver propertyResolver = buildPropertyResolver();
653 1 1. getCondition : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::getCondition → NO_COVERAGE
		return requiredProperty(propertyResolver, "mail.host").or(requiredProperty(propertyResolver, "mail.smtp.host"));
654
	}
655
656
	private Properties buildProperties() {
657 1 1. buildProperties : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildProperties → NO_COVERAGE
		return buildContext.register(new PropertiesBridge(new FirstExistingPropertiesResolver(buildPropertyResolver(), new JavaPropertiesResolver(additionalProperties, getConverter()))));
658
	}
659
660
	private OverrideJavaxMailResolver buildPropertyResolver() {
661 1 1. buildPropertyResolver : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildPropertyResolver → NO_COVERAGE
		return buildContext.register(new OverrideJavaxMailResolver(getPropertyResolver(), getConverter(), hostValueBuilder, portValueBuilder));
662
	}
663
664
	private Converter getConverter() {
665 1 1. getConverter : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::getConverter → NO_COVERAGE
		return buildContext.getConverter();
666
	}
667
668
	private Authenticator buildAuthenticator() {
669 1 1. buildAuthenticator : negated conditional → NO_COVERAGE
		if (this.authenticator != null) {
670 1 1. buildAuthenticator : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAuthenticator → NO_COVERAGE
			return this.authenticator;
671
		}
672 1 1. buildAuthenticator : negated conditional → NO_COVERAGE
		if (authenticatorBuilder != null) {
673 1 1. buildAuthenticator : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAuthenticator → NO_COVERAGE
			return authenticatorBuilder.build();
674
		}
675
		return null;
676
	}
677
678
	private PriorizedContentHandler buildContentHandler(MimeTypeProvider mimetypeProvider, JavaMailAttachmentHandler attachmentHandler) {
679
		PriorizedContentHandler contentHandler = buildContext.register(new PriorizedContentHandler());
680 1 1. buildContentHandler : removed call to fr/sii/ogham/email/sender/impl/javaxmail/PriorizedContentHandler::register → NO_COVERAGE
		contentHandler.register(MultiContent.class, buildContext.register(new MultiContentHandler(contentHandler)));
681 1 1. buildContentHandler : removed call to fr/sii/ogham/email/sender/impl/javaxmail/PriorizedContentHandler::register → NO_COVERAGE
		contentHandler.register(ContentWithAttachments.class, buildContext.register(new ContentWithAttachmentsHandler(contentHandler, attachmentHandler)));
682 1 1. buildContentHandler : removed call to fr/sii/ogham/email/sender/impl/javaxmail/PriorizedContentHandler::register → NO_COVERAGE
		contentHandler.register(MayHaveStringContent.class, buildContext.register(new StringContentHandler(mimetypeProvider, buildCharset())));
683 1 1. buildContentHandler : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildContentHandler → NO_COVERAGE
		return contentHandler;
684
	}
685
686
	private CharsetDetector buildCharset() {
687 1 1. buildCharset : negated conditional → NO_COVERAGE
		if (this.charsetDetector != null) {
688 1 1. buildCharset : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildCharset → NO_COVERAGE
			return this.charsetDetector;
689
		}
690
		Charset charset = this.charsetValueBuilder.getValue();
691 1 1. buildCharset : negated conditional → NO_COVERAGE
		if (charset != null) {
692 1 1. buildCharset : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildCharset → NO_COVERAGE
			return buildContext.register(new FixedCharsetDetector(charset));
693
		}
694 1 1. buildCharset : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildCharset → NO_COVERAGE
		return buildContext.register(new FixedCharsetDetector());
695
	}
696
697
	private PropertyResolver getPropertyResolver() {
698 1 1. getPropertyResolver : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::getPropertyResolver → NO_COVERAGE
		return buildContext.getPropertyResolver();
699
	}
700
701
	private JavaMailAttachmentHandler buildAttachmentHandler(MimeTypeProvider mimetypeProvider) {
702 1 1. buildAttachmentHandler : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAttachmentHandler → NO_COVERAGE
		return buildContext.register(new JavaMailAttachmentHandler(buildAttachmentResourceHandler(mimetypeProvider)));
703
	}
704
705
	private MapAttachmentResourceHandler buildAttachmentResourceHandler(MimeTypeProvider mimetypeProvider) {
706
		MapAttachmentResourceHandler resourceHandler = buildContext.register(new MapAttachmentResourceHandler());
707 1 1. buildAttachmentResourceHandler : removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE
		resourceHandler.registerResourceHandler(FileResource.class, buildContext.register(new FileResourceHandler(mimetypeProvider)));
708 1 1. buildAttachmentResourceHandler : removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE
		resourceHandler.registerResourceHandler(OverrideNameWrapper.class, buildContext.register(new OverrideNameWrapperResourceHandler(resourceHandler)));
709 1 1. buildAttachmentResourceHandler : removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE
		resourceHandler.registerResourceHandler(LookupResource.class, buildContext.register(new FailResourceHandler(noResourceResolverConfigured())));
710 1 1. buildAttachmentResourceHandler : removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE
		resourceHandler.registerResourceHandler(NamedResource.class, buildContext.register(new StreamResourceHandler(mimetypeProvider)));
711 1 1. buildAttachmentResourceHandler : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAttachmentResourceHandler → NO_COVERAGE
		return resourceHandler;
712
	}
713
714
	private static BiFunction<NamedResource, Attachment, AttachmentResourceHandlerException> noResourceResolverConfigured() {
715 2 1. lambda$noResourceResolverConfigured$0 : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::lambda$noResourceResolverConfigured$0 → NO_COVERAGE
2. noResourceResolverConfigured : replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::noResourceResolverConfigured → NO_COVERAGE
		return (resource, attachment) -> new UnresolvableAttachmentResourceHandlerException(
716
				"Failed to attach " + resource.getName() + " because it points to a path but no resource resolver has been configured.", attachment);
717
	}
718
719
	private void updateProperties(Set<? extends Entry<?, ?>> entrySet) {
720
		for (Entry<?, ?> prop : entrySet) {
721 1 1. updateProperties : negated conditional → NO_COVERAGE
			if (prop.getValue() == null) {
722
				additionalProperties.remove(prop.getKey());
723
			} else {
724
				additionalProperties.setProperty(prop.getKey().toString(), prop.getValue().toString());
725
			}
726
		}
727
	}
728
}

Mutations

239

1.1
Location : host
Killed by :
removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE

240

1.1
Location : host
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::host → NO_COVERAGE

280

1.1
Location : host
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::host → NO_COVERAGE

318

1.1
Location : port
Killed by :
removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE

319

1.1
Location : port
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::port → NO_COVERAGE

359

1.1
Location : port
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::port → NO_COVERAGE

397

1.1
Location : charset
Killed by :
removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE

398

1.1
Location : charset
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::charset → NO_COVERAGE

438

1.1
Location : charset
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::charset → NO_COVERAGE

456

1.1
Location : charset
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::charset → NO_COVERAGE

474

1.1
Location : authenticator
Killed by :
negated conditional → NO_COVERAGE

477

1.1
Location : authenticator
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::authenticator → NO_COVERAGE

497

1.1
Location : authenticator
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::authenticator → NO_COVERAGE

521

1.1
Location : intercept
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::intercept → NO_COVERAGE

574

1.1
Location : mimetype
Killed by :
negated conditional → NO_COVERAGE

577

1.1
Location : mimetype
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::mimetype → NO_COVERAGE

600

1.1
Location : mimetype
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::mimetype → NO_COVERAGE

617

1.1
Location : properties
Killed by :
removed call to fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::updateProperties → NO_COVERAGE

618

1.1
Location : properties
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::properties → NO_COVERAGE

636

1.1
Location : properties
Killed by :
removed call to fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::updateProperties → NO_COVERAGE

637

1.1
Location : properties
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::properties → NO_COVERAGE

647

1.1
Location : build
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::build → NO_COVERAGE

653

1.1
Location : getCondition
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::getCondition → NO_COVERAGE

657

1.1
Location : buildProperties
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildProperties → NO_COVERAGE

661

1.1
Location : buildPropertyResolver
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildPropertyResolver → NO_COVERAGE

665

1.1
Location : getConverter
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::getConverter → NO_COVERAGE

669

1.1
Location : buildAuthenticator
Killed by :
negated conditional → NO_COVERAGE

670

1.1
Location : buildAuthenticator
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAuthenticator → NO_COVERAGE

672

1.1
Location : buildAuthenticator
Killed by :
negated conditional → NO_COVERAGE

673

1.1
Location : buildAuthenticator
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAuthenticator → NO_COVERAGE

680

1.1
Location : buildContentHandler
Killed by :
removed call to fr/sii/ogham/email/sender/impl/javaxmail/PriorizedContentHandler::register → NO_COVERAGE

681

1.1
Location : buildContentHandler
Killed by :
removed call to fr/sii/ogham/email/sender/impl/javaxmail/PriorizedContentHandler::register → NO_COVERAGE

682

1.1
Location : buildContentHandler
Killed by :
removed call to fr/sii/ogham/email/sender/impl/javaxmail/PriorizedContentHandler::register → NO_COVERAGE

683

1.1
Location : buildContentHandler
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildContentHandler → NO_COVERAGE

687

1.1
Location : buildCharset
Killed by :
negated conditional → NO_COVERAGE

688

1.1
Location : buildCharset
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildCharset → NO_COVERAGE

691

1.1
Location : buildCharset
Killed by :
negated conditional → NO_COVERAGE

692

1.1
Location : buildCharset
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildCharset → NO_COVERAGE

694

1.1
Location : buildCharset
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildCharset → NO_COVERAGE

698

1.1
Location : getPropertyResolver
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::getPropertyResolver → NO_COVERAGE

702

1.1
Location : buildAttachmentHandler
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAttachmentHandler → NO_COVERAGE

707

1.1
Location : buildAttachmentResourceHandler
Killed by :
removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE

708

1.1
Location : buildAttachmentResourceHandler
Killed by :
removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE

709

1.1
Location : buildAttachmentResourceHandler
Killed by :
removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE

710

1.1
Location : buildAttachmentResourceHandler
Killed by :
removed call to fr/sii/ogham/email/sender/impl/javaxmail/MapAttachmentResourceHandler::registerResourceHandler → NO_COVERAGE

711

1.1
Location : buildAttachmentResourceHandler
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::buildAttachmentResourceHandler → NO_COVERAGE

715

1.1
Location : lambda$noResourceResolverConfigured$0
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::lambda$noResourceResolverConfigured$0 → NO_COVERAGE

2.2
Location : noResourceResolverConfigured
Killed by :
replaced return value with null for fr/sii/ogham/email/builder/javaxmail/JavaxMailBuilder::noResourceResolverConfigured → NO_COVERAGE

721

1.1
Location : updateProperties
Killed by :
negated conditional → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.13.1