ImageHandlingBuilder.java
package fr.sii.ogham.email.builder;
import fr.sii.ogham.core.builder.Builder;
import fr.sii.ogham.core.builder.context.BuildContext;
import fr.sii.ogham.core.builder.env.EnvironmentBuilder;
import fr.sii.ogham.core.fluent.AbstractParent;
import fr.sii.ogham.core.translator.content.ContentTranslator;
/**
* Image handling consists of defining how images are inlined in the email:
* <ul>
* <li>Either inlining directly in the HTML content by encoding image into
* base64 string</li>
* <li>Or attaching the image to the email and referencing it using a
* <a href="https://tools.ietf.org/html/rfc4021#section-2.2.2">Content-ID
* (CID)</a></li>
* <li>Or no inlining</li>
* </ul>
*
* @author Aurélien Baudet
*
*/
public class ImageHandlingBuilder extends AbstractParent<EmailBuilder> implements Builder<ContentTranslator> {
private final BuildContext buildContext;
private ImageInliningBuilder imageInliningBuilder;
/**
* Initializes the builder with a parent builder. The parent builder is used
* when calling {@link #and()} method. The {@link EnvironmentBuilder} is
* used to evaluate properties when {@link #build()} method is called.
*
* @param parent
* the parent builder
* @param buildContext
* for registering instances and property evaluation
*/
public ImageHandlingBuilder(EmailBuilder parent, BuildContext buildContext) {
super(parent);
this.buildContext = buildContext;
}
/**
* Configures how images are handled. Image handling consists of defining
* how images are inlined in the email:
* <ul>
* <li>Either inlining directly in the HTML content by encoding image into
* base64 string</li>
* <li>Or attaching the image to the email and referencing it using a
* <a href="https://tools.ietf.org/html/rfc4021#section-2.2.2">Content-ID
* (CID)</a></li>
* <li>Or no inlining</li>
* </ul>
*
*
* This builder is used to enable the inlining modes (and to configure
* them). Several modes can be enabled.
*
* <p>
* If {@link ImageInliningBuilder#attach()} is called, it enables image
* attachment.
*
* Image defined in a html must be referenced by a
* <a href="https://tools.ietf.org/html/rfc4021#section-2.2.2">Content-ID
* (or CID)</a> if the image is attached to the email.
*
* For example, if your template contains the following HTML code:
*
* <pre>
* {@code
* <img src="classpath:/foo.png" data-inline-image="attach" />
* }
* </pre>
*
* Then the image will be loaded from the classpath and attached to the
* email. The src attribute will be replaced by the Content-ID.
*
* It also works for images included from CSS:
*
* <pre>
* <code>
* <style>
* .some-class {
* background: url('classpath:/foo.png');
* --inline-image: attach;
* }
* </style>
* </code>
* </pre>
*
* Or directly on {@code style} attribute:
*
* <pre>
* {@code
* <div style="background: url('classpath:/foo.png'); --inline-image: attach;"></div>
* }
* </pre>
*
* Then the image will be loaded from the classpath and attached to the
* email. The url will be replaced by the Content-ID.
*
* <p>
* If {@link ImageInliningBuilder#base64()} is called, it enables inlining
* by converting image content into base64 string and using the base64
* string as image source.
*
* For example, if your template contains the following HTML code:
*
* <pre>
* {@code
* <img src="classpath:/foo.png" data-inline-image="base64" />
* }
* </pre>
*
* Then the image will be loaded from the classpath and encoded into a
* base64 string. This base64 string is used in the src attribute of the
* {@code <img>}.
*
* It also works for images included from CSS:
*
* <pre>
* <code>
* <style>
* .some-class {
* background: url('classpath:/foo.png');
* --inline-image: base64;
* }
* </style>
* </code>
* </pre>
*
* Or directly on {@code style} attribute:
*
* <pre>
* {@code
* <div style="background: url('classpath:/foo.png'); --inline-image: base64;"></div>
* }
* </pre>
*
* Then the image will be loaded from the classpath and encoded into a
* base64 string. The url is updated with the base64 string.
*
* <p>
* If you don't want to inline a particular image, you can set the
* "data-inline-image" attribute to "skip":
*
* <pre>
* {@code
* <img src="classpath:/foo.png" data-inline-image="skip" />
* }
* </pre>
*
* Then the image won't be inlined at all.
*
* <p>
* If no inline mode is explicitly defined on the {@code <img>}:
*
* <pre>
* {@code
* <img src="classpath:/foo.png" />
* }
* </pre>
*
* The behavior depends on what you have configured:
* <ul>
* <li>If {@link ImageInliningBuilder#attach()} is enabled (has been
* called), then image will be loaded from the classpath and attached to the
* email. The src attribute will be replaced by the Content-ID.</li>
* <li>If {@link ImageInliningBuilder#attach()} is not enabled (never
* called) and {@link ImageInliningBuilder#base64()} is enabled (has been
* called), then the image will be loaded from the classpath and encoded
* into a base64 string. This base64 string is used in the src attribute of
* the image.</li>
* <li>If neither {@link ImageInliningBuilder#attach()} nor
* {@link ImageInliningBuilder#base64()} are enabled (never called), then
* images won't be inlined at all</li>
* </ul>
*
* @return the builder to configure image inlining
*/
public ImageInliningBuilder inline() {
if (imageInliningBuilder == null) {
imageInliningBuilder = new ImageInliningBuilder(this, buildContext);
}
return imageInliningBuilder;
}
@Override
public ContentTranslator build() {
if (imageInliningBuilder == null) {
return null;
}
return imageInliningBuilder.build();
}
}