diff --git a/buildSrc/src/main/java/org/springframework/boot/build/antora/AntoraAsciidocAttributes.java b/buildSrc/src/main/java/org/springframework/boot/build/antora/AntoraAsciidocAttributes.java index 3648fe67b0..efa5262ce2 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/antora/AntoraAsciidocAttributes.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/antora/AntoraAsciidocAttributes.java @@ -127,6 +127,8 @@ public class AntoraAsciidocAttributes { addDependencyVersion(attributes, "jackson-annotations", "com.fasterxml.jackson.core:jackson-annotations"); addDependencyVersion(attributes, "jackson-core", "com.fasterxml.jackson.core:jackson-core"); addDependencyVersion(attributes, "jackson-databind", "com.fasterxml.jackson.core:jackson-databind"); + addDependencyVersion(attributes, "jackson-dataformat-xml", + "com.fasterxml.jackson.dataformat:jackson-dataformat-xml"); addSpringDataDependencyVersion(attributes, internal, "spring-data-commons"); addSpringDataDependencyVersion(attributes, internal, "spring-data-couchbase"); addSpringDataDependencyVersion(attributes, internal, "spring-data-cassandra"); @@ -185,16 +187,16 @@ public class AntoraAsciidocAttributes { private void addUrlLibraryLinkAttributes(Map attributes) { Map packageAttributes = new LinkedHashMap<>(); this.libraries.forEach((library) -> { - String prefix = "url-" + library.getLinkRootName() + "-"; - library.getLinks().forEach((name, link) -> { - String linkName = prefix + name; + library.getLinks().forEach((name, links) -> links.forEach((link) -> { + String linkRootName = (link.rootName() != null) ? link.rootName() : library.getLinkRootName(); + String linkName = "url-" + linkRootName + "-" + name; attributes.put(linkName, link.url(library)); link.packages() .stream() .map(this::packageAttributeName) .forEach((packageAttributeName) -> packageAttributes.put(packageAttributeName, "{" + linkName + "}")); - }); + })); }); attributes.putAll(packageAttributes); } diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java index 5274211761..e7a8718182 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java @@ -256,7 +256,7 @@ public class BomExtension { private String linkRootName; - private final Map links = new HashMap<>(); + private final Map> links = new HashMap<>(); @Inject public LibraryHandler(Project project, String version) { @@ -458,7 +458,7 @@ public class BomExtension { public static class LinksHandler { - private final Map links = new HashMap<>(); + private final Map> links = new HashMap<>(); public void site(String linkTemplate) { site(asFactory(linkTemplate)); @@ -500,6 +500,10 @@ public class BomExtension { add("javadoc", linkFactory, packages); } + public void javadoc(String rootName, Function linkFactory, String... packages) { + add(rootName, "javadoc", linkFactory, packages); + } + public void releaseNotes(String linkTemplate) { releaseNotes(asFactory(linkTemplate)); } @@ -517,7 +521,13 @@ public class BomExtension { } public void add(String name, Function linkFactory, String[] packages) { - this.links.put(name, new Link(linkFactory, (packages != null) ? List.of(packages) : null)); + add(null, name, linkFactory, packages); + } + + private void add(String rootName, String name, Function linkFactory, + String[] packages) { + Link link = new Link(rootName, linkFactory, (packages != null) ? List.of(packages) : null); + this.links.computeIfAbsent(name, (key) -> new ArrayList<>()).add(link); } private Function asFactory(String linkTemplate) { diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckLinks.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckLinks.java index 18111fccf3..94c415144d 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckLinks.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/CheckLinks.java @@ -59,7 +59,7 @@ public abstract class CheckLinks extends DefaultTask { RestTemplate restTemplate = new RestTemplate(requestFactory); restTemplate.setErrorHandler(new IgnoringErrorHandler()); for (Library library : this.bom.getLibraries()) { - library.getLinks().forEach((name, link) -> { + library.getLinks().forEach((name, links) -> links.forEach((link) -> { URI uri; try { uri = new URI(link.url(library)); @@ -70,7 +70,7 @@ public abstract class CheckLinks extends DefaultTask { catch (URISyntaxException ex) { throw new RuntimeException(ex); } - }); + })); } } diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java index ba1ab81b79..c75e12f5a0 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java @@ -68,7 +68,7 @@ public class Library { private final String linkRootName; - private final Map links; + private final Map> links; /** * Create a new {@code Library} with the given {@code name}, {@code version}, and @@ -89,7 +89,7 @@ public class Library { */ public Library(String name, String calendarName, LibraryVersion version, List groups, List prohibitedVersions, boolean considerSnapshots, VersionAlignment versionAlignment, - String alignsWithBom, String linkRootName, Map links) { + String alignsWithBom, String linkRootName, Map> links) { this.name = name; this.calendarName = (calendarName != null) ? calendarName : name; this.version = version; @@ -148,16 +148,22 @@ public class Library { return this.alignsWithBom; } - public Map getLinks() { + public Map> getLinks() { return this.links; } public String getLinkUrl(String name) { - Link link = getLink(name); - return (link != null) ? link.url(this) : null; + List links = getLinks(name); + if (links == null || links.isEmpty()) { + return null; + } + if (links.size() > 1) { + throw new IllegalStateException("Expected a single '%s' link for %s".formatted(name, getName())); + } + return links.get(0).url(this); } - public Link getLink(String name) { + public List getLinks(String name) { return this.links.get(name); } @@ -524,7 +530,7 @@ public class Library { } - public record Link(Function factory, List packages) { + public record Link(String rootName, Function factory, List packages) { private static final Pattern PACKAGE_EXPAND = Pattern.compile("^(.*)\\[(.*)\\]$"); diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeBom.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeBom.java index 5d44bed62b..31db135268 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeBom.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeBom.java @@ -28,7 +28,6 @@ import org.gradle.api.artifacts.repositories.MavenArtifactRepository; import org.springframework.boot.build.bom.BomExtension; import org.springframework.boot.build.bom.Library.LibraryVersion; -import org.springframework.boot.build.bom.Library.Link; import org.springframework.boot.build.bom.bomr.github.Issue; import org.springframework.boot.build.properties.BuildProperties; @@ -77,7 +76,7 @@ public abstract class UpgradeBom extends UpgradeDependencies { @Override protected String issueBody(Upgrade upgrade, Issue existingUpgrade) { LibraryVersion upgradeVersion = new LibraryVersion(upgrade.getVersion()); - String releaseNotesLink = getReleaseNotesLink(upgrade, upgradeVersion); + String releaseNotesLink = upgrade.getLibrary().getLinkUrl("releaseNotes"); List lines = new ArrayList<>(); String description = upgrade.getLibrary().getName() + " " + upgradeVersion; if (releaseNotesLink != null) { @@ -92,9 +91,4 @@ public abstract class UpgradeBom extends UpgradeDependencies { return String.join("\\r\\n\\r\\n", lines); } - private String getReleaseNotesLink(Upgrade upgrade, LibraryVersion upgradeVersion) { - Link releaseNotesLink = upgrade.getLibrary().getLink("releaseNotes"); - return (releaseNotesLink != null) ? releaseNotesLink.url(upgradeVersion) : null; - } - } diff --git a/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties b/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties index 5bfbb3ec56..b83ddededc 100644 --- a/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties +++ b/buildSrc/src/main/resources/org/springframework/boot/build/antora/antora-asciidoc-attributes.properties @@ -75,6 +75,7 @@ url-spring-data-site=https://spring.io/projects/spring-data url-jackson-annotations-javadoc=https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-annotations/{version-jackson-annotations} url-jackson-core-javadoc=https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-core/{version-jackson-core} url-jackson-databind-javadoc=https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind/{version-jackson-databind} +url-jackson-dataformat-xml-javadoc=https://javadoc.io/doc/com.fasterxml.jackson.dataformat/jackson-dataformat-xml/{version-jackson-dataformat-xml} # === Javadoc Locations === @@ -92,6 +93,7 @@ javadoc-location-org-springframework-data-r2dbc={url-spring-data-r2dbc-javadoc} javadoc-location-org-springframework-data-redis={url-spring-data-redis-javadoc} javadoc-location-org-springframework-data-rest={url-spring-data-rest-javadoc} javadoc-location-com-fasterxml-jackson-databind={url-jackson-databind-javadoc} +javadoc-location-com-fasterxml-jackson-dataformat-xml={url-jackson-dataformat-xml-javadoc} # === API References === diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 326ea2458a..3c585916cf 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -260,6 +260,7 @@ bom { } links { site("https://docs.couchbase.com/java-sdk/current/hello-world/overview.html") + javadoc("https://javadoc.io/doc/com.couchbase.client/java-client/{version}") releaseNotes("https://docs.couchbase.com/java-sdk/current/project-docs/sdk-release-notes.html") } } @@ -553,6 +554,10 @@ bom { "HikariCP" ] } + links { + site("https://github.com/brettwooldridge/HikariCP") + javadoc("https://javadoc.io/doc/com.zaxxer/HikariCP/{version}", "com.zaxxer.hikari") + } } library("HSQLDB", "2.7.4") { group("org.hsqldb") { @@ -817,6 +822,13 @@ bom { "jakarta.websocket-client-api" ] } + links { + releaseNotes("https://github.com/jakartaee/jaxb-api/releases/tag/{version}") + javadoc("jakarta-websocket-server", version -> "https://jakarta.ee/specifications/websocket/%s.%s/apidocs/server" + .formatted(version.major(), version.minor()), "jakarta.websocket.server") + javadoc("jakarta-websocket-client", version -> "https://jakarta.ee/specifications/websocket/%s.%s/apidocs/client" + .formatted(version.major(), version.minor()), "jakarta.websocket") + } } library("Jakarta WS RS", "3.1.0") { group("jakarta.ws.rs") { @@ -833,6 +845,8 @@ bom { } links { releaseNotes("https://github.com/jakartaee/jaxb-api/releases/tag/{version}") + javadoc(version -> "https://jakarta.ee/specifications/xml-binding/%s.%s/apidocs" + .formatted(version.major(), version.minor()), "jakarta.xml.bind") } } library("Jakarta XML SOAP", "3.0.2") { @@ -965,6 +979,7 @@ bom { } links { site("https://eclipse.dev/jetty") + javadoc(version -> "https://javadoc.jetty.org/jetty-%s".formatted(version.major())) releaseNotes("https://github.com/jetty/jetty.project/releases/tag/jetty-{version}") } } @@ -1174,6 +1189,7 @@ bom { } links { site("https://www.liquibase.com") + javadoc("https://javadoc.io/doc/org.liquibase/liquibase-core/{version}") releaseNotes("https://github.com/liquibase/liquibase/releases/tag/v{version}") } } @@ -1185,6 +1201,8 @@ bom { } links { site("https://logging.apache.org/log4j") + javadoc("log4j-api", version -> "https://logging.apache.org/log4j/%s.x/javadoc/log4j-api/index.html".formatted(version.major())) + javadoc("log4j-core", version -> "https://logging.apache.org/log4j/%s.x/javadoc/log4j-core/index.html".formatted(version.major())) docs(version -> "https://logging.apache.org/log4j/%s.x/manual".formatted(version.major())) releaseNotes("https://github.com/apache/logging-log4j2/releases/tag/rel%2F{version}") } @@ -1198,6 +1216,7 @@ bom { } links { site("https://logback.qos.ch") + javadoc("https://logback.qos.ch/apidocs") } } library("Lombok", "1.18.34") { @@ -1208,6 +1227,7 @@ bom { } links { site("https://projectlombok.org") + javadoc("https://projectlombok.org/api/") } } library("MariaDB", "3.4.1") { @@ -2328,6 +2348,8 @@ bom { } links { site("https://www.thymeleaf.org/") + javadoc("thymeleaf", version -> "https://www.thymeleaf.org/apidocs/thymeleaf/%s".formatted(version), "org.thymeleaf") + javadoc("thymeleaf-spring6", version -> "https://www.thymeleaf.org/apidocs/thymeleaf-spring6/%s".formatted(version), "org.thymeleaf.spring6") releaseNotes("https://github.com/thymeleaf/thymeleaf/releases/tag/thymeleaf-{version}") } } @@ -2373,9 +2395,9 @@ bom { } links { site("https://tomcat.apache.org") + javadoc(version -> "https://tomcat.apache.org/tomcat-%s.%s-doc/api".formatted(version.major(), version.minor())) docs(version -> "https://tomcat.apache.org/tomcat-%s.%s-doc".formatted(version.major(), version.minor())) - releaseNotes(version -> "https://tomcat.apache.org/tomcat-%s.%s-doc/changelog.html" - .formatted(version.major(), version.minor())) + releaseNotes(version -> "https://tomcat.apache.org/tomcat-%s.%s-doc/changelog.html".formatted(version.major(), version.minor())) } } library("UnboundID LDAPSDK", "6.0.11") {