1 | package fr.sii.ogham.email.builder; | |
2 | ||
3 | import org.slf4j.Logger; | |
4 | import org.slf4j.LoggerFactory; | |
5 | ||
6 | import fr.sii.ogham.core.async.Awaiter; | |
7 | import fr.sii.ogham.core.builder.ActivableAtRuntime; | |
8 | import fr.sii.ogham.core.builder.Builder; | |
9 | import fr.sii.ogham.core.builder.MessagingBuilder; | |
10 | import fr.sii.ogham.core.builder.condition.RequiredClass; | |
11 | import fr.sii.ogham.core.builder.condition.RequiredClasses; | |
12 | import fr.sii.ogham.core.builder.condition.RequiredProperties; | |
13 | import fr.sii.ogham.core.builder.condition.RequiredProperty; | |
14 | import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilder; | |
15 | import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilderDelegate; | |
16 | import fr.sii.ogham.core.builder.configurer.Configurer; | |
17 | import fr.sii.ogham.core.builder.configurer.MessagingConfigurer; | |
18 | import fr.sii.ogham.core.builder.context.BuildContext; | |
19 | import fr.sii.ogham.core.builder.env.EnvironmentBuilder; | |
20 | import fr.sii.ogham.core.builder.retry.RetryBuilder; | |
21 | import fr.sii.ogham.core.builder.sender.SenderImplementationBuilderHelper; | |
22 | import fr.sii.ogham.core.builder.template.DetectorBuilder; | |
23 | import fr.sii.ogham.core.builder.template.TemplateBuilderHelper; | |
24 | import fr.sii.ogham.core.builder.template.VariantBuilder; | |
25 | import fr.sii.ogham.core.condition.Condition; | |
26 | import fr.sii.ogham.core.condition.fluent.MessageConditions; | |
27 | import fr.sii.ogham.core.filler.MessageFiller; | |
28 | import fr.sii.ogham.core.fluent.AbstractParent; | |
29 | import fr.sii.ogham.core.message.content.MultiTemplateContent; | |
30 | import fr.sii.ogham.core.message.content.Variant; | |
31 | import fr.sii.ogham.core.retry.ExponentialDelayRetry; | |
32 | import fr.sii.ogham.core.retry.FixedDelayRetry; | |
33 | import fr.sii.ogham.core.retry.FixedIntervalRetry; | |
34 | import fr.sii.ogham.core.retry.PerExecutionDelayRetry; | |
35 | import fr.sii.ogham.core.retry.RetryExecutor; | |
36 | import fr.sii.ogham.core.sender.AutoRetrySender; | |
37 | import fr.sii.ogham.core.sender.ConditionalSender; | |
38 | import fr.sii.ogham.core.sender.ContentTranslatorSender; | |
39 | import fr.sii.ogham.core.sender.FillerSender; | |
40 | import fr.sii.ogham.core.sender.MessageSender; | |
41 | import fr.sii.ogham.core.template.parser.TemplateParser; | |
42 | import fr.sii.ogham.core.translator.content.ContentTranslator; | |
43 | import fr.sii.ogham.core.translator.content.EveryContentTranslator; | |
44 | import fr.sii.ogham.core.translator.content.MultiContentTranslator; | |
45 | import fr.sii.ogham.core.translator.content.TemplateContentTranslator; | |
46 | import fr.sii.ogham.core.translator.resource.AttachmentResourceTranslator; | |
47 | import fr.sii.ogham.core.util.BuilderUtils; | |
48 | import fr.sii.ogham.email.attachment.Attachment; | |
49 | import fr.sii.ogham.email.message.Email; | |
50 | import fr.sii.ogham.email.sender.AttachmentResourceTranslatorSender; | |
51 | import fr.sii.ogham.email.sender.EmailSender; | |
52 | import fr.sii.ogham.template.common.adapter.VariantResolver; | |
53 | ||
54 | /** | |
55 | * Configures how to send {@link Email} messages. It allows to: | |
56 | * <ul> | |
57 | * <li>register and configure several sender implementations</li> | |
58 | * <li>register and configure several template engines for parsing templates as | |
59 | * message content</li> | |
60 | * <li>configure handling of missing {@link Email} information</li> | |
61 | * <li>configure handling of file attachments</li> | |
62 | * <li>configure CSS and image handling for {@link Email}s with an HTML | |
63 | * body</li> | |
64 | * </ul> | |
65 | * | |
66 | * You can send an {@link Email} using the minimal behavior and using JavaMail | |
67 | * implementation: | |
68 | * | |
69 | * <pre> | |
70 | * <code> | |
71 | * // Instantiate the messaging service | |
72 | * MessagingService service = new MessagingBuilder() | |
73 | * .email() | |
74 | * .sender(JavaMailBuilder.class) // enable Email sending using JavaMail | |
75 | * .host("your SMTP server host") | |
76 | * .port("your SMTP server port") | |
77 | * .and() | |
78 | * .and() | |
79 | * .build(); | |
80 | * // send the email | |
81 | * service.send(new Email() | |
82 | * .from("sender email address") | |
83 | * .subject("email subject") | |
84 | * .content("email body") | |
85 | * .to("recipient email address")); | |
86 | * </code> | |
87 | * </pre> | |
88 | * | |
89 | * You can also send an {@link Email} using a template (using Freemarker for | |
90 | * example): | |
91 | * | |
92 | * The Freemarker template ("email/sample.html.ftl"): | |
93 | * | |
94 | * <pre> | |
95 | * <html> | |
96 | * <head> | |
97 | * </head> | |
98 | * <body> | |
99 | * Email content with variables: ${name} ${value} | |
100 | * </body> | |
101 | * </html> | |
102 | * </pre> | |
103 | * | |
104 | * Then you can send the {@link Email} like this: | |
105 | * | |
106 | * <pre> | |
107 | * <code> | |
108 | * // Instantiate the messaging service | |
109 | * MessagingService service = new MessagingBuilder() | |
110 | * .email() | |
111 | * .sender(JavaMailBuilder.class) // enable Email sending using JavaMail | |
112 | * .host("your SMTP server host") | |
113 | * .port("your SMTP server port") | |
114 | * .and() | |
115 | * .and() | |
116 | * .template(FreemarkerEmailBuilder.class) // enable templating using Freemarker | |
117 | * .classpath() | |
118 | * .lookup("classpath:") // search resources/templates in the classpath if a path is prefixed by "classpath:" | |
119 | * .and() | |
120 | * .and() | |
121 | * .build(); | |
122 | * // send the email | |
123 | * service.send(new Email() | |
124 | * .from("sender email address") | |
125 | * .subject("email subject") | |
126 | * .content(new TemplateContent("classpath:email/sample.html.ftl", new SampleBean("foo", 42))) | |
127 | * .to("recipient email address")); | |
128 | * </code> | |
129 | * </pre> | |
130 | * | |
131 | * <p> | |
132 | * Instead of explicitly configures SMTP host and port in your code, it could be | |
133 | * better to externalize the configuration in a properties file for example (for | |
134 | * example a file named "email.properties" in the classpath). The previous | |
135 | * example becomes: | |
136 | * | |
137 | * <pre> | |
138 | * <code> | |
139 | * // Instantiate the messaging service | |
140 | * MessagingService service = new MessagingBuilder() | |
141 | * .environment() | |
142 | * .properties("email.properties") | |
143 | * .and() | |
144 | * .email() | |
145 | * .sender(JavaMailBuilder.class) // enable Email sending using JavaMail | |
146 | * .host("${mail.host}") | |
147 | * .port("${mail.port}") | |
148 | * .and() | |
149 | * .and() | |
150 | * .template(FreemarkerEmailBuilder.class) // enable templating using Freemarker | |
151 | * .classpath() | |
152 | * .lookup("classpath:") // search resources/templates in the classpath if a path is prefixed by "classpath:" | |
153 | * .and() | |
154 | * .and() | |
155 | * .build(); | |
156 | * // send the email | |
157 | * service.send(new Email() | |
158 | * .from("sender email address") | |
159 | * .subject("email subject") | |
160 | * .content(new TemplateContent("classpath:email/sample.html.ftl", new SampleBean("foo", 42))) | |
161 | * .to("recipient email address")); | |
162 | * </code> | |
163 | * </pre> | |
164 | * | |
165 | * The content of the file "email.properties": | |
166 | * | |
167 | * <pre> | |
168 | * mail.host=your STMP server host | |
169 | * mail.port=your STMP server port | |
170 | * </pre> | |
171 | * | |
172 | * | |
173 | * Some fields of the Email may be automatically filled by a default value if | |
174 | * they are not defined. For example, the sender address could be configured | |
175 | * only once for your application: | |
176 | * | |
177 | * <pre> | |
178 | * <code> | |
179 | * // Instantiate the messaging service | |
180 | * MessagingService service = new MessagingBuilder() | |
181 | * .environment() | |
182 | * .properties("email.properties") | |
183 | * .and() | |
184 | * .email() | |
185 | * .sender(JavaMailBuilder.class) // enable Email sending using JavaMail | |
186 | * .host("${mail.host}") | |
187 | * .port("${mail.port}") | |
188 | * .and() | |
189 | * .autofill() // enables and configures autofilling | |
190 | * .from() | |
191 | * .defaultValue().properties("${email.sender.address}") | |
192 | * .and() | |
193 | * .and() | |
194 | * .template(FreemarkerEmailBuilder.class) // enable templating using Freemarker | |
195 | * .classpath() | |
196 | * .lookup("classpath:") // search resources/templates in the classpath if a path is prefixed by "classpath:" | |
197 | * .and() | |
198 | * .and() | |
199 | * .build(); | |
200 | * // send the email (now the sender address can be omitted) | |
201 | * service.send(new Email() | |
202 | * .subject("email subject") | |
203 | * .content(new TemplateContent("classpath:email/sample.html.ftl", new SampleBean("foo", 42))) | |
204 | * .to("recipient email address")); | |
205 | * </code> | |
206 | * </pre> | |
207 | * | |
208 | * The content of the file "email.properties": | |
209 | * | |
210 | * <pre> | |
211 | * mail.host=your STMP server host | |
212 | * mail.port=your STMP server port | |
213 | * email.sender.address=sender email address | |
214 | * </pre> | |
215 | * | |
216 | * | |
217 | * | |
218 | * Another very useful automatic filling is for providing the email subject: | |
219 | * | |
220 | * <pre> | |
221 | * <code> | |
222 | * // Instantiate the messaging service | |
223 | * MessagingService service = new MessagingBuilder() | |
224 | * .environment() | |
225 | * .properties("email.properties") | |
226 | * .and() | |
227 | * .email() | |
228 | * .sender(JavaMailBuilder.class) // enable Email sending using JavaMail | |
229 | * .host("${mail.host}") | |
230 | * .port("${mail.port}") | |
231 | * .and() | |
232 | * .autofill() // enables and configures autofilling | |
233 | * .from() | |
234 | * .defaultValue().properties("${email.sender.address}").and() | |
235 | * .and() | |
236 | * .subject() | |
237 | * .htmlTitle(true) // enables use of html title tag as subject | |
238 | * .and() | |
239 | * .template(FreemarkerEmailBuilder.class) // enable templating using Freemarker | |
240 | * .classpath() | |
241 | * .lookup("classpath:") // search resources/templates in the classpath if a path is prefixed by "classpath:" | |
242 | * .and() | |
243 | * .and() | |
244 | * .build(); | |
245 | * // send the email (now the subject can be omitted) | |
246 | * service.send(new Email() | |
247 | * .content(new TemplateContent("classpath:email/sample.html.ftl", new SampleBean("foo", 42))) | |
248 | * .to("recipient email address")); | |
249 | * </code> | |
250 | * </pre> | |
251 | * | |
252 | * Change your template: | |
253 | * | |
254 | * <pre> | |
255 | * <html> | |
256 | * <head> | |
257 | * <title>email subject - ${name}</title> | |
258 | * </head> | |
259 | * <body> | |
260 | * Email content with variables: ${name} ${value} | |
261 | * </body> | |
262 | * </html> | |
263 | * </pre> | |
264 | * | |
265 | * The obvious advantage is that you have a single place to handle email content | |
266 | * (body + subject). There is another benefit: you can also use variables in the | |
267 | * subject. | |
268 | * | |
269 | * | |
270 | * There many other configuration possibilities: | |
271 | * <ul> | |
272 | * <li>for configuring {@link Email}s with HTML content with a text fallback | |
273 | * (useful for smartphones preview of your email for example)</li> | |
274 | * <li>for configuring attachments handling</li> | |
275 | * <li>for configuring image and css handling</li> | |
276 | * </ul> | |
277 | * | |
278 | * <p> | |
279 | * All the previous examples are provided to understand what can be configured. | |
280 | * Hopefully, Ogham provides auto-configuration with a default behavior that | |
281 | * fits 95% of usages. This auto-configuration is provided by | |
282 | * {@link MessagingConfigurer}s. Those configurers are automatically applied | |
283 | * when using predefined {@link MessagingBuilder}s like | |
284 | * {@link MessagingBuilder#minimal()} and {@link MessagingBuilder#standard()}. | |
285 | * | |
286 | * The previous sample using standard configuration becomes: | |
287 | * | |
288 | * <pre> | |
289 | * <code> | |
290 | * // Instantiate the messaging service | |
291 | * MessagingService service = MessagingBuilder.standad() | |
292 | * .environment() | |
293 | * .properties("email.properties") | |
294 | * .and() | |
295 | * .build(); | |
296 | * // send the email | |
297 | * service.send(new Email() | |
298 | * .content(new TemplateContent("classpath:email/sample.html.ftl", new SampleBean("foo", 42))) | |
299 | * .to("recipient email address")); | |
300 | * </code> | |
301 | * </pre> | |
302 | * | |
303 | * The new content of the file "email.properties": | |
304 | * | |
305 | * <pre> | |
306 | * mail.host=your STMP server host | |
307 | * mail.port=your STMP server port | |
308 | * ogham.email.from.default-value=sender email address | |
309 | * </pre> | |
310 | * | |
311 | * <p> | |
312 | * You can also use the auto-configuration for benefit from default behaviors | |
313 | * and override some behaviors for your needs: | |
314 | * | |
315 | * <pre> | |
316 | * <code> | |
317 | * // Instantiate the messaging service | |
318 | * MessagingService service = MessagingBuilder.standard() | |
319 | * .environment() | |
320 | * .properties("email.properties") | |
321 | * .and() | |
322 | * .email() | |
323 | * .autofill() | |
324 | * .from() | |
325 | * .defaultValue() | |
326 | * .properties("${email.sender.address}") // overrides default sender email address property | |
327 | * .and() | |
328 | * .and() | |
329 | * .and() | |
330 | * .and() | |
331 | * .build(); | |
332 | * // send the email | |
333 | * service.send(new Email() | |
334 | * .content(new TemplateContent("classpath:email/sample.html.ftl", new SampleBean("foo", 42))) | |
335 | * .to("recipient email address")); | |
336 | * </code> | |
337 | * </pre> | |
338 | * | |
339 | * The new content of the file "email.properties": | |
340 | * | |
341 | * <pre> | |
342 | * mail.host=your STMP server host | |
343 | * mail.port=your STMP server port | |
344 | * email.sender.address=sender email address | |
345 | * </pre> | |
346 | * | |
347 | * @author Aurélien Baudet | |
348 | * | |
349 | */ | |
350 | public class EmailBuilder extends AbstractParent<MessagingBuilder> implements Builder<ConditionalSender> { | |
351 | private static final Logger LOG = LoggerFactory.getLogger(EmailBuilder.class); | |
352 | ||
353 | private final BuildContext buildContext; | |
354 | private final TemplateBuilderHelper<EmailBuilder> templateBuilderHelper; | |
355 | private final SenderImplementationBuilderHelper<EmailBuilder> senderBuilderHelper; | |
356 | private AttachmentHandlingBuilder attachmentBuilder; | |
357 | private AutofillEmailBuilder autofillBuilder; | |
358 | private CssHandlingBuilder cssBuilder; | |
359 | private ImageHandlingBuilder imageBuilder; | |
360 | private RetryBuilder<EmailBuilder> retryBuilder; | |
361 | | |
362 | /** | |
363 | * Initializes the builder with a parent builder. The parent builder is used | |
364 | * when calling {@link #and()} method. The {@link EnvironmentBuilder} is | |
365 | * used to evaluate properties when {@link #build()} method is called. | |
366 | * | |
367 | * @param parent | |
368 | * the parent builder | |
369 | * @param buildContext | |
370 | * for registering instances and property evaluation | |
371 | */ | |
372 | public EmailBuilder(MessagingBuilder parent, BuildContext buildContext) { | |
373 | super(parent); | |
374 | this.buildContext = buildContext; | |
375 | templateBuilderHelper = new TemplateBuilderHelper<>(this, buildContext); | |
376 | senderBuilderHelper = new SenderImplementationBuilderHelper<>(this, buildContext); | |
377 | } | |
378 | ||
379 | /** | |
380 | * Configures how {@link Attachment}s are handled. | |
381 | * | |
382 | * Attachment resolution consists of finding a file: | |
383 | * <ul> | |
384 | * <li>either on filesystem</li> | |
385 | * <li>or in the classpath</li> | |
386 | * <li>or anywhere else</li> | |
387 | * </ul> | |
388 | * | |
389 | * <p> | |
390 | * To identify which resolution to use, each resolution is configured to | |
391 | * handle one or several lookups prefixes. For example, if resolution is | |
392 | * configured like this: | |
393 | * | |
394 | * <pre> | |
395 | * <code> | |
396 | * .string() | |
397 | * .lookup("string:", "s:") | |
398 | * .and() | |
399 | * .file() | |
400 | * .lookup("file:") | |
401 | * .and() | |
402 | * .classpath() | |
403 | * .lookup("classpath:", ""); | |
404 | * </code> | |
405 | * </pre> | |
406 | * | |
407 | * Then you can reference a file that is in the classpath like this: | |
408 | * | |
409 | * <pre> | |
410 | * "classpath:foo/bar.pdf" | |
411 | * </pre> | |
412 | * | |
413 | * | |
414 | * <p> | |
415 | * Resource resolution is also able to handle path prefix and suffix. The | |
416 | * aim is for example to have a folder that contains all templates. The | |
417 | * developer then configures a path prefix for the folder. He can also | |
418 | * configure a suffix to fix extension for templates. Thanks to those | |
419 | * prefix/suffix, templates can now be referenced by the name of the file | |
420 | * (without extension). It is useful to reference a template independently | |
421 | * from where it is in reality (classpath, file or anywhere else) . | |
422 | * Switching from classpath to file and conversely can be done easily (by | |
423 | * updating the lookup). | |
424 | * | |
425 | * For example: | |
426 | * | |
427 | * <pre> | |
428 | * .classpath().lookup("classpath:").pathPrefix("foo/").pathSuffix(".html"); | |
429 | * | |
430 | * resourceResolver.getResource("classpath:bar"); | |
431 | * </pre> | |
432 | * | |
433 | * The real path is then {@code foo/bar.pdf}. | |
434 | * | |
435 | * <p> | |
436 | * This implementation is used by {@link MessagingBuilder} for general | |
437 | * configuration. That configuration may be inherited (applied to other | |
438 | * resource resolution builders). | |
439 | * | |
440 | * | |
441 | * <p> | |
442 | * Detection of the mimetype of each attachment is not directly configured | |
443 | * here. Attachment handling depends totally on the sender implementation. | |
444 | * Some implementations will require that a mimetype is provided (JavaMail | |
445 | * for example) while other implementations doesn't need it (SendGrid for | |
446 | * example). | |
447 | * | |
448 | * @return the builder to configure attachment handling | |
449 | */ | |
450 | public AttachmentHandlingBuilder attachments() { | |
451 |
8
1. attachments : negated conditional → NO_COVERAGE 2. attachments : negated conditional → KILLED 3. attachments : negated conditional → KILLED 4. attachments : negated conditional → KILLED 5. attachments : negated conditional → KILLED 6. attachments : negated conditional → KILLED 7. attachments : negated conditional → KILLED 8. attachments : negated conditional → KILLED |
if (attachmentBuilder == null) { |
452 | attachmentBuilder = new AttachmentHandlingBuilder(this, buildContext); | |
453 | } | |
454 |
8
1. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → NO_COVERAGE 2. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → KILLED 3. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → KILLED 4. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → KILLED 5. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → KILLED 6. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → KILLED 7. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → KILLED 8. attachments : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::attachments → KILLED |
return attachmentBuilder; |
455 | } | |
456 | ||
457 | /** | |
458 | * Configures how Ogham will add default values to the {@link Email} if some | |
459 | * information is missing. | |
460 | * | |
461 | * If sender address is missing, a default one can be defined in | |
462 | * configuration properties. | |
463 | * | |
464 | * If recipient address is missing, a default one can be defined in | |
465 | * configuration properties. | |
466 | * | |
467 | * If subject is missing, a default one can be defined either: | |
468 | * <ul> | |
469 | * <li>In HTML title</li> | |
470 | * <li>In first line of text template</li> | |
471 | * <li>Using a default value defined in configuration properties</li> | |
472 | * </ul> | |
473 | * | |
474 | * For example: | |
475 | * | |
476 | * <pre> | |
477 | * <code> | |
478 | * builder | |
479 | * .autofill() | |
480 | * .subject() | |
481 | * .defaultValue().properties("${ogham.email.subject.default-value}").and() | |
482 | * .htmlTitle(true) | |
483 | * .text().properties("${ogham.email.subject.extract-from-text.first-line-prefix}").defaultValue("Subject:").and() | |
484 | * .and() | |
485 | * .from() | |
486 | * .defaultValue().properties("${ogham.email.from.default-value}", "${mail.smtp.from}", "${mail.from}").and() | |
487 | * .and() | |
488 | * .to() | |
489 | * .defaultValue().properties("${ogham.email.to.default-value}").and() | |
490 | * .and() | |
491 | * .cc() | |
492 | * .defaultValue().properties("${ogham.email.cc.default-value}").and() | |
493 | * .and() | |
494 | * .bcc() | |
495 | * .defaultValue().properties("${ogham.email.bcc.default-value}") | |
496 | * </code> | |
497 | * </pre> | |
498 | * | |
499 | * @return the builder to configure autofilling of Email | |
500 | */ | |
501 | public AutofillEmailBuilder autofill() { | |
502 |
8
1. autofill : negated conditional → NO_COVERAGE 2. autofill : negated conditional → KILLED 3. autofill : negated conditional → KILLED 4. autofill : negated conditional → KILLED 5. autofill : negated conditional → KILLED 6. autofill : negated conditional → KILLED 7. autofill : negated conditional → KILLED 8. autofill : negated conditional → KILLED |
if (autofillBuilder == null) { |
503 | autofillBuilder = new AutofillEmailBuilder(this, buildContext); | |
504 | } | |
505 |
8
1. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → NO_COVERAGE 2. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → KILLED 3. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → KILLED 4. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → KILLED 5. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → KILLED 6. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → KILLED 7. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → KILLED 8. autofill : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autofill → KILLED |
return autofillBuilder; |
506 | } | |
507 | ||
508 | /** | |
509 | * CSS handling consists of defining how CSS are inlined in the email. | |
510 | * Inlining CSS means that CSS styles are loaded and applied on the matching | |
511 | * HTML nodes using the {@code style} HTML attribute. | |
512 | * | |
513 | * For example: | |
514 | * | |
515 | * <pre> | |
516 | * .css() | |
517 | * .inline() | |
518 | * .jsoup() | |
519 | * </pre> | |
520 | * | |
521 | * Enables inlining of CSS styles using Jsoup utility. | |
522 | * | |
523 | * @return the builder to configure css handling | |
524 | */ | |
525 | public CssHandlingBuilder css() { | |
526 |
8
1. css : negated conditional → NO_COVERAGE 2. css : negated conditional → KILLED 3. css : negated conditional → KILLED 4. css : negated conditional → KILLED 5. css : negated conditional → KILLED 6. css : negated conditional → KILLED 7. css : negated conditional → KILLED 8. css : negated conditional → KILLED |
if (cssBuilder == null) { |
527 | cssBuilder = new CssHandlingBuilder(this, buildContext); | |
528 | } | |
529 |
8
1. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → NO_COVERAGE 2. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → KILLED 3. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → KILLED 4. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → KILLED 5. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → KILLED 6. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → KILLED 7. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → KILLED 8. css : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::css → KILLED |
return cssBuilder; |
530 | } | |
531 | ||
532 | /** | |
533 | * Image handling consists of defining how images are inlined in the email: | |
534 | * <ul> | |
535 | * <li>Either inlining directly in the HTML content by enconding image into | |
536 | * base64 string</li> | |
537 | * <li>Or attaching the image to the email and referencing it using a | |
538 | * <a href="https://tools.ietf.org/html/rfc4021#section-2.2.2">Content-ID | |
539 | * (CID)</a></li> | |
540 | * <li>Or no inlining</li> | |
541 | * </ul> | |
542 | * | |
543 | * | |
544 | * For example: | |
545 | * | |
546 | * <pre> | |
547 | * .images() | |
548 | * .inline() | |
549 | * .attach() | |
550 | * .cid() | |
551 | * .generator(new SequentialIdGenerator()) | |
552 | * .and() | |
553 | * .and() | |
554 | * .base64(); | |
555 | * </pre> | |
556 | * | |
557 | * Enables both inlining modes (attaching images and encoding in base64). By | |
558 | * default, attaching is used if nothing is specified in the HTML. You can | |
559 | * also explicitly specify which mode to using the {@code data-inline-image} | |
560 | * attribute (see {@link ImageHandlingBuilder#inline()} for more | |
561 | * information). | |
562 | * | |
563 | * @return the builder to configure images handling | |
564 | */ | |
565 | public ImageHandlingBuilder images() { | |
566 |
8
1. images : negated conditional → NO_COVERAGE 2. images : negated conditional → KILLED 3. images : negated conditional → KILLED 4. images : negated conditional → KILLED 5. images : negated conditional → KILLED 6. images : negated conditional → KILLED 7. images : negated conditional → KILLED 8. images : negated conditional → KILLED |
if (imageBuilder == null) { |
567 | imageBuilder = new ImageHandlingBuilder(this, buildContext); | |
568 | } | |
569 |
8
1. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → NO_COVERAGE 2. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → KILLED 3. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → KILLED 4. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → KILLED 5. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → KILLED 6. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → KILLED 7. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → KILLED 8. images : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::images → KILLED |
return imageBuilder; |
570 | } | |
571 | ||
572 | /** | |
573 | * Registers and configures a {@link TemplateParser} through a dedicated | |
574 | * builder. | |
575 | * | |
576 | * For example: | |
577 | * | |
578 | * <pre> | |
579 | * .register(ThymeleafEmailBuilder.class) | |
580 | * .detector(new ThymeleafEngineDetector()); | |
581 | * </pre> | |
582 | * | |
583 | * <p> | |
584 | * Your {@link Builder} may implement {@link VariantBuilder} to handle | |
585 | * template {@link Variant}s (used for {@link MultiTemplateContent} that | |
586 | * provide a single path to templates with different extensions for | |
587 | * example). | |
588 | * </p> | |
589 | * | |
590 | * <p> | |
591 | * Your {@link Builder} may also implement {@link DetectorBuilder} in order | |
592 | * to indicate which kind of templates your {@link TemplateParser} is able | |
593 | * to parse. If your template parse is able to parse any template file you | |
594 | * are using, you may not need to implement {@link DetectorBuilder}. | |
595 | * </p> | |
596 | * | |
597 | * <p> | |
598 | * In order to be able to keep chaining, you builder instance may provide a | |
599 | * constructor with two arguments: | |
600 | * <ul> | |
601 | * <li>The type of the parent builder ({@code <P>})</li> | |
602 | * <li>The {@link EnvironmentBuilder} instance</li> | |
603 | * </ul> | |
604 | * If you don't care about chaining, just provide a default constructor. | |
605 | * | |
606 | * @param builderClass | |
607 | * the builder class to instantiate | |
608 | * @param <T> | |
609 | * the type of the builder | |
610 | * @return the builder to configure the implementation | |
611 | */ | |
612 | public <T extends Builder<? extends TemplateParser>> T template(Class<T> builderClass) { | |
613 |
5
1. template : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::template → NO_COVERAGE 2. template : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::template → KILLED 3. template : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::template → KILLED 4. template : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::template → KILLED 5. template : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::template → KILLED |
return templateBuilderHelper.register(builderClass); |
614 | } | |
615 | ||
616 | /** | |
617 | * Registers a custom message sender implementation. | |
618 | * | |
619 | * <p> | |
620 | * If your custom implementation is annotated by one or several of: | |
621 | * <ul> | |
622 | * <li>{@link RequiredClass}</li> | |
623 | * <li>{@link RequiredProperty}</li> | |
624 | * <li>{@link RequiredClasses}</li> | |
625 | * <li>{@link RequiredProperties}</li> | |
626 | * </ul> | |
627 | * Then if condition evaluation returns true, your implementation will be | |
628 | * used. If you provide several annotations, your implementation will be | |
629 | * used only if all conditions are met (and operator). | |
630 | * | |
631 | * <p> | |
632 | * If your custom implementation implements {@link ActivableAtRuntime}, and | |
633 | * the provided condition evaluation returns true, then your implementation | |
634 | * will be used. | |
635 | * | |
636 | * See {@link MessageConditions} to build your condition. | |
637 | * </p> | |
638 | * | |
639 | * <p> | |
640 | * If neither annotations nor implementation of {@link ActivableAtRuntime} | |
641 | * is used, then your custom implementation will be always used. All other | |
642 | * implementations (even standard ones) will never be used. | |
643 | * </p> | |
644 | * | |
645 | * @param sender | |
646 | * the sender to register | |
647 | * @return this instance for fluent chaining | |
648 | */ | |
649 | public EmailBuilder customSender(MessageSender sender) { | |
650 |
3
1. customSender : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::customSender → NO_COVERAGE 2. customSender : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::customSender → KILLED 3. customSender : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::customSender → KILLED |
senderBuilderHelper.customSender(sender); |
651 |
3
1. customSender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::customSender → NO_COVERAGE 2. customSender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::customSender → KILLED 3. customSender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::customSender → KILLED |
return this; |
652 | } | |
653 | ||
654 | /** | |
655 | * Registers and configures sender through a dedicated builder. | |
656 | * | |
657 | * For example: | |
658 | * | |
659 | * <pre> | |
660 | * .sender(JavaMailBuilder.class) | |
661 | * .host("localhost"); | |
662 | * </pre> | |
663 | * | |
664 | * <p> | |
665 | * If your custom builder is annotated by one or several of: | |
666 | * <ul> | |
667 | * <li>{@link RequiredClass}</li> | |
668 | * <li>{@link RequiredProperty}</li> | |
669 | * <li>{@link RequiredClasses}</li> | |
670 | * <li>{@link RequiredProperties}</li> | |
671 | * </ul> | |
672 | * Then if condition evaluation returns true, your built implementation will | |
673 | * be used. If you provide several annotations, your built implementation | |
674 | * will be used only if all conditions are met (and operator). | |
675 | * | |
676 | * <p> | |
677 | * If your custom builder implements {@link ActivableAtRuntime}, and the | |
678 | * provided condition evaluation returns true, then your built | |
679 | * implementation will be used. | |
680 | * | |
681 | * See {@link MessageConditions} to build your condition. | |
682 | * </p> | |
683 | * | |
684 | * <p> | |
685 | * If neither annotations nor implementation of {@link ActivableAtRuntime} | |
686 | * is used, then your built implementation will be always used. All other | |
687 | * implementations (even standard ones) will never be used. | |
688 | * </p> | |
689 | * | |
690 | * <p> | |
691 | * In order to be able to keep chaining, you builder instance may provide a | |
692 | * constructor with one argument with the type of the parent builder | |
693 | * ({@link EmailBuilder}). If you don't care about chaining, just provide a | |
694 | * default constructor. | |
695 | * </p> | |
696 | * | |
697 | * <p> | |
698 | * Your builder may return {@code null} when calling | |
699 | * {@link Builder#build()}. In this case it means that your implementation | |
700 | * can't be used due to current environment. Your implementation is then not | |
701 | * registered. | |
702 | * </p> | |
703 | * | |
704 | * @param builderClass | |
705 | * the builder class to instantiate | |
706 | * @param <T> | |
707 | * the type of the builder | |
708 | * @return the builder to configure the implementation | |
709 | * | |
710 | */ | |
711 | public <T extends Builder<? extends MessageSender>> T sender(Class<T> builderClass) { | |
712 |
6
1. sender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::sender → NO_COVERAGE 2. sender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::sender → KILLED 3. sender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::sender → KILLED 4. sender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::sender → KILLED 5. sender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::sender → KILLED 6. sender : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::sender → KILLED |
return senderBuilderHelper.register(builderClass); |
713 | } | |
714 | ||
715 | /** | |
716 | * If a variant is missing, then force to fail. | |
717 | * | |
718 | * <p> | |
719 | * This may be useful if you want for example to always provide a text | |
720 | * fallback when using an html template. So if a client can't read the html | |
721 | * version, the fallback version will still always be readable. So to avoid | |
722 | * forgetting to write text template, set this to true. | |
723 | * </p> | |
724 | * | |
725 | * <p> | |
726 | * The value set using this method takes precedence over any property and | |
727 | * default value configured using {@link #failIfMissingVariant()}. | |
728 | * | |
729 | * <pre> | |
730 | * .failIfMissingVariant(false) | |
731 | * .failIfMissingVariant() | |
732 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
733 | * .defaultValue(true) | |
734 | * </pre> | |
735 | * | |
736 | * <pre> | |
737 | * .failIfMissingVariant(false) | |
738 | * .failIfMissingVariant() | |
739 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
740 | * .defaultValue(true) | |
741 | * </pre> | |
742 | * | |
743 | * In both cases, {@code failIfMissingVariant(false)} is used. | |
744 | * | |
745 | * <p> | |
746 | * If this method is called several times, only the last value is used. | |
747 | * | |
748 | * <p> | |
749 | * If {@code null} value is set, it is like not setting a value at all. The | |
750 | * property/default value configuration is applied. | |
751 | * | |
752 | * @param fail | |
753 | * fail if a variant is missing | |
754 | * @return this instance for fluent chaining | |
755 | */ | |
756 | public EmailBuilder failIfMissingVariant(Boolean fail) { | |
757 | templateBuilderHelper.failIfMissingVariant(fail); | |
758 |
1
1. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → NO_COVERAGE |
return this; |
759 | } | |
760 | ||
761 | /** | |
762 | * If a variant is missing, then force to fail. | |
763 | * | |
764 | * <p> | |
765 | * This may be useful if you want for example to always provide a text | |
766 | * fallback when using an html template. So if a client can't read the html | |
767 | * version, the fallback version will still always be readable. So to avoid | |
768 | * forgetting to write text template, set this to true. | |
769 | * </p> | |
770 | * | |
771 | * <p> | |
772 | * This method is mainly used by {@link Configurer}s to register some | |
773 | * property keys and/or a default value. The aim is to let developer be able | |
774 | * to externalize its configuration (using system properties, configuration | |
775 | * file or anything else). If the developer doesn't configure any value for | |
776 | * the registered properties, the default value is used (if set). | |
777 | * | |
778 | * <pre> | |
779 | * .failIfMissingVariant() | |
780 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
781 | * .defaultValue(true) | |
782 | * </pre> | |
783 | * | |
784 | * <p> | |
785 | * Non-null value set using {@link #failIfMissingVariant(Boolean)} takes | |
786 | * precedence over property values and default value. | |
787 | * | |
788 | * <pre> | |
789 | * .failIfMissingVariant(false) | |
790 | * .failIfMissingVariant() | |
791 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
792 | * .defaultValue(true) | |
793 | * </pre> | |
794 | * | |
795 | * The value {@code false} is used regardless of the value of the properties | |
796 | * and default value. | |
797 | * | |
798 | * <p> | |
799 | * See {@link ConfigurationValueBuilder} for more information. | |
800 | * | |
801 | * | |
802 | * @return the builder to configure property keys/default value | |
803 | */ | |
804 | public ConfigurationValueBuilder<EmailBuilder, Boolean> failIfMissingVariant() { | |
805 |
8
1. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → NO_COVERAGE 2. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → KILLED 3. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → KILLED 4. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → KILLED 5. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → KILLED 6. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → KILLED 7. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → KILLED 8. failIfMissingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::failIfMissingVariant → KILLED |
return new ConfigurationValueBuilderDelegate<>(this, templateBuilderHelper.failIfMissingVariant()); |
806 | } | |
807 | ||
808 | /** | |
809 | * When {@link #failIfMissingVariant()} is enabled, also indicate which | |
810 | * paths were tried in order to help debugging why a variant was not found. | |
811 | * | |
812 | * <p> | |
813 | * The value set using this method takes precedence over any property and | |
814 | * default value configured using {@link #listPossiblePaths()}. | |
815 | * | |
816 | * <pre> | |
817 | * .listPossiblePaths(true) | |
818 | * .listPossiblePaths() | |
819 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
820 | * .defaultValue(false) | |
821 | * </pre> | |
822 | * | |
823 | * <pre> | |
824 | * .listPossiblePaths(true) | |
825 | * .listPossiblePaths() | |
826 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
827 | * .defaultValue(false) | |
828 | * </pre> | |
829 | * | |
830 | * In both cases, {@code listPossiblePaths(true)} is used. | |
831 | * | |
832 | * <p> | |
833 | * If this method is called several times, only the last value is used. | |
834 | * | |
835 | * <p> | |
836 | * If {@code null} value is set, it is like not setting a value at all. The | |
837 | * property/default value configuration is applied. | |
838 | * | |
839 | * @param enable | |
840 | * enable/disable tracking of possible paths for template | |
841 | * variants | |
842 | * @return this instance for fluent chaining | |
843 | */ | |
844 | public EmailBuilder listPossiblePaths(Boolean enable) { | |
845 | templateBuilderHelper.listPossiblePaths(enable); | |
846 |
1
1. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → NO_COVERAGE |
return this; |
847 | } | |
848 | ||
849 | /** | |
850 | * When {@link #failIfMissingVariant()} is enabled, also indicate which | |
851 | * paths were tried in order to help debugging why a variant was not found. | |
852 | * | |
853 | * <p> | |
854 | * This method is mainly used by {@link Configurer}s to register some | |
855 | * property keys and/or a default value. The aim is to let developer be able | |
856 | * to externalize its configuration (using system properties, configuration | |
857 | * file or anything else). If the developer doesn't configure any value for | |
858 | * the registered properties, the default value is used (if set). | |
859 | * | |
860 | * <pre> | |
861 | * .listPossiblePaths() | |
862 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
863 | * .defaultValue(false) | |
864 | * </pre> | |
865 | * | |
866 | * <p> | |
867 | * Non-null value set using {@link #listPossiblePaths(Boolean)} takes | |
868 | * precedence over property values and default value. | |
869 | * | |
870 | * <pre> | |
871 | * .listPossiblePaths(true) | |
872 | * .listPossiblePaths() | |
873 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
874 | * .defaultValue(false) | |
875 | * </pre> | |
876 | * | |
877 | * The value {@code true} is used regardless of the value of the properties | |
878 | * and default value. | |
879 | * | |
880 | * <p> | |
881 | * See {@link ConfigurationValueBuilder} for more information. | |
882 | * | |
883 | * | |
884 | * @return the builder to configure property keys/default value | |
885 | */ | |
886 | public ConfigurationValueBuilder<EmailBuilder, Boolean> listPossiblePaths() { | |
887 |
8
1. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → NO_COVERAGE 2. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → KILLED 3. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → KILLED 4. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → KILLED 5. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → KILLED 6. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → KILLED 7. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → KILLED 8. listPossiblePaths : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::listPossiblePaths → KILLED |
return new ConfigurationValueBuilderDelegate<>(this, templateBuilderHelper.listPossiblePaths()); |
888 | } | |
889 | ||
890 | /** | |
891 | * Provide custom resolver that will handle a missing variant. | |
892 | * | |
893 | * @param resolver | |
894 | * the custom resolver | |
895 | * @return this instance for fluent chaining | |
896 | */ | |
897 | public EmailBuilder missingVariant(VariantResolver resolver) { | |
898 |
1
1. missingVariant : removed call to fr/sii/ogham/core/builder/template/TemplateBuilderHelper::missingVariant → NO_COVERAGE |
templateBuilderHelper.missingVariant(resolver); |
899 |
1
1. missingVariant : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::missingVariant → NO_COVERAGE |
return this; |
900 | } | |
901 | | |
902 | /** | |
903 | * Configure automatic retry if message couldn't be sent. | |
904 | * | |
905 | * | |
906 | * For example: | |
907 | * | |
908 | * <pre> | |
909 | * .autoRetry() | |
910 | * .fixedDelay() | |
911 | * .maxRetries().properties("${ogham.email.send-retry.max-attempts}").and() | |
912 | * .delay().properties("${ogham.email.send-retry.delay-between-attempts}") | |
913 | * </pre> | |
914 | * | |
915 | * | |
916 | * <p> | |
917 | * This builder lets you configure: | |
918 | * <ul> | |
919 | * <li>The retry strategy: | |
920 | * <ul> | |
921 | * <li>{@link FixedDelayRetry}: wait for a fixed delay after the last | |
922 | * failure</li> | |
923 | * <li>{@link FixedIntervalRetry}: wait for a fixed delay between executions | |
924 | * (do not wait for the end of the action)</li> | |
925 | * <li>{@link ExponentialDelayRetry}: start with a delay, the next delay | |
926 | * will be doubled on so on</li> | |
927 | * <li>{@link PerExecutionDelayRetry}: provide a custom delay for each | |
928 | * execution</li> | |
929 | * </ul> | |
930 | * </li> | |
931 | * <li>The {@link RetryExecutor} implementation</li> | |
932 | * <li>The {@link Awaiter} implementation</li> | |
933 | * <li>The {@link Condition} used to determine if the raised error should | |
934 | * trigger a retry or not</li> | |
935 | * </ul> | |
936 | * | |
937 | * @return the builder to configure retry management | |
938 | */ | |
939 | public RetryBuilder<EmailBuilder> autoRetry() { | |
940 |
8
1. autoRetry : negated conditional → NO_COVERAGE 2. autoRetry : negated conditional → KILLED 3. autoRetry : negated conditional → KILLED 4. autoRetry : negated conditional → KILLED 5. autoRetry : negated conditional → KILLED 6. autoRetry : negated conditional → KILLED 7. autoRetry : negated conditional → KILLED 8. autoRetry : negated conditional → KILLED |
if (retryBuilder == null) { |
941 | retryBuilder = new RetryBuilder<>(this, buildContext); | |
942 | } | |
943 |
8
1. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → NO_COVERAGE 2. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → KILLED 3. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → KILLED 4. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → KILLED 5. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → KILLED 6. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → KILLED 7. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → KILLED 8. autoRetry : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::autoRetry → KILLED |
return retryBuilder; |
944 | } | |
945 | ||
946 | @Override | |
947 | public ConditionalSender build() { | |
948 | EmailSender emailSender = buildContext.register(new EmailSender()); | |
949 | ConditionalSender sender = emailSender; | |
950 |
7
1. build : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::addSenders → SURVIVED 2. build : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::addSenders → NO_COVERAGE 3. build : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::addSenders → KILLED 4. build : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::addSenders → KILLED 5. build : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::addSenders → KILLED 6. build : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::addSenders → KILLED 7. build : removed call to fr/sii/ogham/core/builder/sender/SenderImplementationBuilderHelper::addSenders → KILLED |
senderBuilderHelper.addSenders(emailSender); |
951 |
4
1. build : negated conditional → NO_COVERAGE 2. build : negated conditional → SURVIVED 3. build : negated conditional → KILLED 4. build : negated conditional → KILLED |
if (autofillBuilder != null) { |
952 | MessageFiller messageFiller = autofillBuilder.build(); | |
953 | LOG.debug("Automatic filling of message enabled {}", messageFiller); | |
954 | sender = buildContext.register(new FillerSender(messageFiller, sender)); | |
955 | } | |
956 |
4
1. build : negated conditional → NO_COVERAGE 2. build : negated conditional → SURVIVED 3. build : negated conditional → KILLED 4. build : negated conditional → KILLED |
if (attachmentBuilder != null) { |
957 | AttachmentResourceTranslator resourceTranslator = attachmentBuilder.build(); | |
958 | LOG.debug("Resource translation enabled {}", resourceTranslator); | |
959 | sender = buildContext.register(new AttachmentResourceTranslatorSender(resourceTranslator, sender)); | |
960 | } | |
961 |
8
1. build : negated conditional → NO_COVERAGE 2. build : negated conditional → SURVIVED 3. build : negated conditional → NO_COVERAGE 4. build : negated conditional → SURVIVED 5. build : negated conditional → NO_COVERAGE 6. build : negated conditional → SURVIVED 7. build : negated conditional → KILLED 8. build : negated conditional → KILLED |
if (templateBuilderHelper.hasRegisteredTemplates() || cssBuilder != null || imageBuilder != null) { |
962 | ContentTranslator translator = buildContentTranslator(); | |
963 | LOG.debug("Content translation enabled {}", translator); | |
964 | sender = buildContext.register(new ContentTranslatorSender(translator, sender)); | |
965 | } | |
966 | RetryExecutor retryExecutor = BuilderUtils.build(retryBuilder); | |
967 |
7
1. build : negated conditional → NO_COVERAGE 2. build : negated conditional → SURVIVED 3. build : negated conditional → KILLED 4. build : negated conditional → KILLED 5. build : negated conditional → KILLED 6. build : negated conditional → KILLED 7. build : negated conditional → KILLED |
if (retryExecutor != null) { |
968 | LOG.debug("Automatic retry of message sending enabled {}", retryExecutor); | |
969 | sender = buildContext.register(new AutoRetrySender(sender, retryExecutor)); | |
970 | } | |
971 |
8
1. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → NO_COVERAGE 2. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → KILLED 3. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → KILLED 4. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → KILLED 5. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → KILLED 6. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → KILLED 7. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → KILLED 8. build : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::build → KILLED |
return sender; |
972 | } | |
973 | ||
974 | private ContentTranslator buildContentTranslator() { | |
975 | EveryContentTranslator translator = buildContext.register(new EveryContentTranslator()); | |
976 |
5
1. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addTemplateTranslator → NO_COVERAGE 2. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addTemplateTranslator → SURVIVED 3. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addTemplateTranslator → KILLED 4. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addTemplateTranslator → KILLED 5. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addTemplateTranslator → KILLED |
addTemplateTranslator(translator); |
977 |
3
1. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addMultiContent → NO_COVERAGE 2. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addMultiContent → SURVIVED 3. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addMultiContent → KILLED |
addMultiContent(translator); |
978 |
3
1. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addCssInlining → SURVIVED 2. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addCssInlining → NO_COVERAGE 3. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addCssInlining → KILLED |
addCssInlining(translator); |
979 |
3
1. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addImageInlining → SURVIVED 2. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addImageInlining → NO_COVERAGE 3. buildContentTranslator : removed call to fr/sii/ogham/email/builder/EmailBuilder::addImageInlining → KILLED |
addImageInlining(translator); |
980 |
7
1. buildContentTranslator : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::buildContentTranslator → SURVIVED 2. buildContentTranslator : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::buildContentTranslator → NO_COVERAGE 3. buildContentTranslator : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::buildContentTranslator → KILLED 4. buildContentTranslator : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::buildContentTranslator → KILLED 5. buildContentTranslator : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::buildContentTranslator → KILLED 6. buildContentTranslator : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::buildContentTranslator → KILLED 7. buildContentTranslator : replaced return value with null for fr/sii/ogham/email/builder/EmailBuilder::buildContentTranslator → KILLED |
return translator; |
981 | } | |
982 | ||
983 | private void addTemplateTranslator(EveryContentTranslator translator) { | |
984 |
8
1. addTemplateTranslator : negated conditional → NO_COVERAGE 2. addTemplateTranslator : negated conditional → KILLED 3. addTemplateTranslator : negated conditional → KILLED 4. addTemplateTranslator : negated conditional → KILLED 5. addTemplateTranslator : negated conditional → KILLED 6. addTemplateTranslator : negated conditional → KILLED 7. addTemplateTranslator : negated conditional → KILLED 8. addTemplateTranslator : negated conditional → KILLED |
if (!templateBuilderHelper.hasRegisteredTemplates()) { |
985 | return; | |
986 | } | |
987 | TemplateParser templateParser = templateBuilderHelper.buildTemplateParser(); | |
988 | LOG.debug("Registering content translator that parses templates using {}", templateParser); | |
989 |
4
1. addTemplateTranslator : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → NO_COVERAGE 2. addTemplateTranslator : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → KILLED 3. addTemplateTranslator : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → KILLED 4. addTemplateTranslator : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → KILLED |
translator.addTranslator(buildContext.register(new TemplateContentTranslator(templateParser, templateBuilderHelper.buildVariant()))); |
990 | } | |
991 | ||
992 | private void addMultiContent(EveryContentTranslator translator) { | |
993 |
3
1. addMultiContent : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → SURVIVED 2. addMultiContent : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → NO_COVERAGE 3. addMultiContent : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → KILLED |
translator.addTranslator(buildContext.register(new MultiContentTranslator(translator))); |
994 | } | |
995 | ||
996 | private void addImageInlining(EveryContentTranslator translator) { | |
997 |
3
1. addImageInlining : negated conditional → NO_COVERAGE 2. addImageInlining : negated conditional → SURVIVED 3. addImageInlining : negated conditional → KILLED |
if (imageBuilder == null) { |
998 | return; | |
999 | } | |
1000 | ContentTranslator imageInliner = imageBuilder.build(); | |
1001 |
3
1. addImageInlining : negated conditional → NO_COVERAGE 2. addImageInlining : negated conditional → SURVIVED 3. addImageInlining : negated conditional → KILLED |
if (imageInliner != null) { |
1002 | LOG.debug("Image inlining is enabled"); | |
1003 |
3
1. addImageInlining : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → SURVIVED 2. addImageInlining : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → NO_COVERAGE 3. addImageInlining : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → KILLED |
translator.addTranslator(imageInliner); |
1004 | } | |
1005 | } | |
1006 | ||
1007 | private void addCssInlining(EveryContentTranslator translator) { | |
1008 |
3
1. addCssInlining : negated conditional → NO_COVERAGE 2. addCssInlining : negated conditional → SURVIVED 3. addCssInlining : negated conditional → KILLED |
if (cssBuilder == null) { |
1009 | return; | |
1010 | } | |
1011 | ContentTranslator cssInliner = cssBuilder.build(); | |
1012 |
3
1. addCssInlining : negated conditional → SURVIVED 2. addCssInlining : negated conditional → NO_COVERAGE 3. addCssInlining : negated conditional → KILLED |
if (cssInliner != null) { |
1013 | LOG.debug("CSS inlining is enabled"); | |
1014 |
3
1. addCssInlining : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → SURVIVED 2. addCssInlining : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → NO_COVERAGE 3. addCssInlining : removed call to fr/sii/ogham/core/translator/content/EveryContentTranslator::addTranslator → KILLED |
translator.addTranslator(cssInliner); |
1015 | } | |
1016 | } | |
1017 | ||
1018 | } | |
Mutations | ||
451 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
454 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
502 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
505 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
526 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
529 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
566 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
569 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
613 |
1.1 2.2 3.3 4.4 5.5 |
|
650 |
1.1 2.2 3.3 |
|
651 |
1.1 2.2 3.3 |
|
712 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
758 |
1.1 |
|
805 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
846 |
1.1 |
|
887 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
898 |
1.1 |
|
899 |
1.1 |
|
940 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
943 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
950 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
951 |
1.1 2.2 3.3 4.4 |
|
956 |
1.1 2.2 3.3 4.4 |
|
961 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
967 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
971 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
976 |
1.1 2.2 3.3 4.4 5.5 |
|
977 |
1.1 2.2 3.3 |
|
978 |
1.1 2.2 3.3 |
|
979 |
1.1 2.2 3.3 |
|
980 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
984 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
989 |
1.1 2.2 3.3 4.4 |
|
993 |
1.1 2.2 3.3 |
|
997 |
1.1 2.2 3.3 |
|
1001 |
1.1 2.2 3.3 |
|
1003 |
1.1 2.2 3.3 |
|
1008 |
1.1 2.2 3.3 |
|
1012 |
1.1 2.2 3.3 |
|
1014 |
1.1 2.2 3.3 |