io.quarkus.qute.runtime.EngineProducer Maven / Gradle / Ivy
package io.quarkus.qute.runtime;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import javax.enterprise.inject.Produces;
import javax.inject.Singleton;
import javax.interceptor.Interceptor;
import org.jboss.logging.Logger;
import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.qute.Engine;
import io.quarkus.qute.EngineBuilder;
import io.quarkus.qute.HtmlEscaper;
import io.quarkus.qute.NamespaceResolver;
import io.quarkus.qute.ReflectionValueResolver;
import io.quarkus.qute.Resolver;
import io.quarkus.qute.Results;
import io.quarkus.qute.TemplateLocator.TemplateLocation;
import io.quarkus.qute.UserTagSectionHelper;
import io.quarkus.qute.ValueResolver;
import io.quarkus.qute.ValueResolvers;
import io.quarkus.qute.Variant;
import io.quarkus.qute.runtime.QuteRecorder.QuteContext;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.Startup;
@Startup(Interceptor.Priority.PLATFORM_BEFORE)
@Singleton
public class EngineProducer {
public static final String INJECT_NAMESPACE = "inject";
private static final String TAGS = "tags/";
private static final Logger LOGGER = Logger.getLogger(EngineProducer.class);
private final Engine engine;
private final ContentTypes contentTypes;
private final List tags;
private final List suffixes;
private final String basePath;
private final String tagPath;
public EngineProducer(QuteContext context, QuteConfig config, QuteRuntimeConfig runtimeConfig,
Event builderReady, Event engineReady, ContentTypes contentTypes, LaunchMode launchMode) {
this.contentTypes = contentTypes;
this.suffixes = config.suffixes;
this.basePath = "templates/";
this.tagPath = basePath + TAGS;
this.tags = context.getTags();
LOGGER.debugf("Initializing Qute [templates: %s, tags: %s, resolvers: %s", context.getTemplatePaths(), tags,
context.getResolverClasses());
EngineBuilder builder = Engine.builder()
.addDefaultSectionHelpers();
// We don't register the map resolver because of param declaration validation
// See DefaultTemplateExtensions
builder.addValueResolver(ValueResolvers.thisResolver());
builder.addValueResolver(ValueResolvers.orResolver());
builder.addValueResolver(ValueResolvers.trueResolver());
builder.addValueResolver(ValueResolvers.collectionResolver());
builder.addValueResolver(ValueResolvers.mapperResolver());
builder.addValueResolver(ValueResolvers.mapEntryResolver());
// foo.string.raw returns a RawString which is never escaped
builder.addValueResolver(ValueResolvers.rawResolver());
builder.addValueResolver(ValueResolvers.logicalAndResolver());
builder.addValueResolver(ValueResolvers.logicalOrResolver());
builder.addValueResolver(ValueResolvers.orEmpty());
// Note that arrays are handled specifically during validation
builder.addValueResolver(ValueResolvers.arrayResolver());
// Enable/disable strict rendering
if (runtimeConfig.strictRendering) {
builder.strictRendering(true);
} else {
builder.strictRendering(false);
// If needed use a specific result mapper for the selected strategy
if (runtimeConfig.propertyNotFoundStrategy.isPresent()) {
switch (runtimeConfig.propertyNotFoundStrategy.get()) {
case THROW_EXCEPTION:
builder.addResultMapper(new PropertyNotFoundThrowException());
break;
case NOOP:
builder.addResultMapper(new PropertyNotFoundNoop());
break;
case OUTPUT_ORIGINAL:
builder.addResultMapper(new PropertyNotFoundOutputOriginal());
break;
default:
// Use the default strategy
break;
}
} else {
// Throw an expection in the development mode
if (launchMode == LaunchMode.DEVELOPMENT) {
builder.addResultMapper(new PropertyNotFoundThrowException());
}
}
}
// Escape some characters for HTML templates
builder.addResultMapper(new HtmlEscaper());
// Fallback reflection resolver
builder.addValueResolver(new ReflectionValueResolver());
// Remove standalone lines if desired
builder.removeStandaloneLines(runtimeConfig.removeStandaloneLines);
// Allow anyone to customize the builder
builderReady.fire(builder);
// Resolve @Named beans
builder.addNamespaceResolver(NamespaceResolver.builder(INJECT_NAMESPACE).resolve(ctx -> {
InstanceHandle
© 2015 - 2025 Weber Informatics LLC | Privacy Policy