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);
}
Aggregations