You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2026/04/21 06:13:13 UTC

(groovy) 02/34: GROOVY-11682 — module attribute on

This is an automated email from the ASF dual-hosted git repository.

paulk-asert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 56415b246b905a551f2e8bec504e5231550cee07
Author: Paul King <pa...@asert.com.au>
AuthorDate: Mon Apr 20 07:25:57 2026 +1000

    GROOVY-11682 — module attribute on <link>
---
 .../groovy/tools/groovydoc/LinkArgument.java       | 39 ++++++++++++++++++----
 .../groovy/tools/groovydoc/GroovyDocToolTest.java  | 37 ++++++++++++++++++++
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/LinkArgument.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/LinkArgument.java
index 3c62bc3b16..42f8f0b5ec 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/LinkArgument.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/LinkArgument.java
@@ -19,12 +19,15 @@
 package org.codehaus.groovy.tools.groovydoc;
 
 /**
- * Represents a link pair (href, packages).
- * The packages are comma separated.
+ * Represents a link pair (href, packages) with optional JPMS module.
+ * The packages are comma separated. When a module is specified, the
+ * module name is inserted between the base href and the package path,
+ * matching the JPMS-era Javadoc layout (e.g. {@code .../api/java.base/java/lang/Object.html}).
  */
 public class LinkArgument {
     private String href = "";
     private String packages = "";
+    private String module = "";
 
     /**
      * Get the packages attribute.
@@ -45,12 +48,16 @@ public class LinkArgument {
     }
 
     /**
-     * Get the href attribute.
+     * Get the href attribute, with the module name appended when set.
+     * For pre-JPMS external docs, returns the raw href; for JPMS-aware
+     * external docs (e.g. JDK 9+), returns {@code href + module + "/"}.
      *
-     * @return the href attribute.
+     * @return the effective base URL for this link
      */
     public String getHref() {
-        return href;
+        if (module == null || module.isEmpty()) return href;
+        String base = href.endsWith("/") ? href : href + "/";
+        return base + module + "/";
     }
 
     /**
@@ -62,4 +69,24 @@ public class LinkArgument {
         href = hr;
     }
 
-}
\ No newline at end of file
+    /**
+     * Get the module attribute.
+     *
+     * @return the module attribute, or an empty string if not set
+     */
+    public String getModule() {
+        return module;
+    }
+
+    /**
+     * Set the module attribute. When set, the module name is inserted
+     * between the base href and the package path, yielding JPMS-era
+     * Javadoc URLs such as {@code .../api/java.base/java/lang/Object.html}.
+     *
+     * @param module the JPMS module name (e.g. {@code java.base})
+     */
+    public void setModule(String module) {
+        this.module = module;
+    }
+
+}
diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java
index 6e9b3b0ba2..64f8db2cfe 100644
--- a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java
+++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java
@@ -94,6 +94,43 @@ public class GroovyDocToolTest extends GroovyTestCase {
         );
     }
 
+    // GROOVY-11682
+    public void testLinkArgumentModuleComposesJpmsStyleUrl() {
+        LinkArgument link = new LinkArgument();
+        link.setHref("https://docs.oracle.com/en/java/javase/17/docs/api/");
+        assertEquals("https://docs.oracle.com/en/java/javase/17/docs/api/", link.getHref());
+
+        link.setModule("java.base");
+        assertEquals("https://docs.oracle.com/en/java/javase/17/docs/api/java.base/", link.getHref());
+
+        LinkArgument noSlash = new LinkArgument();
+        noSlash.setHref("https://example.org/api");
+        noSlash.setModule("java.sql");
+        assertEquals("https://example.org/api/java.sql/", noSlash.getHref());
+    }
+
+    // GROOVY-11682
+    public void testLinkWithModuleProducesJpmsStyleUrlInRenderedDoc() throws Exception {
+        ArrayList<LinkArgument> links = new ArrayList<>();
+        LinkArgument link = new LinkArgument();
+        link.setHref("https://docs.oracle.com/en/java/javase/17/docs/api/");
+        link.setModule("java.base");
+        link.setPackages("java.,javax.");
+        links.add(link);
+
+        GroovyDocTool jpmsTool = makeHtmltool(links, null, new Properties());
+        String base = "org/codehaus/groovy/tools/groovydoc/testfiles";
+        jpmsTool.add(List.of(base + "/DocumentedClass.groovy"));
+
+        MockOutputTool output = new MockOutputTool();
+        jpmsTool.renderToOutput(output, MOCK_DIR);
+
+        String doc = output.getText(MOCK_DIR + "/" + base + "/DocumentedClass.html");
+        assertNotNull("Expected DocumentedClass.html in output", doc);
+        assertTrue("Expected JPMS-style module segment in URL, got:\n" + doc,
+            doc.contains("https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html"));
+    }
+
     // GROOVY-9057
     public void testParseErrorIsTrackedInErrorCount() throws Exception {
         assertEquals("Initial error count should be zero", 0, xmlToolForTests.getErrorCount());