Search in sources :

Example 1 with TemplateLocator

use of io.quarkus.qute.TemplateLocator in project quarkus by quarkusio.

the class QuteProcessor method analyzeTemplates.

@BuildStep
TemplatesAnalysisBuildItem analyzeTemplates(List<TemplatePathBuildItem> templatePaths, TemplateFilePathsBuildItem filePaths, List<CheckedTemplateBuildItem> checkedTemplates, List<MessageBundleMethodBuildItem> messageBundleMethods, List<TemplateGlobalBuildItem> globals, QuteConfig config) {
    long start = System.nanoTime();
    checkDuplicatePaths(templatePaths);
    List<TemplateAnalysis> analysis = new ArrayList<>();
    // A dummy engine instance is used to parse and validate all templates during the build
    // The real engine instance is created at startup
    EngineBuilder builder = Engine.builder().addDefaultSectionHelpers();
    // Register user tags
    for (TemplatePathBuildItem path : templatePaths) {
        if (path.isTag()) {
            String tagPath = path.getPath();
            String tagName = tagPath.substring(TemplatePathBuildItem.TAGS.length(), tagPath.length());
            if (tagName.contains(".")) {
                tagName = tagName.substring(0, tagName.indexOf('.'));
            }
            builder.addSectionHelper(new UserTagSectionHelper.Factory(tagName, tagPath));
        }
    }
    builder.computeSectionHelper(name -> {
        // Create a dummy section helper factory for an uknown section that could be potentially registered at runtime
        return new SectionHelperFactory<SectionHelper>() {

            @Override
            public SectionHelper initialize(SectionInitContext context) {
                return new SectionHelper() {

                    @Override
                    public CompletionStage<ResultNode> resolve(SectionResolutionContext context) {
                        return ResultNode.NOOP;
                    }
                };
            }
        };
    });
    builder.addLocator(new TemplateLocator() {

        @Override
        public Optional<TemplateLocation> locate(String id) {
            TemplatePathBuildItem found = templatePaths.stream().filter(p -> p.getPath().equals(id)).findAny().orElse(null);
            if (found != null) {
                return Optional.of(new TemplateLocation() {

                    @Override
                    public Reader read() {
                        return new StringReader(found.getContent());
                    }

                    @Override
                    public Optional<Variant> getVariant() {
                        return Optional.empty();
                    }
                });
            }
            return Optional.empty();
        }
    });
    Map<String, MessageBundleMethodBuildItem> messageBundleMethodsMap;
    if (messageBundleMethods.isEmpty()) {
        messageBundleMethodsMap = Collections.emptyMap();
    } else {
        messageBundleMethodsMap = new HashMap<>();
        for (MessageBundleMethodBuildItem messageBundleMethod : messageBundleMethods) {
            messageBundleMethodsMap.put(messageBundleMethod.getTemplateId(), messageBundleMethod);
        }
    }
    builder.addParserHook(new ParserHook() {

        @Override
        public void beforeParsing(ParserHelper parserHelper) {
            // The template id may be the full path, e.g. "items.html" or a path without the suffic, e.g. "items"
            String templateId = parserHelper.getTemplateId();
            if (filePaths.contains(templateId)) {
                // It's a file-based template
                // We need to find out whether the parsed template represents a checked template
                String path = templateId;
                for (String suffix : config.suffixes) {
                    if (path.endsWith(suffix)) {
                        // Remove the suffix
                        path = path.substring(0, path.length() - (suffix.length() + 1));
                        break;
                    }
                }
                // Set the bindings for globals first so that type-safe templates can override them
                for (TemplateGlobalBuildItem global : globals) {
                    parserHelper.addParameter(global.getName(), JandexUtil.getBoxedTypeName(global.getVariableType()).toString());
                }
                for (CheckedTemplateBuildItem checkedTemplate : checkedTemplates) {
                    if (checkedTemplate.templateId.equals(path)) {
                        for (Entry<String, String> entry : checkedTemplate.bindings.entrySet()) {
                            parserHelper.addParameter(entry.getKey(), entry.getValue());
                        }
                        break;
                    }
                }
            }
            // If needed add params to message bundle templates
            MessageBundleMethodBuildItem messageBundleMethod = messageBundleMethodsMap.get(templateId);
            if (messageBundleMethod != null) {
                MethodInfo method = messageBundleMethod.getMethod();
                for (ListIterator<Type> it = method.parameters().listIterator(); it.hasNext(); ) {
                    Type paramType = it.next();
                    String name = MessageBundleProcessor.getParameterName(method, it.previousIndex());
                    parserHelper.addParameter(name, JandexUtil.getBoxedTypeName(paramType));
                }
            }
        }
    }).build();
    Engine dummyEngine = builder.build();
    for (TemplatePathBuildItem path : templatePaths) {
        Template template = dummyEngine.getTemplate(path.getPath());
        if (template != null) {
            analysis.add(new TemplateAnalysis(null, template.getGeneratedId(), template.getExpressions(), path.getPath()));
        }
    }
    // Message bundle templates
    for (MessageBundleMethodBuildItem messageBundleMethod : messageBundleMethods) {
        Template template = dummyEngine.parse(messageBundleMethod.getTemplate(), null, messageBundleMethod.getTemplateId());
        analysis.add(new TemplateAnalysis(messageBundleMethod.getTemplateId(), template.getGeneratedId(), template.getExpressions(), messageBundleMethod.getMethod().declaringClass().name() + "#" + messageBundleMethod.getMethod().name() + "()"));
    }
    LOGGER.debugf("Finished analysis of %s templates in %s ms", analysis.size(), TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
    return new TemplatesAnalysisBuildItem(analysis);
}
Also used : DotNames(io.quarkus.arc.processor.DotNames) GeneratedClassGizmoAdaptor(io.quarkus.deployment.GeneratedClassGizmoAdaptor) Arrays(java.util.Arrays) JandexUtil(io.quarkus.deployment.util.JandexUtil) Primitive(org.jboss.jandex.PrimitiveType.Primitive) ClassOutput(io.quarkus.gizmo.ClassOutput) FieldInfo(org.jboss.jandex.FieldInfo) TemplateData(io.quarkus.qute.TemplateData) AdditionalBeanBuildItem(io.quarkus.arc.deployment.AdditionalBeanBuildItem) BeanDiscoveryFinishedBuildItem(io.quarkus.arc.deployment.BeanDiscoveryFinishedBuildItem) TemplateLocator(io.quarkus.qute.TemplateLocator) ExtensionMethodGenerator(io.quarkus.qute.generator.ExtensionMethodGenerator) Map(java.util.Map) ParameterizedType(org.jboss.jandex.ParameterizedType) Path(java.nio.file.Path) WhenSectionHelper(io.quarkus.qute.WhenSectionHelper) AnnotationValue(org.jboss.jandex.AnnotationValue) TemplateInstance(io.quarkus.qute.TemplateInstance) STATIC_INIT(io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT) ErrorCode(io.quarkus.qute.ErrorCode) Set(java.util.Set) Annotations(io.quarkus.arc.processor.Annotations) Reader(java.io.Reader) InjectionPointInfo(io.quarkus.arc.processor.InjectionPointInfo) UncheckedIOException(java.io.UncheckedIOException) Feature(io.quarkus.deployment.Feature) EngineBuilder(io.quarkus.qute.EngineBuilder) CollectionTemplateExtensions(io.quarkus.qute.runtime.extensions.CollectionTemplateExtensions) CompletionStage(java.util.concurrent.CompletionStage) Stream(java.util.stream.Stream) Template(io.quarkus.qute.Template) NumberTemplateExtensions(io.quarkus.qute.runtime.extensions.NumberTemplateExtensions) AnnotationInstance(org.jboss.jandex.AnnotationInstance) Info(io.quarkus.qute.deployment.TypeInfos.Info) Predicate.not(java.util.function.Predicate.not) SetSectionHelper(io.quarkus.qute.SetSectionHelper) Record(io.quarkus.deployment.annotations.Record) VirtualMethodPart(io.quarkus.qute.Expression.VirtualMethodPart) DotName(org.jboss.jandex.DotName) CDI_NAMESPACE(io.quarkus.qute.runtime.EngineProducer.CDI_NAMESPACE) ArrayList(java.util.ArrayList) ValidationPhaseBuildItem(io.quarkus.arc.deployment.ValidationPhaseBuildItem) Dependency(io.quarkus.maven.dependency.Dependency) BeanArchiveIndexBuildItem(io.quarkus.arc.deployment.BeanArchiveIndexBuildItem) EngineProducer(io.quarkus.qute.runtime.EngineProducer) ApplicationArchivesBuildItem(io.quarkus.deployment.builditem.ApplicationArchivesBuildItem) Files(java.nio.file.Files) PrimitiveType(org.jboss.jandex.PrimitiveType) IOException(java.io.IOException) File(java.io.File) StringReader(java.io.StringReader) GeneratedClassBuildItem(io.quarkus.deployment.builditem.GeneratedClassBuildItem) BytecodeTransformerBuildItem(io.quarkus.deployment.builditem.BytecodeTransformerBuildItem) LoopSectionHelper(io.quarkus.qute.LoopSectionHelper) PanacheEntityClassesBuildItem(io.quarkus.panache.common.deployment.PanacheEntityClassesBuildItem) StringTemplateExtensions(io.quarkus.qute.runtime.extensions.StringTemplateExtensions) TypeVariable(org.jboss.jandex.TypeVariable) SectionHelperFactory(io.quarkus.qute.SectionHelperFactory) QuteRecorder(io.quarkus.qute.runtime.QuteRecorder) ContentTypes(io.quarkus.qute.runtime.ContentTypes) ListIterator(java.util.ListIterator) SectionHelper(io.quarkus.qute.SectionHelper) ParserHelper(io.quarkus.qute.ParserHelper) ClassInfo(org.jboss.jandex.ClassInfo) ValidationErrorBuildItem(io.quarkus.arc.deployment.ValidationPhaseBuildItem.ValidationErrorBuildItem) BuildProducer(io.quarkus.deployment.annotations.BuildProducer) Expression(io.quarkus.qute.Expression) MethodInfo(org.jboss.jandex.MethodInfo) Collectors.toMap(java.util.stream.Collectors.toMap) FeatureBuildItem(io.quarkus.deployment.builditem.FeatureBuildItem) TemplateExtension(io.quarkus.qute.TemplateExtension) TemplateAnalysis(io.quarkus.qute.deployment.TemplatesAnalysisBuildItem.TemplateAnalysis) Param(io.quarkus.qute.generator.ExtensionMethodGenerator.Param) TemplateGlobalGenerator(io.quarkus.qute.generator.TemplateGlobalGenerator) AnnotationTarget(org.jboss.jandex.AnnotationTarget) INJECT_NAMESPACE(io.quarkus.qute.runtime.EngineProducer.INJECT_NAMESPACE) TemplateGlobal(io.quarkus.qute.TemplateGlobal) ZipUtils(io.quarkus.fs.util.ZipUtils) Predicate(java.util.function.Predicate) QuteConfig(io.quarkus.qute.runtime.QuteConfig) ConfigTemplateExtensions(io.quarkus.qute.runtime.extensions.ConfigTemplateExtensions) NativeImageResourceBuildItem(io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem) FileSystem(java.nio.file.FileSystem) Collectors(java.util.stream.Collectors) QuteContext(io.quarkus.qute.runtime.QuteRecorder.QuteContext) Objects(java.util.Objects) QualifierRegistrarBuildItem(io.quarkus.arc.deployment.QualifierRegistrarBuildItem) ResolveCreator(io.quarkus.qute.generator.ExtensionMethodGenerator.NamespaceResolverCreator.ResolveCreator) TemplateProducer(io.quarkus.qute.runtime.TemplateProducer) List(java.util.List) NamespaceResolverCreator(io.quarkus.qute.generator.ExtensionMethodGenerator.NamespaceResolverCreator) Modifier(java.lang.reflect.Modifier) Entry(java.util.Map.Entry) ResolvedDependency(io.quarkus.maven.dependency.ResolvedDependency) Optional(java.util.Optional) UserTagSectionHelper(io.quarkus.qute.UserTagSectionHelper) Pattern(java.util.regex.Pattern) ResultNode(io.quarkus.qute.ResultNode) SyntheticBeanBuildItem(io.quarkus.arc.deployment.SyntheticBeanBuildItem) ReflectiveClassBuildItem(io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem) CheckedTemplate(io.quarkus.qute.CheckedTemplate) MapTemplateExtensions(io.quarkus.qute.runtime.extensions.MapTemplateExtensions) HotDeploymentWatchedFileBuildItem(io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem) Logger(org.jboss.logging.Logger) Type(org.jboss.jandex.Type) HashMap(java.util.HashMap) CurateOutcomeBuildItem(io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem) Function(java.util.function.Function) HashSet(java.util.HashSet) BuildStep(io.quarkus.deployment.annotations.BuildStep) Charset(java.nio.charset.Charset) Variant(io.quarkus.qute.Variant) Kind(org.jboss.jandex.AnnotationTarget.Kind) TypeCheck(io.quarkus.qute.deployment.TypeCheckExcludeBuildItem.TypeCheck) ServiceStartBuildItem(io.quarkus.deployment.builditem.ServiceStartBuildItem) IndexView(org.jboss.jandex.IndexView) Iterator(java.util.Iterator) TimeTemplateExtensions(io.quarkus.qute.runtime.extensions.TimeTemplateExtensions) ValueResolverGenerator(io.quarkus.qute.generator.ValueResolverGenerator) TimeUnit(java.util.concurrent.TimeUnit) QualifierRegistrar(io.quarkus.arc.processor.QualifierRegistrar) ApplicationArchive(io.quarkus.deployment.ApplicationArchive) TemplateException(io.quarkus.qute.TemplateException) ParserHook(io.quarkus.qute.ParserHook) Comparator(java.util.Comparator) Collections(java.util.Collections) BeanInfo(io.quarkus.arc.processor.BeanInfo) Engine(io.quarkus.qute.Engine) ArrayList(java.util.ArrayList) TemplateAnalysis(io.quarkus.qute.deployment.TemplatesAnalysisBuildItem.TemplateAnalysis) Template(io.quarkus.qute.Template) CheckedTemplate(io.quarkus.qute.CheckedTemplate) TemplateLocator(io.quarkus.qute.TemplateLocator) ParserHook(io.quarkus.qute.ParserHook) ParserHelper(io.quarkus.qute.ParserHelper) StringReader(java.io.StringReader) WhenSectionHelper(io.quarkus.qute.WhenSectionHelper) SetSectionHelper(io.quarkus.qute.SetSectionHelper) LoopSectionHelper(io.quarkus.qute.LoopSectionHelper) SectionHelper(io.quarkus.qute.SectionHelper) UserTagSectionHelper(io.quarkus.qute.UserTagSectionHelper) EngineBuilder(io.quarkus.qute.EngineBuilder) Engine(io.quarkus.qute.Engine) Optional(java.util.Optional) ResultNode(io.quarkus.qute.ResultNode) Variant(io.quarkus.qute.Variant) ParameterizedType(org.jboss.jandex.ParameterizedType) PrimitiveType(org.jboss.jandex.PrimitiveType) Type(org.jboss.jandex.Type) SectionHelperFactory(io.quarkus.qute.SectionHelperFactory) MethodInfo(org.jboss.jandex.MethodInfo) UserTagSectionHelper(io.quarkus.qute.UserTagSectionHelper) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Aggregations

AdditionalBeanBuildItem (io.quarkus.arc.deployment.AdditionalBeanBuildItem)1 BeanArchiveIndexBuildItem (io.quarkus.arc.deployment.BeanArchiveIndexBuildItem)1 BeanDiscoveryFinishedBuildItem (io.quarkus.arc.deployment.BeanDiscoveryFinishedBuildItem)1 QualifierRegistrarBuildItem (io.quarkus.arc.deployment.QualifierRegistrarBuildItem)1 SyntheticBeanBuildItem (io.quarkus.arc.deployment.SyntheticBeanBuildItem)1 ValidationPhaseBuildItem (io.quarkus.arc.deployment.ValidationPhaseBuildItem)1 ValidationErrorBuildItem (io.quarkus.arc.deployment.ValidationPhaseBuildItem.ValidationErrorBuildItem)1 Annotations (io.quarkus.arc.processor.Annotations)1 BeanInfo (io.quarkus.arc.processor.BeanInfo)1 DotNames (io.quarkus.arc.processor.DotNames)1 InjectionPointInfo (io.quarkus.arc.processor.InjectionPointInfo)1 QualifierRegistrar (io.quarkus.arc.processor.QualifierRegistrar)1 ApplicationArchive (io.quarkus.deployment.ApplicationArchive)1 Feature (io.quarkus.deployment.Feature)1 GeneratedClassGizmoAdaptor (io.quarkus.deployment.GeneratedClassGizmoAdaptor)1 BuildProducer (io.quarkus.deployment.annotations.BuildProducer)1 BuildStep (io.quarkus.deployment.annotations.BuildStep)1 STATIC_INIT (io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT)1 Record (io.quarkus.deployment.annotations.Record)1 ApplicationArchivesBuildItem (io.quarkus.deployment.builditem.ApplicationArchivesBuildItem)1