BodyBuilder.java

1
package fr.sii.ogham.email.message.fluent;
2
3
import fr.sii.ogham.core.message.content.Content;
4
import fr.sii.ogham.core.message.content.MultiTemplateContent;
5
import fr.sii.ogham.core.message.fluent.SingleContentBuilder;
6
import fr.sii.ogham.core.resource.path.ResourcePath;
7
import fr.sii.ogham.core.template.context.Context;
8
import fr.sii.ogham.email.message.Email;
9
10
/**
11
 * Fluent API to build a content based on:
12
 * <ul>
13
 * <li>Either a single string</li>
14
 * <li>Or a single template string</li>
15
 * <li>Or a single template loaded from a path</li>
16
 * <li>Or two templates (HTML and text) loaded from a path</li>
17
 * </ul>
18
 * 
19
 * @author Aurélien Baudet
20
 *
21
 * @since 3.0.0
22
 */
23
public class BodyBuilder {
24
	private final Email parent;
25
	private final SingleContentBuilder<Email> singleBuilder;
26
	private Content content;
27
28
	/**
29
	 * Initializes with the parent to go back to.
30
	 * 
31
	 * @param parent
32
	 *            the parent instance
33
	 */
34
	public BodyBuilder(Email parent) {
35
		super();
36
		this.parent = parent;
37
		this.singleBuilder = new SingleContentBuilder<>(parent);
38
	}
39
40
	/**
41
	 * Set the content directly as a simple string.
42
	 * 
43
	 * <p>
44
	 * The body will have only one part (only one main body and no alternative
45
	 * body). It can be either HTML or textual.
46
	 * 
47
	 * <p>
48
	 * If this method is called several times, only the last value is used.
49
	 * 
50
	 * <p>
51
	 * If any other method of this class was called before calling this method,
52
	 * only the value of this method is used.
53
	 * 
54
	 * @param content
55
	 *            the content as a string
56
	 * @return the instance for fluent chaining
57
	 */
58
	public Email string(String content) {
59 3 1. string : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::string → NO_COVERAGE
2. string : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::string → KILLED
3. string : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::string → KILLED
		return singleBuilder.string(content);
60
	}
61
62
	/**
63
	 * Set the content using a template (directly provided as a string). The
64
	 * template contains variables that are evaluated against the bean object.
65
	 * 
66
	 * <p>
67
	 * The body will have only one part (only one main body and no alternative
68
	 * body). It can be either HTML or textual.
69
	 * 
70
	 * <p>
71
	 * If this method is called several times, only the last value is used.
72
	 * 
73
	 * <p>
74
	 * If any other method of this class was called before calling this method,
75
	 * only the value of this method is used.
76
	 * 
77
	 * @param template
78
	 *            the template directly provided as a string
79
	 * @param bean
80
	 *            the object that contains the variables that are referenced in
81
	 *            the template
82
	 * @return the instance for fluent chaining
83
	 */
84
	public Email templateString(String template, Object bean) {
85 2 1. templateString : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::templateString → NO_COVERAGE
2. templateString : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::templateString → KILLED
		return singleBuilder.templateString(template, bean);
86
	}
87
88
	/**
89
	 * Set the content using a template (directly provided as a string). The
90
	 * template contains variables that are evaluated against the evaluation
91
	 * context. The context contains at least the values of the variables but
92
	 * can also contain additional information for parsing the template.
93
	 * 
94
	 * <p>
95
	 * The body will have only one part (only one main body and no alternative
96
	 * body). It can be either HTML or textual.
97
	 * 
98
	 * <p>
99
	 * If this method is called several times, only the last value is used.
100
	 * 
101
	 * <p>
102
	 * If any other method of this class was called before calling this method,
103
	 * only the value of this method is used.
104
	 * 
105
	 * @param template
106
	 *            the template directly provided as a string
107
	 * @param context
108
	 *            contains at least the variables that are referenced in the
109
	 *            template and may contain additional information to parse the
110
	 *            template
111
	 * @return the instance for fluent chaining
112
	 */
113
	public Email templateString(String template, Context context) {
114 1 1. templateString : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::templateString → NO_COVERAGE
		return singleBuilder.templateString(template, context);
115
	}
116
117
	/**
118
	 * Set the content using template(s) loaded from a path. The template(s)
119
	 * contain variables that are evaluated against the bean object.
120
	 * 
121
	 * <p>
122
	 * This method lets you provide both main body and alternative body using a
123
	 * single path (without extension). For example:
124
	 * 
125
	 * You have two templates:
126
	 * <ul>
127
	 * <li>A textual template located at
128
	 * <code>/templates/email/register.txt</code> in the classpath</li>
129
	 * <li>An HTML template located at
130
	 * <code>/templates/email/register.html</code> in the classpath</li>
131
	 * </ul>
132
	 * 
133
	 * You can reference both templates with the same model:
134
	 * 
135
	 * <pre>
136
	 * {@code .template("/templates/email/register", new RegistrationContext(...))}
137
	 * </pre>
138
	 * 
139
	 * Both templates will be parsed using the same evaluation context. The HTML
140
	 * template will be used as the main body and the textual template will be
141
	 * used as the alternative body (when the email client can't read the HTML
142
	 * body).
143
	 * 
144
	 * <p>
145
	 * <strong>NOTE:</strong> the extensions varies according to template engine
146
	 * that is used to parse the template.
147
	 * 
148
	 * <p>
149
	 * This method is really convenient as if one template is missing (for
150
	 * example, you have only written the HTML template but not the textual
151
	 * template already), the found template is used as the main body (and the
152
	 * email won't have the alternative part). This way you can later add the
153
	 * missing template without changing your code.
154
	 * 
155
	 * <p>
156
	 * If this method is called several times, only the last value is used.
157
	 * 
158
	 * <p>
159
	 * If any other method of this class was called before calling this method,
160
	 * only the value of this method is used.
161
	 * 
162
	 * @param templatePath
163
	 *            the path to the template
164
	 * @param bean
165
	 *            the object that contains the variables that are referenced in
166
	 *            the template
167
	 * @return the instance for fluent chaining
168
	 */
169
	public Email template(String templatePath, Object bean) {
170
		this.content = new MultiTemplateContent(templatePath, bean);
171 2 1. template : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE
2. template : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → KILLED
		return parent;
172
	}
173
174
	/**
175
	 * Set the content using template(s) loaded from a path. The template(s)
176
	 * contain variables that are evaluated against the bean object.
177
	 * 
178
	 * <p>
179
	 * This method lets you provide both main body and alternative body using a
180
	 * single path (without extension). For example:
181
	 * 
182
	 * You have two templates:
183
	 * <ul>
184
	 * <li>A textual template located at
185
	 * <code>/templates/email/register.txt</code> in the classpath</li>
186
	 * <li>An HTML template located at
187
	 * <code>/templates/email/register.html</code> in the classpath</li>
188
	 * </ul>
189
	 * 
190
	 * You can reference both templates with the same model:
191
	 * 
192
	 * <pre>
193
	 * {@code .template("/templates/email/register", new RegistrationContext(...))}
194
	 * </pre>
195
	 * 
196
	 * Both templates will be parsed using the same evaluation context. The HTML
197
	 * template will be used as the main body and the textual template will be
198
	 * used as the alternative body (when the email client can't read the HTML
199
	 * body).
200
	 * 
201
	 * <p>
202
	 * <strong>NOTE:</strong> the extensions varies according to template engine
203
	 * that is used to parse the template.
204
	 * 
205
	 * <p>
206
	 * This method is really convenient as if one template is missing (for
207
	 * example, you have only written the HTML template but not the textual
208
	 * template already), the found template is used as the main body (and the
209
	 * email won't have the alternative part). This way you can later add the
210
	 * missing template without changing your code.
211
	 * 
212
	 * <p>
213
	 * If this method is called several times, only the last value is used.
214
	 * 
215
	 * <p>
216
	 * If any other method of this class was called before calling this method,
217
	 * only the value of this method is used.
218
	 * 
219
	 * @param templatePath
220
	 *            the path to the template
221
	 * @param bean
222
	 *            the object that contains the variables that are referenced in
223
	 *            the template
224
	 * @return the instance for fluent chaining
225
	 */
226
	public Email template(ResourcePath templatePath, Object bean) {
227
		this.content = new MultiTemplateContent(templatePath, bean);
228 1 1. template : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE
		return parent;
229
	}
230
231
	/**
232
	 * Set the content using template(s) loaded from a path. The template(s)
233
	 * contain variables that are evaluated against the evaluation context. The
234
	 * context contains at least the values of the variables but can also
235
	 * contain additional information for parsing the template.
236
	 * 
237
	 * <p>
238
	 * This method lets you provide both main body and alternative body using a
239
	 * single path (without extension). For example:
240
	 * 
241
	 * You have two templates:
242
	 * <ul>
243
	 * <li>A textual template located at
244
	 * <code>/templates/email/register.txt</code> in the classpath</li>
245
	 * <li>An HTML template located at
246
	 * <code>/templates/email/register.html</code> in the classpath</li>
247
	 * </ul>
248
	 * 
249
	 * You can reference both templates with the same model:
250
	 * 
251
	 * <pre>
252
	 * {@code .template("/templates/email/register", new RegistrationContext(...))}
253
	 * </pre>
254
	 * 
255
	 * Both templates will be parsed using the same evaluation context. The HTML
256
	 * template will be used as the main body and the textual template will be
257
	 * used as the alternative body (when the email client can't read the HTML
258
	 * body).
259
	 * 
260
	 * <p>
261
	 * <strong>NOTE:</strong> the extensions varies according to template engine
262
	 * that is used to parse the template.
263
	 * 
264
	 * <p>
265
	 * This method is really convenient as if one template is missing (for
266
	 * example, you have only written the HTML template but not the textual
267
	 * template already), the found template is used as the main body (and the
268
	 * email won't have the alternative part). This way you can later add the
269
	 * missing template without changing your code.
270
	 * 
271
	 * <p>
272
	 * If this method is called several times, only the last value is used.
273
	 * 
274
	 * <p>
275
	 * If any other method of this class was called before calling this method,
276
	 * only the value of this method is used.
277
	 * 
278
	 * @param templatePath
279
	 *            the path to the template
280
	 * @param context
281
	 *            contains at least the variables that are referenced in the
282
	 *            template and may contain additional information to parse the
283
	 *            template
284
	 * @return the instance for fluent chaining
285
	 */
286
	public Email template(String templatePath, Context context) {
287
		this.content = new MultiTemplateContent(templatePath, context);
288 2 1. template : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE
2. template : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → KILLED
		return parent;
289
	}
290
291
	/**
292
	 * Set the content using template(s) loaded from a path. The template(s)
293
	 * contain variables that are evaluated against the evaluation context. The
294
	 * context contains at least the values of the variables but can also
295
	 * contain additional information for parsing the template.
296
	 * 
297
	 * <p>
298
	 * This method lets you provide both main body and alternative body using a
299
	 * single path (without extension). For example:
300
	 * 
301
	 * You have two templates:
302
	 * <ul>
303
	 * <li>A textual template located at
304
	 * <code>/templates/email/register.txt</code> in the classpath</li>
305
	 * <li>An HTML template located at
306
	 * <code>/templates/email/register.html</code> in the classpath</li>
307
	 * </ul>
308
	 * 
309
	 * You can reference both templates with the same model:
310
	 * 
311
	 * <pre>
312
	 * {@code .template("/templates/email/register", new RegistrationContext(...))}
313
	 * </pre>
314
	 * 
315
	 * Both templates will be parsed using the same evaluation context. The HTML
316
	 * template will be used as the main body and the textual template will be
317
	 * used as the alternative body (when the email client can't read the HTML
318
	 * body).
319
	 * 
320
	 * <p>
321
	 * <strong>NOTE:</strong> the extensions varies according to template engine
322
	 * that is used to parse the template.
323
	 * 
324
	 * <p>
325
	 * This method is really convenient as if one template is missing (for
326
	 * example, you have only written the HTML template but not the textual
327
	 * template already), the found template is used as the main body (and the
328
	 * email won't have the alternative part). This way you can later add the
329
	 * missing template without changing your code.
330
	 * 
331
	 * <p>
332
	 * If this method is called several times, only the last value is used.
333
	 * 
334
	 * <p>
335
	 * If any other method of this class was called before calling this method,
336
	 * only the value of this method is used.
337
	 * 
338
	 * @param templatePath
339
	 *            the path to the template
340
	 * @param context
341
	 *            contains at least the variables that are referenced in the
342
	 *            template and may contain additional information to parse the
343
	 *            template
344
	 * @return the instance for fluent chaining
345
	 */
346
	public Email template(ResourcePath templatePath, Context context) {
347
		this.content = new MultiTemplateContent(templatePath, context);
348 1 1. template : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE
		return parent;
349
	}
350
351
	/**
352
	 * Build the final {@link Content}.
353
	 * 
354
	 * {@link #template(ResourcePath, Context)} method (and variants) preempts
355
	 * any call to {@link #string(String)},
356
	 * {@link #templateString(String, Context)} and
357
	 * {@link #templateString(String, Object)}.
358
	 * 
359
	 * @return the built content
360
	 */
361
	public Content build() {
362 4 1. build : negated conditional → SURVIVED
2. build : negated conditional → NO_COVERAGE
3. build : negated conditional → KILLED
4. build : negated conditional → KILLED
		if (content != null) {
363 2 1. build : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → NO_COVERAGE
2. build : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → KILLED
			return content;
364
		}
365 4 1. build : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → SURVIVED
2. build : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → NO_COVERAGE
3. build : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → KILLED
4. build : replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → KILLED
		return singleBuilder.build();
366
	}
367
}

