CssInliningBuilder.java
package fr.sii.ogham.email.builder;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.builder.resolution.ClassPathResolutionBuilder;
import fr.sii.ogham.core.builder.resolution.FileResolutionBuilder;
import fr.sii.ogham.core.builder.resolution.ResourceResolutionBuilder;
import fr.sii.ogham.core.builder.resolution.ResourceResolutionBuilderHelper;
import fr.sii.ogham.core.builder.resolution.StringResolutionBuilder;
import fr.sii.ogham.core.fluent.AbstractParent;
import fr.sii.ogham.core.resource.path.LookupAwareRelativePathResolver;
import fr.sii.ogham.core.resource.path.RelativePathResolver;
import fr.sii.ogham.core.resource.resolver.FirstSupportingResourceResolver;
import fr.sii.ogham.core.resource.resolver.ResourceResolver;
import fr.sii.ogham.core.translator.content.ContentTranslator;
import fr.sii.ogham.html.inliner.CssInliner;
import fr.sii.ogham.html.inliner.impl.jsoup.JsoupCssInliner;
import fr.sii.ogham.html.translator.InlineCssTranslator;
/**
* Configures how CSS are applied on HTML emails.
*
* Inlining CSS means that CSS styles are loaded and applied on the matching
* HTML nodes using the {@code style} HTML attribute.
*
* @author Aurélien Baudet
*
*/
public class CssInliningBuilder extends AbstractParent<CssHandlingBuilder> implements ResourceResolutionBuilder<CssInliningBuilder>, Builder<ContentTranslator> {
private static final Logger LOG = LoggerFactory.getLogger(CssInliningBuilder.class);
private final BuildContext buildContext;
private ResourceResolutionBuilderHelper<CssInliningBuilder> resourceResolutionBuilderHelper;
private boolean useJsoup;
/**
* 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 CssInliningBuilder(CssHandlingBuilder parent, BuildContext buildContext) {
super(parent);
this.buildContext = buildContext;
resourceResolutionBuilderHelper = new ResourceResolutionBuilderHelper<>(this, buildContext);
}
/**
* Enable CSS inlining: CSS styles are loaded and applied on the matching
* HTML nodes using the {@code style} HTML attribute.
*
* The implementation uses <a href="https://jsoup.org/">jsoup</a> to parse
* HTML content.
*
* @return this instance for fluent chaining
*/
public CssInliningBuilder jsoup() {
useJsoup = true;
return this;
}
@Override
public ClassPathResolutionBuilder<CssInliningBuilder> classpath() {
return resourceResolutionBuilderHelper.classpath();
}
@Override
public FileResolutionBuilder<CssInliningBuilder> file() {
return resourceResolutionBuilderHelper.file();
}
@Override
public StringResolutionBuilder<CssInliningBuilder> string() {
return resourceResolutionBuilderHelper.string();
}
@Override
public CssInliningBuilder resolver(ResourceResolver resolver) {
return resourceResolutionBuilderHelper.resolver(resolver);
}
@Override
public ContentTranslator build() {
CssInliner cssInliner = buildInliner();
if (cssInliner == null) {
LOG.info("CSS won't be applied on HTML content of your emails because no inliner is configured");
return null;
}
return buildContext.register(new InlineCssTranslator(cssInliner, buildResolver(), buildRelativePathProvider()));
}
private CssInliner buildInliner() {
if (useJsoup) {
return buildContext.register(new JsoupCssInliner());
}
return null;
}
private ResourceResolver buildResolver() {
List<ResourceResolver> resolvers = resourceResolutionBuilderHelper.buildResolvers();
return buildContext.register(new FirstSupportingResourceResolver(resolvers));
}
private RelativePathResolver buildRelativePathProvider() {
return buildContext.register(new LookupAwareRelativePathResolver(resourceResolutionBuilderHelper.getAllLookups()));
}
}