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 2.2 3.3 |
|
85 |
1.1 2.2 |
|
114 |
1.1 |
|
171 |
1.1 2.2 |
|
228 |
1.1 |
|
288 |
1.1 2.2 |
|
348 |
1.1 |
|
362 |
1.1 2.2 3.3 4.4 |
|
363 |
1.1 2.2 |
|
365 |
1.1 2.2 3.3 4.4 |