Mutations

59

1.1
Location : string
Killed by : oghamjavamail.it.JavaMailStructureTest.plainTextBody(oghamjavamail.it.JavaMailStructureTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::string → KILLED

2.2
Location : string
Killed by : oghamall.it.email.FluentEmailTest.bodyString(oghamall.it.email.FluentEmailTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::string → KILLED

3.3
Location : string
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::string → NO_COVERAGE

85

1.1
Location : templateString
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::templateString → NO_COVERAGE

2.2
Location : templateString
Killed by : oghamall.it.email.FluentEmailTest.bodyTemplateString(oghamall.it.email.FluentEmailTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::templateString → KILLED

114

1.1
Location : templateString
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::templateString → NO_COVERAGE

171

1.1
Location : template
Killed by : oghamall.it.email.FluentEmailTest.invalidTemplate(oghamall.it.email.FluentEmailTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → KILLED

2.2
Location : template
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE

228

1.1
Location : template
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE

288

1.1
Location : template
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE

2.2
Location : template
Killed by : oghamall.it.retry.AutoRetryTest.doNotResendEmailIfTemplateNotFound(oghamall.it.retry.AutoRetryTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → KILLED

348

1.1
Location : template
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::template → NO_COVERAGE

362

1.1
Location : build
Killed by : none
negated conditional → SURVIVED

2.2
Location : build
Killed by : oghamjavamail.it.JavaMailStructureTest.plainTextBody(oghamjavamail.it.JavaMailStructureTest)
negated conditional → KILLED

3.3
Location : build
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : build
Killed by : oghamall.it.email.FluentEmailTest.invalidTemplate(oghamall.it.email.FluentEmailTest)
negated conditional → KILLED

363

1.1
Location : build
Killed by : oghamall.it.email.FluentEmailTest.invalidTemplate(oghamall.it.email.FluentEmailTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → KILLED

2.2
Location : build
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → NO_COVERAGE

365

1.1
Location : build
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → SURVIVED

2.2
Location : build
Killed by : oghamall.it.email.FluentEmailTest.bodyString(oghamall.it.email.FluentEmailTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → KILLED

3.3
Location : build
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → NO_COVERAGE

4.4
Location : build
Killed by : oghamjavamail.it.JavaMailStructureTest.plainTextBody(oghamjavamail.it.JavaMailStructureTest)
replaced return value with null for fr/sii/ogham/email/message/fluent/BodyBuilder::build → KILLED

Active mutators

Tests examined


Report generated by PIT OGHAM