From deec6aa76dffaa80f3c01e72377913cd22f96672 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Tue, 26 Aug 2025 06:37:48 +0000 Subject: [PATCH] 8365394: Stylesheet must not load fonts on --no-fonts output Reviewed-by: hannesw --- .../doclets/formats/html/HtmlDoclet.java | 48 ++++++++++++++----- .../doclets/toolkit/util/DocFile.java | 32 ++++++++++--- .../javadoc/doclet/testFonts/TestFonts.java | 4 ++ .../doclet/testStylesheet/TestStylesheet.java | 1 + 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java index d00d7b1becf..24fc8e6b2de 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java @@ -317,10 +317,11 @@ public class HtmlDoclet extends AbstractDoclet { copyResource(DocPaths.HIGHLIGHT_JS, DocPaths.SCRIPT_FILES.resolve(DocPaths.HIGHLIGHT_JS), true); } - // If a stylesheet file is not specified, copy the default stylesheet - // and replace newline with platform-specific newline. + // If a stylesheet file is not specified, copy the default stylesheet, + // replace newline with platform-specific newline, + // and remove the reference to fonts if --no-fonts is used. if (options.stylesheetFile().isEmpty()) { - copyResource(DocPaths.STYLESHEET, DocPaths.RESOURCE_FILES.resolve(DocPaths.STYLESHEET), true); + copyStylesheet(options); } copyResource(DocPaths.SCRIPT_JS_TEMPLATE, DocPaths.SCRIPT_FILES.resolve(DocPaths.SCRIPT_JS), true); copyResource(DocPaths.LEFT_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.LEFT_SVG), true); @@ -463,18 +464,13 @@ public class HtmlDoclet extends AbstractDoclet { private void copyResource(DocPath sourcePath, DocPath targetPath, boolean replaceNewLine) throws DocletException { - DocPath resourcePath = DocPaths.RESOURCES.resolve(sourcePath); - // Resolve resources against doclets.formats.html package - URL resourceURL = HtmlConfiguration.class.getResource(resourcePath.getPath()); - if (resourceURL == null) { - throw new ResourceIOException(sourcePath, new FileNotFoundException(resourcePath.getPath())); - } + ReadableResource resource = resolveResource(sourcePath); DocFile f = DocFile.createFileForOutput(configuration, targetPath); if (sourcePath.getPath().toLowerCase(Locale.ROOT).endsWith(".template")) { - f.copyResource(resourcePath, resourceURL, configuration.docResources); + f.copyResource(resource.path(), resource.url(), configuration.docResources); } else { - f.copyResource(resourcePath, resourceURL, replaceNewLine); + f.copyResource(resource.path(), resource.url(), replaceNewLine); } } @@ -503,6 +499,23 @@ public class HtmlDoclet extends AbstractDoclet { } } + private void copyStylesheet(HtmlOptions options) throws DocletException { + ReadableResource resource = resolveResource(DocPaths.STYLESHEET); + var targetPath = DocPaths.RESOURCE_FILES.resolve(DocPaths.STYLESHEET); + DocFile f = DocFile.createFileForOutput(configuration, targetPath); + + if (options.noFonts()) { + f.copyResource(resource.path(), resource.url(), line -> { + if (line.startsWith("@import url('fonts")) { + return null; // remove the line + } + return line; + }); + } else { + f.copyResource(resource.path(), resource.url(), true); + } + } + private void copyFile(String filename, DocPath targetPath) throws DocFileIOException { if (filename.isEmpty()) { return; @@ -519,4 +532,17 @@ public class HtmlDoclet extends AbstractDoclet { fromfile.getPath(), path.getPath()); toFile.copyFile(fromfile); } + + private ReadableResource resolveResource(DocPath sourcePath) throws ResourceIOException { + DocPath resolvedPath = DocPaths.RESOURCES.resolve(sourcePath); + // Resolve resources against doclets.formats.html package + URL resourceURL = HtmlConfiguration.class.getResource(resolvedPath.getPath()); + if (resourceURL == null) { + throw new ResourceIOException(sourcePath, new FileNotFoundException(resolvedPath.getPath())); + } + return new ReadableResource(resolvedPath, resourceURL); + } + + private record ReadableResource(DocPath path, URL url) { + } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocFile.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocFile.java index 1c69e6156e2..26e9635b9db 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocFile.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocFile.java @@ -35,6 +35,7 @@ import java.io.Writer; import java.net.URL; import java.nio.file.Path; import java.util.MissingResourceException; +import java.util.function.UnaryOperator; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -188,7 +189,7 @@ public abstract class DocFile { */ public void copyResource(DocPath resource, URL url, boolean replaceNewLine) throws DocFileIOException, ResourceIOException { - copyResource(resource, url, replaceNewLine, null); + copyResource(resource, url, replaceNewLine, UnaryOperator.identity()); } /** @@ -202,11 +203,27 @@ public abstract class DocFile { * @throws ResourceIOException if there is a problem while reading the resource */ public void copyResource(DocPath resource, URL url, Resources resources) throws DocFileIOException, ResourceIOException { - copyResource(resource, url, true, resources); + copyResource(resource, url, resources == null ? UnaryOperator.identity() : line -> localize(line, resources)); } - private void copyResource(DocPath resource, URL url, boolean replaceNewLine, Resources resources) - throws DocFileIOException, ResourceIOException { + /** + * Copy the contents of a resource file to this file while transforming and filtering its lines. + * + * @param resource the path of the resource + * @param url the URL of the resource + * @param lineTransformer the transforming function that is called for each line; may return + * {@code null} to remove a line. + * + * @throws DocFileIOException if there is a problem while writing the copy + * @throws ResourceIOException if there is a problem while reading the resource + */ + public void copyResource(DocPath resource, URL url, UnaryOperator lineTransformer) + throws DocFileIOException, ResourceIOException { + copyResource(resource, url, true, lineTransformer); + } + + private void copyResource(DocPath resource, URL url, boolean replaceNewLine, UnaryOperator lineTransformer) + throws ResourceIOException, DocFileIOException { try { InputStream in = url.openStream(); @@ -216,8 +233,11 @@ public abstract class DocFile { try (Writer writer = openWriter()) { String line; while ((line = readResourceLine(resource, reader)) != null) { - write(this, writer, resources == null ? line : localize(line, resources)); - write(this, writer, PLATFORM_LINE_SEPARATOR); + String transformedLine = lineTransformer.apply(line); + if (transformedLine != null) { + write(this, writer, transformedLine); + write(this, writer, PLATFORM_LINE_SEPARATOR); + } } } catch (IOException e) { throw new DocFileIOException(this, DocFileIOException.Mode.WRITE, e); diff --git a/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java b/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java index 56b2bbfb786..647ae9d8cdd 100644 --- a/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java +++ b/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java @@ -64,6 +64,8 @@ public class TestFonts extends JavadocTester { javadoc("-d", base.resolve("out").toString(), src.resolve("Dummy.java").toString()); checkExit(Exit.OK); + checkOutput("resource-files/stylesheet.css", true, + "@import url('fonts/dejavu.css');"); checkOutput("resource-files/fonts/dejavu.css", true, """ /* DejaVu fonts v2.37 */""", @@ -115,6 +117,8 @@ public class TestFonts extends JavadocTester { "resource-files/link.svg", "resource-files/stylesheet.css", "resource-files/x.svg"); + checkOutput("resource-files/stylesheet.css", false, + "@import url('fonts/dejavu.css');"); checkFiles(false, "resource-files/fonts"); } } diff --git a/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java b/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java index 87ff58e1395..44651c16f5e 100644 --- a/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java +++ b/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java @@ -55,6 +55,7 @@ public class TestStylesheet extends JavadocTester { @Test public void test(Path base) { + setUseDefaultOptions(false); javadoc("-d", base.resolve("out").toString(), "-sourcepath", testSrc, "pkg");