You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2026/10/08 11:50:09 UTC
(juneau) branch juneau-release-manager updated: Serve Excel/PDF export libraries (JSZip, pdfmake) from a local WebJars pack instead of cdnjs
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch juneau-release-manager
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/juneau-release-manager by this push:
new e78de19746 Serve Excel/PDF export libraries (JSZip, pdfmake) from a local WebJars pack instead of cdnjs
e78de19746 is described below
commit e78de197461f9e893e330372cfab52755bdd17cb
Author: James Bognar <ja...@apache.org>
AuthorDate: Thu Oct 8 07:50:04 2026 -0400
Serve Excel/PDF export libraries (JSZip, pdfmake) from a local WebJars pack instead of cdnjs
---
pom.xml | 14 ++++++++++++++
.../java/org/apache/juneau/releng/rest/ReleaseRest.java | 16 ++++++++++++++++
src/main/resources/templates/releases.ftlh | 4 ++--
.../org/apache/juneau/releng/rest/ReleaseRestTest.java | 17 ++++++++++++++---
4 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/pom.xml b/pom.xml
index dcb0e864e5..d8aa7000c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,20 @@
<artifactId>juneau-secret-macos-keychain</artifactId>
<version>${juneau.version}</version>
</dependency>
+ <!-- Excel/PDF export libraries for the "datatables-export" toolkit pack. Their npm transitive deps are not
+ needed (both ship a self-contained browser bundle), so exclude them. -->
+ <dependency>
+ <groupId>org.webjars.npm</groupId>
+ <artifactId>jszip</artifactId>
+ <version>3.10.1</version>
+ <exclusions><exclusion><groupId>*</groupId><artifactId>*</artifactId></exclusion></exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.npm</groupId>
+ <artifactId>pdfmake</artifactId>
+ <version>0.2.7</version>
+ <exclusions><exclusion><groupId>*</groupId><artifactId>*</artifactId></exclusion></exclusions>
+ </dependency>
<!-- FreeMarker engine (provided-scope in the bridge module; supply it here). -->
<dependency>
<groupId>org.freemarker</groupId>
diff --git a/src/main/java/org/apache/juneau/releng/rest/ReleaseRest.java b/src/main/java/org/apache/juneau/releng/rest/ReleaseRest.java
index d32bb97cd2..80e4366d7d 100644
--- a/src/main/java/org/apache/juneau/releng/rest/ReleaseRest.java
+++ b/src/main/java/org/apache/juneau/releng/rest/ReleaseRest.java
@@ -43,6 +43,9 @@ import org.apache.juneau.rest.server.view.View;
import org.apache.juneau.rest.server.view.freemarker.FreemarkerMixin;
import org.apache.juneau.rest.server.view.freemarker.FreemarkerViewRenderer;
import org.apache.juneau.rest.server.view.freemarker.console.ConsoleFreemarkerMixin;
+import org.apache.juneau.rest.server.view.freemarker.console.ToolkitPack;
+import org.apache.juneau.rest.server.view.freemarker.console.ToolkitPackRegistry;
+import org.apache.juneau.rest.server.staticfile.WebJarResolver;
import org.apache.juneau.rest.server.staticfile.WebJarsMixin;
import org.apache.juneau.rest.server.views.ViewsMixin;
@@ -98,6 +101,10 @@ public class ReleaseRest extends BasicRestResource {
/**
* The Freemarker mixin used to render this resource's templates.
+ *
+ * <p>
+ * Registers the app-local {@code datatables-export} pack (JSZip, pdfmake and its fonts, from WebJars) that the
+ * releases card requires for Excel and PDF export; it loads after the built-in Buttons pack.
*/
// Return type stays FreemarkerMixin - FreemarkerViewRenderer does an exact-type bean lookup (see
// ConsoleFreemarkerMixin's class Javadoc).
@@ -105,6 +112,15 @@ public class ReleaseRest extends BasicRestResource {
public FreemarkerMixin freemarker() {
var builder = ConsoleFreemarkerMixin.create();
builder.adopterAssets(getClass().getClassLoader(), "static");
+ builder.registerToolkitPack(ToolkitPack.create("datatables-export")
+ .js(
+ WebJarResolver.asset("org.webjars.npm", "jszip", "jszip/{version}/dist/jszip.min.js"),
+ WebJarResolver.asset("org.webjars.npm", "pdfmake", "pdfmake/{version}/build/pdfmake.min.js"),
+ WebJarResolver.asset("org.webjars.npm", "pdfmake", "pdfmake/{version}/build/vfs_fonts.js"))
+ .dependsOn(ToolkitPackRegistry.PACK_DATATABLES_BUTTONS)
+ .kind(ToolkitPack.Kind.VENDOR)
+ .resolver(ToolkitPackRegistry.WEBJAR_RESOLVER)
+ .build());
builder.basePath("/templates/").templateSuffix(".ftlh");
return builder.build();
}
diff --git a/src/main/resources/templates/releases.ftlh b/src/main/resources/templates/releases.ftlh
index 5c4c259858..6ae278c130 100644
--- a/src/main/resources/templates/releases.ftlh
+++ b/src/main/resources/templates/releases.ftlh
@@ -16,12 +16,12 @@
-->
<@page tab="releases" toolkit="views"
- init="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js,https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js,https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.min.js,/js/releases-detail.js">
+ init="/js/releases-detail.js">
<div class="jc-page-header">
<h1>All Releases</h1>
<p class="jc-page-sub">Every Apache Juneau release, from the current vote candidate back through GA history.</p>
</div>
- <@card type="datatables" id="releases" requires="datatables-buttons">
+ <@card type="datatables" id="releases" requires="datatables-export">
{
rowType: 'Release',
dataMode: 'server',
diff --git a/src/test/java/org/apache/juneau/releng/rest/ReleaseRestTest.java b/src/test/java/org/apache/juneau/releng/rest/ReleaseRestTest.java
index a4836e4f23..7c20bf472b 100644
--- a/src/test/java/org/apache/juneau/releng/rest/ReleaseRestTest.java
+++ b/src/test/java/org/apache/juneau/releng/rest/ReleaseRestTest.java
@@ -177,9 +177,20 @@ class ReleaseRestTest {
assertTrue(body.contains("/webjars/"), "Pack assets should be served as WebJars: " + body);
assertFalse(body.contains("cdn.datatables.net"), "Buttons must not come from the CDN: " + body);
assertFalse(body.contains("/datatables/jquery.min.js"), "Bundled jQuery should be gone: " + body);
- assertTrue(body.contains("jszip.min.js"), "Missing jszip.min.js script include: " + body);
- assertTrue(body.contains("pdfmake.min.js"), "Missing pdfmake.min.js script include: " + body);
- assertTrue(body.contains("vfs_fonts.min.js"), "Missing vfs_fonts.min.js script include: " + body);
+ var jszipIdx = body.indexOf("jszip.min.js");
+ var pdfmakeIdx = body.indexOf("pdfmake.min.js");
+ var vfsIdx = body.indexOf("vfs_fonts.js");
+ assertTrue(jszipIdx >= 0, "Missing jszip.min.js script include: " + body);
+ assertTrue(pdfmakeIdx >= 0, "Missing pdfmake.min.js script include: " + body);
+ assertTrue(vfsIdx >= 0, "Missing vfs_fonts.js script include: " + body);
+ assertTrue(buttonsHtml5Idx < jszipIdx, "Buttons must precede JSZip: " + body);
+ assertTrue(jszipIdx < pdfmakeIdx && pdfmakeIdx < vfsIdx, "Export libraries out of order: " + body);
+ assertEquals(jszipIdx, body.lastIndexOf("jszip.min.js"), "JSZip loaded more than once: " + body);
+ assertEquals(pdfmakeIdx, body.lastIndexOf("pdfmake.min.js"), "pdfmake loaded more than once: " + body);
+ assertEquals(vfsIdx, body.lastIndexOf("vfs_fonts.js"), "vfs_fonts loaded more than once: " + body);
+ assertTrue(body.contains("/webjars/jszip/3.10.1/dist/jszip.min.js"), "JSZip should be served as a WebJar: " + body);
+ assertTrue(body.contains("/webjars/pdfmake/0.2.7/build/pdfmake.min.js"), "pdfmake should be served as a WebJar: " + body);
+ assertFalse(body.contains("cdnjs"), "No cdnjs URL should remain: " + body);
}
}
}