Skip to content

Commit 5a37e8e

Browse files
BoykoAlexpway99
authored andcommitted
Boot 3: Remove @ConstructorBinding annotation on @ConfigurationProperties type
1 parent 830733f commit 5a37e8e

File tree

2 files changed

+279
-0
lines changed

2 files changed

+279
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
* <p>
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+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
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+
package org.openrewrite.java.spring.boot3;
17+
18+
import org.openrewrite.ExecutionContext;
19+
import org.openrewrite.Recipe;
20+
import org.openrewrite.internal.ListUtils;
21+
import org.openrewrite.java.JavaIsoVisitor;
22+
import org.openrewrite.java.tree.J;
23+
import org.openrewrite.java.tree.JavaType;
24+
import org.openrewrite.java.tree.TypeUtils;
25+
26+
/**
27+
* @author Alex Boyko
28+
*/
29+
public class RemoveConstructorBindingAnnotation extends Recipe {
30+
31+
private static final String ANNOTATION_CONSTRUCTOR_BINDING = "org.springframework.boot.context.properties.ConstructorBinding";
32+
private static final String ANNOTATION_CONFIG_PROPERTIES = "org.springframework.boot.context.properties.ConfigurationProperties";
33+
34+
@Override
35+
public String getDisplayName() {
36+
return "Remove Unnecessary @ConstructorBinding";
37+
}
38+
39+
@Override
40+
public String getDescription() {
41+
return "As of Boot 3.0 @ConstructorBinding is no longer needed at the type level on @ConfigurationProperties classes and should be removed.";
42+
}
43+
44+
@Override
45+
public JavaIsoVisitor<ExecutionContext> getVisitor() {
46+
return new JavaIsoVisitor<ExecutionContext>() {
47+
@Override
48+
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext context) {
49+
boolean isConfigPropsAnnotationPresent = classDecl.getLeadingAnnotations().stream().filter(a -> {
50+
JavaType.FullyQualified fqType = TypeUtils.asFullyQualified(a.getType());
51+
if (fqType != null && ANNOTATION_CONFIG_PROPERTIES.equals(fqType.getFullyQualifiedName())) {
52+
return true;
53+
}
54+
return false;
55+
}).findFirst().isPresent();
56+
J.ClassDeclaration c = super.visitClassDeclaration(classDecl, context);
57+
if (isConfigPropsAnnotationPresent) {
58+
c = c.withLeadingAnnotations(ListUtils.map(c.getLeadingAnnotations(), anno -> {
59+
if (TypeUtils.isOfClassType(anno.getType(), ANNOTATION_CONSTRUCTOR_BINDING)) {
60+
maybeRemoveImport(ANNOTATION_CONSTRUCTOR_BINDING);
61+
return null;
62+
}
63+
return anno;
64+
}));
65+
}
66+
return c;
67+
}
68+
};
69+
}
70+
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
* <p>
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+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
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+
package org.openrewrite.java.spring.boot3
17+
18+
import org.junit.jupiter.api.Test
19+
import org.openrewrite.Recipe
20+
import org.openrewrite.java.JavaParser
21+
import org.openrewrite.java.JavaRecipeTest
22+
23+
/**
24+
* @author Alex Boyko
25+
*/
26+
class RemoveConstructorBindingAnnotationTest : JavaRecipeTest {
27+
28+
override val parser: JavaParser
29+
get() = JavaParser.fromJavaVersion()
30+
.logCompilationWarningsAndErrors(true)
31+
.classpath("spring-boot")
32+
.build()
33+
34+
override val recipe: Recipe
35+
get() = RemoveConstructorBindingAnnotation()
36+
37+
38+
@Test
39+
fun topLevelTypeAnnotation() = assertChanged(
40+
before = """
41+
import org.springframework.boot.context.properties.ConfigurationProperties;
42+
import org.springframework.boot.context.properties.ConstructorBinding;
43+
44+
@ConfigurationProperties
45+
@ConstructorBinding
46+
class A {
47+
void method() {
48+
}
49+
}
50+
""",
51+
after = """
52+
import org.springframework.boot.context.properties.ConfigurationProperties;
53+
54+
@ConfigurationProperties
55+
class A {
56+
void method() {
57+
}
58+
}
59+
"""
60+
)
61+
62+
@Test
63+
fun constructorAnnotation() = assertUnchanged(
64+
before = """
65+
import org.springframework.boot.context.properties.ConfigurationProperties;
66+
import org.springframework.boot.context.properties.ConstructorBinding;
67+
68+
@ConfigurationProperties
69+
class A {
70+
@ConstructorBinding
71+
A() {
72+
}
73+
}
74+
"""
75+
)
76+
77+
@Test
78+
fun topLevelTypeAnnotationWithoutConfigProperties() = assertUnchanged(
79+
before = """
80+
import org.springframework.boot.context.properties.ConstructorBinding;
81+
82+
@ConstructorBinding
83+
class A {
84+
}
85+
"""
86+
)
87+
88+
@Test
89+
fun constructorAnnotationWithMultipleConstructors() = assertUnchanged(
90+
before = """
91+
import org.springframework.boot.context.properties.ConfigurationProperties;
92+
import org.springframework.boot.context.properties.ConstructorBinding;
93+
94+
@ConfigurationProperties
95+
class A {
96+
A() {
97+
}
98+
@ConstructorBinding
99+
A(int n) {
100+
}
101+
}
102+
"""
103+
)
104+
105+
@Test
106+
fun noConstrBindingAnnotation() = assertUnchanged(
107+
before = """
108+
import org.springframework.boot.context.properties.ConfigurationProperties;
109+
110+
@ConfigurationProperties
111+
class A {
112+
A() {
113+
}
114+
A(int n) {
115+
}
116+
}
117+
"""
118+
)
119+
120+
@Test
121+
fun topLevelTypeAnnotationInnerClass() = assertChanged(
122+
before = """
123+
import org.springframework.boot.context.properties.ConfigurationProperties;
124+
import org.springframework.boot.context.properties.ConstructorBinding;
125+
126+
class A {
127+
void method() {
128+
}
129+
130+
@ConfigurationProperties
131+
@ConstructorBinding
132+
static class B {
133+
}
134+
}
135+
""",
136+
after = """
137+
import org.springframework.boot.context.properties.ConfigurationProperties;
138+
139+
class A {
140+
void method() {
141+
}
142+
143+
@ConfigurationProperties
144+
static class B {
145+
}
146+
}
147+
"""
148+
)
149+
150+
@Test
151+
fun constructorAnnotationInnerClass() = assertChanged(
152+
before = """
153+
import org.springframework.boot.context.properties.ConfigurationProperties;
154+
import org.springframework.boot.context.properties.ConstructorBinding;
155+
156+
@ConfigurationProperties
157+
@ConstructorBinding
158+
class A {
159+
void method() {
160+
}
161+
162+
@ConfigurationProperties
163+
static class B {
164+
@ConstructorBinding
165+
B() {
166+
}
167+
}
168+
}
169+
""",
170+
after = """
171+
import org.springframework.boot.context.properties.ConfigurationProperties;
172+
import org.springframework.boot.context.properties.ConstructorBinding;
173+
174+
@ConfigurationProperties
175+
class A {
176+
void method() {
177+
}
178+
179+
@ConfigurationProperties
180+
static class B {
181+
@ConstructorBinding
182+
B() {
183+
}
184+
}
185+
}
186+
"""
187+
)
188+
189+
@Test
190+
fun constructorAndTypeAnnotationWithMultipleConstructorsInnerClass() = assertUnchanged(
191+
before = """
192+
import org.springframework.boot.context.properties.ConfigurationProperties;
193+
import org.springframework.boot.context.properties.ConstructorBinding;
194+
195+
class A {
196+
@ConfigurationProperties
197+
static class B {
198+
B() {
199+
}
200+
@ConstructorBinding
201+
B(int n) {
202+
}
203+
}
204+
}
205+
"""
206+
)
207+
208+
}

0 commit comments

Comments
 (0)