io.quarkus.runtime.TemplateHtmlBuilder Maven / Gradle / Ivy
package io.quarkus.runtime;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import io.quarkus.dev.config.CurrentConfig;
import io.quarkus.runtime.util.ExceptionUtil;
public class TemplateHtmlBuilder {
private static String CSS = null;
private static final String SCRIPT_STACKTRACE_MANIPULATION = "\n";
private static final String HTML_TEMPLATE_START = "" +
"\n" +
"\n" +
"\n" +
" %1$s%2$s \n" +
" \n" +
" \n" +
SCRIPT_STACKTRACE_MANIPULATION +
"\n" +
"\n" +
"\n" +
" \n" +
" ";
private static final String HTML_TEMPLATE_END = "
\n";
private static final String RESOURCES_START = " config) {
this(null, title, subTitle, details, null, Collections.emptyList());
}
public TemplateHtmlBuilder(String baseUrl, String title, String subTitle, String details, String redirect,
List config) {
this.baseUrl = baseUrl;
loadCssFile();
result = new StringBuilder(String.format(HTML_TEMPLATE_START, escapeHtml(title),
subTitle == null || subTitle.isEmpty() ? "" : " - " + escapeHtml(subTitle), CSS));
result.append(String.format(HEADER_TEMPLATE, escapeHtml(title), escapeHtml(details)));
if (!config.isEmpty()) {
result.append(String.format(CONFIG_EDITOR_HEAD, redirect));
for (CurrentConfig i : config) {
result.append(String.format(CONFIG_EDITOR_ROW, escapeHtml(i.getPropertyName()), escapeHtml(i.getPropertyName()),
escapeHtml(i.getCurrentValue())));
}
result.append(CONFIG_EDITOR_TAIL);
}
}
public TemplateHtmlBuilder stack(final Throwable throwable) {
result.append(String.format(ERROR_STACK, escapeHtml(ExceptionUtil.generateStackTrace(throwable))));
result.append(String.format(ERROR_STACK_REVERSED, escapeHtml(ExceptionUtil.rootCauseFirstStackTrace(throwable))));
result.append(STACKTRACE_DISPLAY_DIV);
return this;
}
public TemplateHtmlBuilder resourcesStart(String title) {
result.append(String.format(RESOURCES_START, title));
return this;
}
public TemplateHtmlBuilder resourcesEnd() {
result.append(RESOURCES_END);
return this;
}
public TemplateHtmlBuilder noResourcesFound() {
result.append(String.format(RESOURCE_TEMPLATE, "No resources discovered"));
return this;
}
public TemplateHtmlBuilder resourcePath(String title) {
return resourcePath(title, true, false, null);
}
public TemplateHtmlBuilder staticResourcePath(String title) {
return staticResourcePath(title, null);
}
public TemplateHtmlBuilder staticResourcePath(String title, String description) {
return resourcePath(title, false, true, description);
}
public TemplateHtmlBuilder servletMapping(String title) {
return resourcePath(title, false, true, null);
}
private TemplateHtmlBuilder resourcePath(String title, boolean withListStart, boolean withAnchor, String description) {
String content;
if (withAnchor) {
String text = title;
if (title.startsWith("/")) {
title = title.substring(1);
}
if (!title.startsWith("http") && baseUrl != null) {
title = baseUrl + title;
}
if (title.startsWith("http")) {
int firstSlashIndex = title.indexOf("/", title.indexOf("//") + 2);
text = title.substring(firstSlashIndex);
}
content = String.format(ANCHOR_TEMPLATE_ABSOLUTE, title, escapeHtml(text));
} else {
content = escapeHtml(title);
}
if (description != null && !description.isEmpty()) {
content = String.format(DESCRIPTION_TEMPLATE, content, description);
}
result.append(String.format(RESOURCE_TEMPLATE, content));
if (withListStart) {
result.append(LIST_START);
}
return this;
}
public TemplateHtmlBuilder method(String method, String fullPath) {
fullPath = escapeHtml(fullPath);
if (method.equalsIgnoreCase("GET")) {
if (baseUrl != null) {
fullPath = "" + fullPath + "";
} else {
fullPath = "" + fullPath + "";
}
}
result.append(String.format(METHOD_START, escapeHtml(method), fullPath));
return this;
}
public TemplateHtmlBuilder consumes(String consumes) {
result.append(String.format(METHOD_IO, "Consumes", escapeHtml(consumes)));
return this;
}
public TemplateHtmlBuilder produces(String produces) {
result.append(String.format(METHOD_IO, "Produces", escapeHtml(produces)));
return this;
}
public TemplateHtmlBuilder listItem(String content) {
result.append(String.format(LIST_ITEM, escapeHtml(content)));
return this;
}
public TemplateHtmlBuilder methodEnd() {
result.append(METHOD_END);
return this;
}
public TemplateHtmlBuilder resourceStart() {
result.append(LIST_START);
return this;
}
public TemplateHtmlBuilder resourceEnd() {
result.append(LIST_END);
return this;
}
public TemplateHtmlBuilder append(String html) {
result.append(html);
return this;
}
@Override
public String toString() {
return result.append(HTML_TEMPLATE_END).toString();
}
private static String escapeHtml(final String bodyText) {
if (bodyText == null) {
return "";
}
return bodyText
.replace("&", "&")
.replace("<", "<")
.replace(">", ">");
}
public static String adjustRoot(String httpRoot, String basePath) {
//httpRoot can optionally end with a slash
//also some templates want the returned path to start with a / and some don't
//to make this work we check if the basePath starts with a / or not, and make sure we
//return the value that follows the same pattern
if (httpRoot.equals("/")) {
//leave it alone
return basePath;
}
if (basePath.startsWith("/")) {
if (!httpRoot.endsWith("/")) {
return httpRoot + basePath;
}
return httpRoot.substring(0, httpRoot.length() - 1) + basePath;
}
if (httpRoot.endsWith("/")) {
return httpRoot.substring(1) + basePath;
}
return httpRoot.substring(1) + "/" + basePath;
}
public void loadCssFile() {
if (CSS == null) {
ClassLoader classLoader = getClass().getClassLoader();
String cssFilePath = "META-INF/template-html-builder.css";
try (InputStream inputStream = classLoader.getResourceAsStream(cssFilePath)) {
if (inputStream != null) {
// Use a Scanner to read the contents of the CSS file
try (Scanner scanner = new Scanner(inputStream, "UTF-8")) {
StringBuilder stringBuilder = new StringBuilder();
while (scanner.hasNextLine()) {
stringBuilder.append(scanner.nextLine()).append("\n");
}
CSS = stringBuilder.toString();
}
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
}
%1$s
";
private static final String ANCHOR_TEMPLATE_ABSOLUTE = "%2$s";
private static final String DESCRIPTION_TEMPLATE = "%1$s — %2$s";
private static final String RESOURCE_TEMPLATE = "
";
private static final String STACKTRACE_DISPLAY_DIV = "";
private static final String ERROR_STACK = " %1$s
\n"; private static final String LIST_START = "- \n";
private static final String METHOD_START = "
- %1$s %2$s\n"
+ "
- \n";
private static final String METHOD_IO = "
- %1$s: %2$s \n"; private static final String LIST_ITEM = "
- %s \n"; private static final String METHOD_END = "
";
private static final String LIST_END = "
\n" +
"The stacktrace below is the original. " +
"See the stacktrace in reversed order (root-cause first)"
+
"
\n";
private static final String ERROR_STACK_REVERSED = " The stacktrace below is the original. " +
"See the stacktrace in reversed order (root-cause first)"
+
" %1$s
\n" +
"
%1$s
\n" +
"
\n";
private static final String CONFIG_EDITOR_HEAD = "The stacktrace below has been reversed to show the root cause first. " + "See the original stacktrace
" + "%1$s
\n" +
" The following incorrect config values were detected:
" + ""; private StringBuilder result; private String baseUrl; public TemplateHtmlBuilder(String title, String subTitle, String details) { this(null, title, subTitle, details, null, Collections.emptyList()); } public TemplateHtmlBuilder(String baseUrl, String title, String subTitle, String details) { this(baseUrl, title, subTitle, details, null, Collections.emptyList()); } public TemplateHtmlBuilder(String title, String subTitle, String details, String redirect, List© 2015 - 2025 Weber Informatics LLC | Privacy Policy