Merge branch '2.5.x' into 2.6.x

Closes gh-31127
This commit is contained in:
Phillip Webb 2022-05-19 18:03:52 -07:00
commit 9fa33e5645
8 changed files with 71 additions and 26 deletions

View File

@ -64,6 +64,11 @@ dependencies {
versionProperties(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "effectiveBom")) versionProperties(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "effectiveBom"))
} }
ext {
versionElements = version.split("\\.")
xsdVersion = versionElements[0] + "." + versionElements[1]
}
syncDocumentationSourceForAsciidoctor { syncDocumentationSourceForAsciidoctor {
from(documentPluginGoals) { from(documentPluginGoals) {
into "asciidoc/goals" into "asciidoc/goals"
@ -71,6 +76,9 @@ syncDocumentationSourceForAsciidoctor {
} }
sourceSets { sourceSets {
main {
output.dir("${buildDir}/generated/resources/xsd", builtBy: "xsdResources")
}
intTest { intTest {
output.dir("${buildDir}/generated-resources", builtBy: "extractVersionProperties") output.dir("${buildDir}/generated-resources", builtBy: "extractVersionProperties")
} }
@ -78,8 +86,7 @@ sourceSets {
tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) { tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
doFirst { doFirst {
def versionEl = version.split("\\.") attributes "spring-boot-xsd-version" : project.ext.xsdVersion
attributes "spring-boot-xsd-version": versionEl[0] + '.' + versionEl[1]
} }
} }
@ -129,6 +136,12 @@ task zip(type: Zip) {
} }
} }
task xsdResources(type: Sync) {
from "src/main/xsd/layers-${project.ext.xsdVersion}.xsd"
into "${buildDir}/generated/resources/xsd/org/springframework/boot/maven"
rename { fileName -> "layers.xsd" }
}
prepareMavenBinaries { prepareMavenBinaries {
versions "3.8.1", "3.6.3", "3.5.4" versions "3.8.1", "3.6.3", "3.5.4"
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -171,6 +171,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo
private Document getDocumentIfAvailable(File xmlFile) throws Exception { private Document getDocumentIfAvailable(File xmlFile) throws Exception {
InputSource inputSource = new InputSource(new FileInputStream(xmlFile)); InputSource inputSource = new InputSource(new FileInputStream(xmlFile));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder(); DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(inputSource); return builder.parse(inputSource);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2020 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,16 +16,24 @@
package org.springframework.boot.maven; package org.springframework.boot.maven;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.xml.XMLConstants;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.springframework.boot.loader.tools.Layer; import org.springframework.boot.loader.tools.Layer;
import org.springframework.boot.loader.tools.Library; import org.springframework.boot.loader.tools.Library;
@ -45,6 +53,7 @@ import org.springframework.boot.loader.tools.layer.LibraryContentFilter;
class CustomLayersProvider { class CustomLayersProvider {
CustomLayers getLayers(Document document) { CustomLayers getLayers(Document document) {
validate(document);
Element root = document.getDocumentElement(); Element root = document.getDocumentElement();
List<ContentSelector<String>> applicationSelectors = getApplicationSelectors(root); List<ContentSelector<String>> applicationSelectors = getApplicationSelectors(root);
List<ContentSelector<Library>> librarySelectors = getLibrarySelectors(root); List<ContentSelector<Library>> librarySelectors = getLibrarySelectors(root);
@ -52,6 +61,27 @@ class CustomLayersProvider {
return new CustomLayers(layers, applicationSelectors, librarySelectors); return new CustomLayers(layers, applicationSelectors, librarySelectors);
} }
private void validate(Document document) {
Schema schema = loadSchema();
try {
Validator validator = schema.newValidator();
validator.validate(new DOMSource(document));
}
catch (SAXException | IOException ex) {
throw new IllegalStateException("Invalid layers.xml configuration", ex);
}
}
private Schema loadSchema() {
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
return factory.newSchema(getClass().getResource("layers.xsd"));
}
catch (SAXException ex) {
throw new IllegalStateException("Unable to load layers XSD");
}
}
private List<ContentSelector<String>> getApplicationSelectors(Element root) { private List<ContentSelector<String>> getApplicationSelectors(Element root) {
return getSelectors(root, "application", (element) -> getSelector(element, ApplicationContentFilter::new)); return getSelectors(root, "application", (element) -> getSelector(element, ApplicationContentFilter::new));
} }

View File

@ -6,9 +6,9 @@
<xsd:element name="layers" type="layersType" /> <xsd:element name="layers" type="layersType" />
<xsd:complexType name="layersType"> <xsd:complexType name="layersType">
<xsd:sequence> <xsd:sequence>
<xsd:element name="application" type="applicationType" /> <xsd:element name="application" type="applicationType" minOccurs="0"/>
<xsd:element name="dependencies" type="dependenciesType" /> <xsd:element name="dependencies" type="dependenciesType" minOccurs="0"/>
<xsd:element name="layerOrder" type="layerOrderType" /> <xsd:element name="layerOrder" type="layerOrderType" minOccurs="0"/>
</xsd:sequence> </xsd:sequence>
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="applicationType"> <xsd:complexType name="applicationType">

View File

@ -6,9 +6,9 @@
<xsd:element name="layers" type="layersType" /> <xsd:element name="layers" type="layersType" />
<xsd:complexType name="layersType"> <xsd:complexType name="layersType">
<xsd:sequence> <xsd:sequence>
<xsd:element name="application" type="applicationType" /> <xsd:element name="application" type="applicationType" minOccurs="0"/>
<xsd:element name="dependencies" type="dependenciesType" /> <xsd:element name="dependencies" type="dependenciesType" minOccurs="0"/>
<xsd:element name="layerOrder" type="layerOrderType" /> <xsd:element name="layerOrder" type="layerOrderType" minOccurs="0"/>
</xsd:sequence> </xsd:sequence>
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="applicationType"> <xsd:complexType name="applicationType">
@ -78,21 +78,21 @@
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="intoType"> <xsd:extension base="intoType">
<xsd:choice minOccurs="0"> <xsd:choice minOccurs="0">
<xsd:element type="xsd:string" name="includeProjectDependencies" minOccurs="0"> <xsd:element type="xsd:string" name="includeModuleDependencies" minOccurs="0">
<xsd:annotation> <xsd:annotation>
<xsd:documentation><![CDATA[ <xsd:documentation><![CDATA[
Include dependencies on other modules in the build. Include dependencies on other modules in the build.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
</xsd:element> </xsd:element>
<xsd:element type="xsd:string" name="excludeProjectDependencies" minOccurs="0"> <xsd:element type="xsd:string" name="excludeModuleDependencies" minOccurs="0">
<xsd:annotation> <xsd:annotation>
<xsd:documentation><![CDATA[ <xsd:documentation><![CDATA[
Exclude dependencies on other modules in the build. Exclude dependencies on other modules in the build.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:extension> </xsd:extension>
</xsd:complexContent> </xsd:complexContent>
</xsd:complexType> </xsd:complexType>

View File

@ -6,9 +6,9 @@
<xsd:element name="layers" type="layersType" /> <xsd:element name="layers" type="layersType" />
<xsd:complexType name="layersType"> <xsd:complexType name="layersType">
<xsd:sequence> <xsd:sequence>
<xsd:element name="application" type="applicationType" /> <xsd:element name="application" type="applicationType" minOccurs="0"/>
<xsd:element name="dependencies" type="dependenciesType" /> <xsd:element name="dependencies" type="dependenciesType" minOccurs="0"/>
<xsd:element name="layerOrder" type="layerOrderType" /> <xsd:element name="layerOrder" type="layerOrderType" minOccurs="0"/>
</xsd:sequence> </xsd:sequence>
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="applicationType"> <xsd:complexType name="applicationType">
@ -78,21 +78,21 @@
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="intoType"> <xsd:extension base="intoType">
<xsd:choice minOccurs="0"> <xsd:choice minOccurs="0">
<xsd:element type="xsd:string" name="includeProjectDependencies" minOccurs="0"> <xsd:element type="xsd:string" name="includeModuleDependencies" minOccurs="0">
<xsd:annotation> <xsd:annotation>
<xsd:documentation><![CDATA[ <xsd:documentation><![CDATA[
Include dependencies on other modules in the build. Include dependencies on other modules in the build.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
</xsd:element> </xsd:element>
<xsd:element type="xsd:string" name="excludeProjectDependencies" minOccurs="0"> <xsd:element type="xsd:string" name="excludeModuleDependencies" minOccurs="0">
<xsd:annotation> <xsd:annotation>
<xsd:documentation><![CDATA[ <xsd:documentation><![CDATA[
Exclude dependencies on other modules in the build. Exclude dependencies on other modules in the build.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:extension> </xsd:extension>
</xsd:complexContent> </xsd:complexContent>
</xsd:complexType> </xsd:complexType>

View File

@ -6,9 +6,9 @@
<xsd:element name="layers" type="layersType" /> <xsd:element name="layers" type="layersType" />
<xsd:complexType name="layersType"> <xsd:complexType name="layersType">
<xsd:sequence> <xsd:sequence>
<xsd:element name="application" type="applicationType" /> <xsd:element name="application" type="applicationType" minOccurs="0"/>
<xsd:element name="dependencies" type="dependenciesType" /> <xsd:element name="dependencies" type="dependenciesType" minOccurs="0"/>
<xsd:element name="layerOrder" type="layerOrderType" /> <xsd:element name="layerOrder" type="layerOrderType" minOccurs="0"/>
</xsd:sequence> </xsd:sequence>
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="applicationType"> <xsd:complexType name="applicationType">
@ -78,21 +78,21 @@
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="intoType"> <xsd:extension base="intoType">
<xsd:choice minOccurs="0"> <xsd:choice minOccurs="0">
<xsd:element type="xsd:string" name="includeProjectDependencies" minOccurs="0"> <xsd:element type="xsd:string" name="includeModuleDependencies" minOccurs="0">
<xsd:annotation> <xsd:annotation>
<xsd:documentation><![CDATA[ <xsd:documentation><![CDATA[
Include dependencies on other modules in the build. Include dependencies on other modules in the build.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
</xsd:element> </xsd:element>
<xsd:element type="xsd:string" name="excludeProjectDependencies" minOccurs="0"> <xsd:element type="xsd:string" name="excludeModuleDependencies" minOccurs="0">
<xsd:annotation> <xsd:annotation>
<xsd:documentation><![CDATA[ <xsd:documentation><![CDATA[
Exclude dependencies on other modules in the build. Exclude dependencies on other modules in the build.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:extension> </xsd:extension>
</xsd:complexContent> </xsd:complexContent>
</xsd:complexType> </xsd:complexType>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -97,6 +97,7 @@ class CustomLayersProviderTests {
ClassPathResource resource = new ClassPathResource(resourceName); ClassPathResource resource = new ClassPathResource(resourceName);
InputSource inputSource = new InputSource(resource.getInputStream()); InputSource inputSource = new InputSource(resource.getInputStream());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder documentBuilder = factory.newDocumentBuilder(); DocumentBuilder documentBuilder = factory.newDocumentBuilder();
return documentBuilder.parse(inputSource); return documentBuilder.parse(inputSource);
} }