Skip to content

Commit

Permalink
index.html (welcome page) now dynamic
Browse files Browse the repository at this point in the history
Signed-off-by: Phillip Kruger <phillip.kruger@gmail.com>
  • Loading branch information
phillip-kruger committed Dec 12, 2023
1 parent 419ed1a commit e919139
Show file tree
Hide file tree
Showing 17 changed files with 560 additions and 386 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

import io.mvnpm.importmap.Aggregator;
import io.mvnpm.importmap.Location;
import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.builder.Version;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
Expand All @@ -67,6 +68,7 @@
import io.quarkus.devui.spi.page.MenuPageBuildItem;
import io.quarkus.devui.spi.page.Page;
import io.quarkus.devui.spi.page.PageBuilder;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.vertx.core.json.jackson.DatabindCodec;

Expand Down Expand Up @@ -362,6 +364,7 @@ void loadAllBuildTimeTemplates(BuildProducer<StaticContentBuildItem> buildTimeCo
@BuildStep(onlyIf = IsDevelopment.class)
void createBuildTimeData(BuildProducer<BuildTimeConstBuildItem> buildTimeConstProducer,
BuildProducer<ThemeVarsBuildItem> themeVarsProducer,
CurateOutcomeBuildItem curateOutcomeBuildItem,
List<InternalPageBuildItem> internalPages,
ExtensionsBuildItem extensionsBuildItem,
NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem,
Expand All @@ -373,7 +376,7 @@ void createBuildTimeData(BuildProducer<BuildTimeConstBuildItem> buildTimeConstPr
addThemeBuildTimeData(internalBuildTimeData, themeVarsProducer);
addMenuSectionBuildTimeData(internalBuildTimeData, internalPages, extensionsBuildItem);
addFooterTabBuildTimeData(internalBuildTimeData, extensionsBuildItem);
addVersionInfoBuildTimeData(internalBuildTimeData, nonApplicationRootPathBuildItem);
addVersionInfoBuildTimeData(internalBuildTimeData, curateOutcomeBuildItem, nonApplicationRootPathBuildItem);
addIdeBuildTimeData(internalBuildTimeData, effectiveIdeBuildItem, launchModeBuildItem);
buildTimeConstProducer.produce(internalBuildTimeData);
}
Expand Down Expand Up @@ -471,10 +474,20 @@ private void addFooterTabBuildTimeData(BuildTimeConstBuildItem internalBuildTime
}

private void addVersionInfoBuildTimeData(BuildTimeConstBuildItem internalBuildTimeData,
CurateOutcomeBuildItem curateOutcomeBuildItem,
NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) {

Map<String, String> applicationInfo = new HashMap<>();

// Add GAV
ApplicationModel applicationModel = curateOutcomeBuildItem.getApplicationModel();
ResolvedDependency appArtifact = applicationModel.getAppArtifact();
String groupId = appArtifact.getGroupId();
applicationInfo.put("groupId", groupId);
String artifactId = appArtifact.getArtifactId();
applicationInfo.put("artifactId", artifactId);
// Add version info
String contextRoot = nonApplicationRootPathBuildItem.getNonApplicationRootPath() + DEV_UI + SLASH;
Map<String, String> applicationInfo = new HashMap<>();
applicationInfo.put("contextRoot", contextRoot);
applicationInfo.put("quarkusVersion", Version.getVersion());
applicationInfo.put("applicationName", config.getOptionalValue("quarkus.application.name", String.class).orElse(""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
Expand Down Expand Up @@ -66,6 +67,7 @@
import io.quarkus.qute.Qute;
import io.quarkus.runtime.util.ClassPathUtils;
import io.quarkus.vertx.http.deployment.FilterBuildItem;
import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.deployment.webjar.WebJarBuildItem;
Expand Down Expand Up @@ -131,6 +133,7 @@ void registerDevUiHandlers(
DevUIRecorder recorder,
LaunchModeBuildItem launchModeBuildItem,
NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem,
HttpRootPathBuildItem httpRootPathBuildItem,
ShutdownContextBuildItem shutdownContext) throws IOException {

if (launchModeBuildItem.isNotLocalDevModeType()) {
Expand Down Expand Up @@ -230,6 +233,24 @@ void registerDevUiHandlers(
.route("dev")
.handler(recorder.redirect(contextRoot))
.build());

// Redirect naked to welcome if there is no index.html
if (!hasOwnIndexHtml()) {
routeProducer.produce(httpRootPathBuildItem.routeBuilder()
.orderedRoute("/", Integer.MIN_VALUE)
.handler(recorder.redirect(contextRoot, "welcome"))
.build());
}
}

private boolean hasOwnIndexHtml() {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
Enumeration<URL> jarsWithIndexHtml = tccl.getResources("META-INF/resources/index.html");
return jarsWithIndexHtml.hasMoreElements();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}

/**
Expand Down Expand Up @@ -466,7 +487,7 @@ void getAllExtensions(List<CardPageBuildItem> cardPageBuildItems,
}

if (metaData.containsKey(CODESTART)) {
Map<String, Object> codestartMap = (Map<String, Object>) metaData.get(metaData);
Map<String, Object> codestartMap = (Map<String, Object>) metaData.get(CODESTART);
if (codestartMap != null) {
Codestart codestart = new Codestart();
codestart.setName((String) codestartMap.getOrDefault(NAME, null));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.quarkus.devui.deployment.welcome;

import java.net.URL;

public class SelectedExtension {
public String name;
public String description;
public URL guide;

public SelectedExtension() {
}

public SelectedExtension(String name, String description, URL guide) {
this.name = name;
this.guide = guide;
this.description = description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.quarkus.devui.deployment.welcome;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class WelcomeData {

public String configFile;
public String resourcesDir;
public String sourceDir;
public List<SelectedExtension> selectedExtensions = new ArrayList<>();

public void addSelectedExtension(String name, String description, URL guide) {
selectedExtensions.add(new SelectedExtension(name, description, guide));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package io.quarkus.devui.deployment.welcome;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import io.quarkus.bootstrap.workspace.SourceDir;
import io.quarkus.bootstrap.workspace.WorkspaceModule;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.devui.deployment.ExtensionsBuildItem;
import io.quarkus.devui.deployment.InternalPageBuildItem;
import io.quarkus.devui.deployment.extension.Extension;
import io.quarkus.devui.spi.page.Page;

/**
* This creates Welcome page
*/
public class WelcomeProcessor {

@BuildStep(onlyIf = IsDevelopment.class)
InternalPageBuildItem createWelcomePages(CurateOutcomeBuildItem curateOutcomeBuildItem,
ExtensionsBuildItem extensionsBuildItem) {

InternalPageBuildItem welcomePageBuildItem = new InternalPageBuildItem("Welcome", -1);

welcomePageBuildItem.addBuildTimeData("welcomeData", createWelcomeData(curateOutcomeBuildItem, extensionsBuildItem));

welcomePageBuildItem.addPage(Page.webComponentPageBuilder()
.namespace("devui-welcome")
.title("Welcome")
.icon("font-awesome-brands:redhat")
.componentLink("qwc-welcome.js")
.excludeFromMenu());

return welcomePageBuildItem;
}

private WelcomeData createWelcomeData(CurateOutcomeBuildItem curateOutcomeBuildItem,
ExtensionsBuildItem extensionsBuildItem) {

WorkspaceModule workspaceModule = curateOutcomeBuildItem.getApplicationModel().getApplicationModule();

WelcomeData welcomeData = new WelcomeData();
welcomeData.configFile = getConfigFile(workspaceModule);
welcomeData.sourceDir = getSourceDir(workspaceModule);
welcomeData.resourcesDir = getResourcesDir(workspaceModule);

List<Extension> selectedExtensions = getSelectedExtensions(workspaceModule, extensionsBuildItem);
for (Extension extension : selectedExtensions) {
welcomeData.addSelectedExtension(extension.getName(), extension.getDescription(), extension.getGuide());
if (extension.getCodestart() != null) {
// TODO: Get the codestarts ?
//extension.getCodestart().getArtifact()
//extension.getCodestart().getName()
//extension.getCodestart().getLanguages()
}
}

return welcomeData;
}

private String getConfigFile(WorkspaceModule workspaceModule) {
File moduleDir = workspaceModule.getModuleDir();
if (moduleDir != null) {
String root = moduleDir.toPath().toString();
Collection<SourceDir> resourcesDirs = workspaceModule.getMainSources().getResourceDirs();
if (resourcesDirs != null && !resourcesDirs.isEmpty()) {
Path resourceDirs = resourcesDirs.iterator().next().getDir();
Path propertiesFile = resourceDirs.resolve("application.properties");
if (Files.exists(propertiesFile)) {
return propertiesFile.toString().substring((int) root.length() + 1);
}
Path propertiesYaml = resourceDirs.resolve("application.yaml");
if (Files.exists(propertiesYaml)) {
return propertiesYaml.toString().substring((int) root.length() + 1);
}
}
}
return null;
}

private String getSourceDir(WorkspaceModule workspaceModule) {
File moduleDir = workspaceModule.getModuleDir();
if (moduleDir != null) {
String root = moduleDir.toPath().toString();
Collection<SourceDir> sourceDirs = workspaceModule.getMainSources().getSourceDirs();
if (sourceDirs != null && !sourceDirs.isEmpty()) {
String sourceDir = sourceDirs.iterator().next().getDir().toString();
return sourceDir.substring((int) root.length() + 1);
}
}
return null;
}

private String getResourcesDir(WorkspaceModule workspaceModule) {
File moduleDir = workspaceModule.getModuleDir();
if (moduleDir != null) {
String root = moduleDir.toPath().toString();
Collection<SourceDir> resourcesDirs = workspaceModule.getMainSources().getResourceDirs();
if (resourcesDirs != null && !resourcesDirs.isEmpty()) {
String resourceDirs = resourcesDirs.iterator().next().getDir().toString();
return resourceDirs.substring((int) root.length() + 1);
}
}
return null;
}

private List<Extension> getSelectedExtensions(WorkspaceModule workspaceModule,
ExtensionsBuildItem extensionsBuildItem) {

Map<String, Extension> extensionMap = getExtensionMap(extensionsBuildItem);

List<Extension> selectedDependency = workspaceModule.getDirectDependencies()
.stream()
.filter((dependency) -> {
return dependency.isJar()
&& (dependency.getScope() == null || !dependency.getScope().equals("test"))
&& !dependency.getGroupId().startsWith("org.mvnpm")
&& !dependency.getGroupId().startsWith("org.webjars");
}).map((t) -> {
String key = t.getGroupId() + ":" + t.getArtifactId();
return extensionMap.get(key);
}).collect(Collectors.toList());

return selectedDependency;
}

private Map<String, Extension> getExtensionMap(ExtensionsBuildItem extensionsBuildItem) {
Map<String, Extension> all = new HashMap<>();
extensionsBuildItem.getActiveExtensions().forEach((t) -> {
String gav[] = t.getArtifact().split(":");
all.put(gav[0] + ":" + gav[1], t);
});
extensionsBuildItem.getInactiveExtensions().forEach((t) -> {
String gav[] = t.getArtifact().split(":");
all.put(gav[0] + ":" + gav[1], t);
});
return all;
}

}
Loading

0 comments on commit e919139

Please sign in to comment.