Skip to content

Commit 7fc9deb

Browse files
committed
Consider super classes when detecting nested property classes
Update `PropertyDescriptor.isParentTheSame` to consider the candidate as well as all super classes. Fixes gh-21626
1 parent 49fd727 commit 7fc9deb

File tree

9 files changed

+304
-10
lines changed

9 files changed

+304
-10
lines changed

spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -177,7 +177,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
177177
}
178178
if (roundEnv.processingOver()) {
179179
try {
180-
writeMetaData();
180+
writeMetadata();
181181
}
182182
catch (Exception ex) {
183183
throw new IllegalStateException("Failed to write metadata", ex);
@@ -324,7 +324,7 @@ private String getPrefix(AnnotationMirror annotation) {
324324
return null;
325325
}
326326

327-
protected ConfigurationMetadata writeMetaData() throws Exception {
327+
protected ConfigurationMetadata writeMetadata() throws Exception {
328328
ConfigurationMetadata metadata = this.metadataCollector.getMetadata();
329329
metadata = mergeAdditionalMetadata(metadata);
330330
if (!metadata.getItems().isEmpty()) {

spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptor.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -119,7 +119,7 @@ protected boolean isNested(MetadataGenerationEnvironment environment) {
119119
if (isCyclePresent(typeElement, getOwnerElement())) {
120120
return false;
121121
}
122-
return isParentTheSame(typeElement, getOwnerElement());
122+
return isParentTheSame(environment, typeElement, getOwnerElement());
123123
}
124124

125125
ItemMetadata resolveItemMetadata(String prefix, MetadataGenerationEnvironment environment) {
@@ -169,11 +169,20 @@ private boolean isCyclePresent(Element returnType, Element element) {
169169
return isCyclePresent(returnType, element.getEnclosingElement());
170170
}
171171

172-
private boolean isParentTheSame(Element returnType, TypeElement element) {
172+
private boolean isParentTheSame(MetadataGenerationEnvironment environment, Element returnType,
173+
TypeElement element) {
173174
if (returnType == null || element == null) {
174175
return false;
175176
}
176-
return getTopLevelType(returnType).equals(getTopLevelType(element));
177+
returnType = getTopLevelType(returnType);
178+
Element candidate = element;
179+
while (candidate != null && candidate instanceof TypeElement) {
180+
if (returnType.equals(getTopLevelType(candidate))) {
181+
return true;
182+
}
183+
candidate = environment.getTypeUtils().asElement(((TypeElement) candidate).getSuperclass());
184+
}
185+
return false;
177186
}
178187

179188
private Element getTopLevelType(Element element) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2012-2022 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.boot.configurationprocessor;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
22+
import org.springframework.boot.configurationprocessor.metadata.Metadata;
23+
import org.springframework.boot.configurationsample.inheritance.ChildProperties;
24+
import org.springframework.boot.configurationsample.inheritance.ChildPropertiesConfig;
25+
import org.springframework.boot.configurationsample.inheritance.OverrideChildProperties;
26+
import org.springframework.boot.configurationsample.inheritance.OverrideChildPropertiesConfig;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
30+
class InheritanceMetadataGenerationTests extends AbstractMetadataGenerationTests {
31+
32+
@Test
33+
void childProperties() throws Exception {
34+
ConfigurationMetadata metadata = compile(ChildPropertiesConfig.class);
35+
assertThat(metadata).has(Metadata.withGroup("inheritance").fromSource(ChildPropertiesConfig.class));
36+
assertThat(metadata).has(Metadata.withGroup("inheritance.nest").fromSource(ChildProperties.class));
37+
assertThat(metadata).has(Metadata.withGroup("inheritance.child-nest").fromSource(ChildProperties.class));
38+
assertThat(metadata).has(Metadata.withProperty("inheritance.bool-value"));
39+
assertThat(metadata).has(Metadata.withProperty("inheritance.int-value"));
40+
assertThat(metadata).has(Metadata.withProperty("inheritance.long-value"));
41+
assertThat(metadata).has(Metadata.withProperty("inheritance.nest.bool-value"));
42+
assertThat(metadata).has(Metadata.withProperty("inheritance.nest.int-value"));
43+
assertThat(metadata).has(Metadata.withProperty("inheritance.child-nest.bool-value"));
44+
assertThat(metadata).has(Metadata.withProperty("inheritance.child-nest.int-value"));
45+
}
46+
47+
@Test
48+
void overrideChildProperties() throws Exception {
49+
ConfigurationMetadata metadata = compile(OverrideChildPropertiesConfig.class);
50+
assertThat(metadata).has(Metadata.withGroup("inheritance").fromSource(OverrideChildPropertiesConfig.class));
51+
assertThat(metadata).has(Metadata.withGroup("inheritance.nest").fromSource(OverrideChildProperties.class));
52+
assertThat(metadata).has(Metadata.withProperty("inheritance.bool-value"));
53+
assertThat(metadata).has(Metadata.withProperty("inheritance.int-value"));
54+
assertThat(metadata).has(Metadata.withProperty("inheritance.long-value"));
55+
assertThat(metadata).has(Metadata.withProperty("inheritance.nest.bool-value"));
56+
assertThat(metadata).has(Metadata.withProperty("inheritance.nest.int-value"));
57+
assertThat(metadata).has(Metadata.withProperty("inheritance.nest.long-value"));
58+
59+
}
60+
61+
}

spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/test/TestConfigurationMetadataAnnotationProcessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -127,8 +127,8 @@ protected String nameAnnotation() {
127127
}
128128

129129
@Override
130-
protected ConfigurationMetadata writeMetaData() throws Exception {
131-
super.writeMetaData();
130+
protected ConfigurationMetadata writeMetadata() throws Exception {
131+
super.writeMetadata();
132132
try {
133133
File metadataFile = new File(this.outputLocation, "META-INF/spring-configuration-metadata.json");
134134
if (metadataFile.isFile()) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2012-2022 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.boot.configurationsample.inheritance;
18+
19+
public class BaseProperties {
20+
21+
private boolean boolValue;
22+
23+
private int intValue;
24+
25+
private final Nest nest = new Nest();
26+
27+
public boolean isBoolValue() {
28+
return this.boolValue;
29+
}
30+
31+
public void setBoolValue(boolean boolValue) {
32+
this.boolValue = boolValue;
33+
}
34+
35+
public int getIntValue() {
36+
return this.intValue;
37+
}
38+
39+
public void setIntValue(int intValue) {
40+
this.intValue = intValue;
41+
}
42+
43+
public Nest getNest() {
44+
return this.nest;
45+
}
46+
47+
public static class Nest {
48+
49+
private boolean boolValue;
50+
51+
private int intValue;
52+
53+
public boolean isBoolValue() {
54+
return this.boolValue;
55+
}
56+
57+
public void setBoolValue(boolean boolValue) {
58+
this.boolValue = boolValue;
59+
}
60+
61+
public int getIntValue() {
62+
return this.intValue;
63+
}
64+
65+
public void setIntValue(int intValue) {
66+
this.intValue = intValue;
67+
}
68+
69+
}
70+
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2012-2022 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.boot.configurationsample.inheritance;
18+
19+
public class ChildProperties extends BaseProperties {
20+
21+
private long longValue;
22+
23+
private final NestInChild childNest = new NestInChild();
24+
25+
public long getLongValue() {
26+
return this.longValue;
27+
}
28+
29+
public void setLongValue(long longValue) {
30+
this.longValue = longValue;
31+
}
32+
33+
public NestInChild getChildNest() {
34+
return this.childNest;
35+
}
36+
37+
public static class NestInChild {
38+
39+
private boolean boolValue;
40+
41+
private int intValue;
42+
43+
public boolean isBoolValue() {
44+
return this.boolValue;
45+
}
46+
47+
public void setBoolValue(boolean boolValue) {
48+
this.boolValue = boolValue;
49+
}
50+
51+
public int getIntValue() {
52+
return this.intValue;
53+
}
54+
55+
public void setIntValue(int intValue) {
56+
this.intValue = intValue;
57+
}
58+
59+
}
60+
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2012-2022 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.boot.configurationsample.inheritance;
18+
19+
import org.springframework.boot.configurationsample.ConfigurationProperties;
20+
21+
public class ChildPropertiesConfig {
22+
23+
@ConfigurationProperties(prefix = "inheritance")
24+
public ChildProperties childConfig() {
25+
return new ChildProperties();
26+
}
27+
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.springframework.boot.configurationsample.inheritance;
2+
3+
public class OverrideChildProperties extends BaseProperties {
4+
5+
private long longValue;
6+
7+
private final CustomNest nest = new CustomNest();
8+
9+
public long getLongValue() {
10+
return this.longValue;
11+
}
12+
13+
public void setLongValue(long longValue) {
14+
this.longValue = longValue;
15+
}
16+
17+
@Override
18+
public CustomNest getNest() {
19+
return this.nest;
20+
}
21+
22+
public static class CustomNest extends Nest {
23+
24+
private long longValue;
25+
26+
public long getLongValue() {
27+
return this.longValue;
28+
}
29+
30+
public void setLongValue(long longValue) {
31+
this.longValue = longValue;
32+
}
33+
34+
}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2012-2022 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.boot.configurationsample.inheritance;
18+
19+
import org.springframework.boot.configurationsample.ConfigurationProperties;
20+
21+
public class OverrideChildPropertiesConfig {
22+
23+
@ConfigurationProperties(prefix = "inheritance")
24+
public OverrideChildProperties overrideChildProperties() {
25+
return new OverrideChildProperties();
26+
}
27+
28+
}

0 commit comments

Comments
 (0)