Skip to content

Commit 779541b

Browse files
committed
Merge branch '5.7.x' into 5.8.x
Automate spring-security.xsd Closes gh-13823
2 parents f026e29 + 5b293d2 commit 779541b

File tree

5 files changed

+264
-11
lines changed

5 files changed

+264
-11
lines changed

buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaZipPlugin.groovy

+11-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import org.gradle.api.Plugin
44
import org.gradle.api.Project
55
import org.gradle.api.plugins.JavaPlugin
66
import org.gradle.api.tasks.bundling.Zip
7+
import org.springframework.gradle.xsd.CreateVersionlessXsdTask
78

89
public class SchemaZipPlugin implements Plugin<Project> {
910

@@ -15,7 +16,10 @@ public class SchemaZipPlugin implements Plugin<Project> {
1516
schemaZip.archiveClassifier = 'schema'
1617
schemaZip.description = "Builds -${schemaZip.archiveClassifier} archive containing all " +
1718
"XSDs for deployment at static.springframework.org/schema."
18-
19+
def versionlessXsd = project.tasks.create("versionlessXsd", CreateVersionlessXsdTask) {
20+
description = "Generates spring-security.xsd"
21+
versionlessXsdFile = project.layout.buildDirectory.file("versionlessXsd/spring-security.xsd")
22+
}
1923
project.rootProject.subprojects.each { module ->
2024

2125
module.getPlugins().withType(JavaPlugin.class).all {
@@ -36,17 +40,14 @@ public class SchemaZipPlugin implements Plugin<Project> {
3640
duplicatesStrategy 'exclude'
3741
from xsdFile.path
3842
}
39-
}
40-
File symlink = module.sourceSets.main.resources.find {
41-
it.path.endsWith('org/springframework/security/config/spring-security.xsd')
42-
}
43-
if (symlink != null) {
44-
schemaZip.into('security') {
45-
duplicatesStrategy 'exclude'
46-
from symlink.path
47-
}
43+
versionlessXsd.getInputFiles().from(xsdFile.path)
4844
}
4945
}
5046
}
47+
48+
schemaZip.into("security") {
49+
from(versionlessXsd.getOutputs())
50+
}
51+
5152
}
5253
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright 2019-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.gradle.xsd;
18+
19+
import org.gradle.api.DefaultTask;
20+
import org.gradle.api.file.ConfigurableFileCollection;
21+
import org.gradle.api.file.RegularFileProperty;
22+
import org.gradle.api.tasks.*;
23+
import org.gradle.work.DisableCachingByDefault;
24+
25+
import java.io.File;
26+
import java.io.IOException;
27+
import java.nio.file.Files;
28+
import java.nio.file.Path;
29+
import java.nio.file.StandardCopyOption;
30+
import java.util.regex.Matcher;
31+
import java.util.regex.Pattern;
32+
33+
/**
34+
* Creates the spring-security.xsd automatically
35+
*
36+
* @author Rob Winch
37+
*/
38+
@DisableCachingByDefault(because = "not worth it")
39+
public abstract class CreateVersionlessXsdTask extends DefaultTask {
40+
41+
@InputFiles
42+
public abstract ConfigurableFileCollection getInputFiles();
43+
44+
@OutputFile
45+
abstract RegularFileProperty getVersionlessXsdFile();
46+
47+
@TaskAction
48+
void createVersionlessXsd() throws IOException {
49+
XsdFileMajorMinorVersion largest = null;
50+
ConfigurableFileCollection inputFiles = getInputFiles();
51+
if (inputFiles.isEmpty()) {
52+
throw new IllegalStateException("No Inputs configured");
53+
}
54+
for (File file : inputFiles) {
55+
XsdFileMajorMinorVersion current = XsdFileMajorMinorVersion.create(file);
56+
if (current == null) {
57+
continue;
58+
}
59+
if (largest == null) {
60+
largest = current;
61+
}
62+
else if (current.getVersion().isGreaterThan(largest.getVersion())) {
63+
largest = current;
64+
}
65+
}
66+
if (largest == null) {
67+
throw new IllegalStateException("Could not create versionless xsd file because no files matching spring-security-<digit>.xsd were found in " + inputFiles.getFiles());
68+
}
69+
Path to = getVersionlessXsdFile().getAsFile().get().toPath();
70+
Path from = largest.getFile().toPath();
71+
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
72+
}
73+
74+
static class XsdFileMajorMinorVersion {
75+
private final File file;
76+
77+
private final MajorMinorVersion version;
78+
79+
private XsdFileMajorMinorVersion(File file, MajorMinorVersion version) {
80+
this.file = file;
81+
this.version = version;
82+
}
83+
84+
private static final Pattern FILE_MAJOR_MINOR_VERSION_PATTERN = Pattern.compile("^spring-security-(\\d+)\\.(\\d+)\\.xsd$");
85+
86+
/**
87+
* If matches xsd with major minor version (e.g. spring-security-5.1.xsd returns it, otherwise null
88+
* @param file
89+
* @return
90+
*/
91+
static XsdFileMajorMinorVersion create(File file) {
92+
String fileName = file.getName();
93+
Matcher matcher = FILE_MAJOR_MINOR_VERSION_PATTERN.matcher(fileName);
94+
if (!matcher.find()) {
95+
return null;
96+
}
97+
int major = Integer.parseInt(matcher.group(1));
98+
int minor = Integer.parseInt(matcher.group(2));
99+
MajorMinorVersion version = new MajorMinorVersion(major, minor);
100+
return new XsdFileMajorMinorVersion(file, version);
101+
}
102+
103+
public File getFile() {
104+
return file;
105+
}
106+
107+
public MajorMinorVersion getVersion() {
108+
return version;
109+
}
110+
}
111+
112+
static class MajorMinorVersion {
113+
private final int major;
114+
115+
private final int minor;
116+
117+
MajorMinorVersion(int major, int minor) {
118+
this.major = major;
119+
this.minor = minor;
120+
}
121+
122+
public int getMajor() {
123+
return major;
124+
}
125+
126+
public int getMinor() {
127+
return minor;
128+
}
129+
130+
public boolean isGreaterThan(MajorMinorVersion version) {
131+
if (getMajor() > version.getMajor()) {
132+
return true;
133+
}
134+
if (getMajor() < version.getMajor()) {
135+
return false;
136+
}
137+
if (getMinor() > version.getMinor()) {
138+
return true;
139+
}
140+
if (getMinor() < version.getMinor()) {
141+
return false;
142+
}
143+
// they are equal
144+
return false;
145+
}
146+
}
147+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2019-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.gradle.xsd;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.gradle.xsd.CreateVersionlessXsdTask.MajorMinorVersion;
21+
import org.springframework.gradle.xsd.CreateVersionlessXsdTask.XsdFileMajorMinorVersion;
22+
23+
import java.io.File;
24+
25+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
26+
27+
/**
28+
* @author Rob Winch
29+
*/
30+
class CreateVersionlessXsdTaskTests {
31+
32+
@Test
33+
void xsdCreateWhenValid() {
34+
File file = new File("spring-security-2.0.xsd");
35+
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
36+
assertThat(xsdFile).isNotNull();
37+
assertThat(xsdFile.getFile()).isEqualTo(file);
38+
assertThat(xsdFile.getVersion().getMajor()).isEqualTo(2);
39+
assertThat(xsdFile.getVersion().getMinor()).isEqualTo(0);
40+
}
41+
42+
@Test
43+
void xsdCreateWhenPatchReleaseThenNull() {
44+
File file = new File("spring-security-2.0.1.xsd");
45+
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
46+
assertThat(xsdFile).isNull();
47+
}
48+
49+
@Test
50+
void xsdCreateWhenNotXsdFileThenNull() {
51+
File file = new File("spring-security-2.0.txt");
52+
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
53+
assertThat(xsdFile).isNull();
54+
}
55+
56+
@Test
57+
void xsdCreateWhenNotStartWithSpringSecurityThenNull() {
58+
File file = new File("spring-securityNO-2.0.xsd");
59+
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
60+
assertThat(xsdFile).isNull();
61+
}
62+
63+
@Test
64+
void isGreaterWhenMajorLarger() {
65+
MajorMinorVersion larger = new MajorMinorVersion(2,0);
66+
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
67+
assertThat(larger.isGreaterThan(smaller)).isTrue();
68+
assertThat(smaller.isGreaterThan(larger)).isFalse();
69+
}
70+
71+
@Test
72+
void isGreaterWhenMinorLarger() {
73+
MajorMinorVersion larger = new MajorMinorVersion(1,1);
74+
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
75+
assertThat(larger.isGreaterThan(smaller)).isTrue();
76+
assertThat(smaller.isGreaterThan(larger)).isFalse();
77+
}
78+
79+
@Test
80+
void isGreaterWhenMajorAndMinorLarger() {
81+
MajorMinorVersion larger = new MajorMinorVersion(2,1);
82+
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
83+
assertThat(larger.isGreaterThan(smaller)).isTrue();
84+
assertThat(smaller.isGreaterThan(larger)).isFalse();
85+
}
86+
87+
@Test
88+
void isGreaterWhenSame() {
89+
MajorMinorVersion first = new MajorMinorVersion(1,0);
90+
MajorMinorVersion second = new MajorMinorVersion(1,0);
91+
assertThat(first.isGreaterThan(second)).isFalse();
92+
assertThat(second.isGreaterThan(first)).isFalse();
93+
}
94+
}

config/spring-security-config.gradle

+12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2+
import org.springframework.gradle.xsd.CreateVersionlessXsdTask
23
import trang.RncToXsd
34

45
apply plugin: 'io.spring.convention.spring-module'
@@ -110,6 +111,17 @@ dependencies {
110111
testRuntimeOnly 'org.hsqldb:hsqldb'
111112
}
112113

114+
def versionlessXsd = project.tasks.create("versionlessXsd", CreateVersionlessXsdTask) {
115+
inputFiles.from(project.sourceSets.main.resources)
116+
versionlessXsdFile = project.layout.buildDirectory.file("versionlessXsd/spring-security.xsd")
117+
}
118+
119+
processResources {
120+
from(versionlessXsd) {
121+
into 'org/springframework/security/config/'
122+
}
123+
}
124+
113125
tasks.named('rncToXsd', RncToXsd).configure {
114126
rncDir = file('src/main/resources/org/springframework/security/config/')
115127
xsdDir = rncDir

config/src/main/resources/org/springframework/security/config/spring-security.xsd

-1
This file was deleted.

0 commit comments

Comments
 (0)