Skip to content

Commit de1ee94

Browse files
committed
[draft] Remove Spring annotations if they repeating in subclasses
1 parent cf3870d commit de1ee94

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Moderne Source Available License (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://docs.moderne.io/licensing/moderne-source-available-license
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;
17+
18+
import org.openrewrite.ExecutionContext;
19+
import org.openrewrite.Preconditions;
20+
import org.openrewrite.Recipe;
21+
import org.openrewrite.TreeVisitor;
22+
import org.openrewrite.java.JavaIsoVisitor;
23+
import org.openrewrite.java.search.UsesType;
24+
import org.openrewrite.java.tree.J;
25+
26+
public class NotRepeatSpringAnnotationsInSubclasses extends Recipe {
27+
28+
@Override
29+
public String getDisplayName() {
30+
return "Remove Spring annotations if they repeating in subclasses";
31+
}
32+
33+
@Override
34+
public String getDescription() {
35+
return "Remove Spring annotations if they repeating in subclasses.";
36+
}
37+
38+
@Override
39+
public TreeVisitor<?, ExecutionContext> getVisitor() {
40+
return Preconditions.check(new UsesType<>("org.springframework.web.bind.annotation.PostMapping", false), new JavaIsoVisitor<ExecutionContext>() {
41+
@Override
42+
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
43+
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx);
44+
return cd;
45+
}
46+
47+
@Override
48+
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext executionContext) {
49+
return super.visitMethodDeclaration(method, executionContext);
50+
}
51+
});
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
* <p>
4+
* Licensed under the Moderne Source Available License (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://docs.moderne.io/licensing/moderne-source-available-license
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;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.openrewrite.java.JavaParser;
20+
import org.openrewrite.test.RecipeSpec;
21+
import org.openrewrite.test.RewriteTest;
22+
23+
import static org.openrewrite.java.Assertions.java;
24+
25+
class NotRepeatSpringAnnotationsInSubclassesTest implements RewriteTest {
26+
27+
@Override
28+
public void defaults(RecipeSpec spec) {
29+
spec.recipe(new NotRepeatSpringAnnotationsInSubclasses())
30+
.parser(JavaParser.fromJavaVersion().classpath("spring-beans", "spring-boot",
31+
"spring-context", "spring-core", "spring-web"));
32+
}
33+
34+
@Test
35+
void removeLeadingAutowiredAnnotation() {
36+
//language=java
37+
rewriteRun(
38+
java(
39+
"""
40+
import org.springframework.web.bind.annotation.PathVariable;
41+
import org.springframework.web.bind.annotation.PostMapping;
42+
import org.springframework.web.bind.annotation.RequestBody;
43+
44+
public interface UserApi {
45+
46+
@PostMapping("/users/{id}")
47+
String updateUser(
48+
@PathVariable("id") Long id,
49+
@RequestBody UserData request
50+
);
51+
52+
class UserData {
53+
private String firstName;
54+
private String lastName;
55+
56+
public String getFirstName() {return firstName;}
57+
58+
public void setFirstName(String firstName) {
59+
this.firstName = firstName;
60+
}
61+
62+
public String getLastName() {
63+
return lastName;
64+
}
65+
66+
public void setLastName(String lastName) {
67+
this.lastName = lastName;
68+
}
69+
}
70+
}
71+
"""),
72+
java(
73+
"""
74+
import org.springframework.web.bind.annotation.PathVariable;
75+
import org.springframework.web.bind.annotation.PostMapping;
76+
import org.springframework.web.bind.annotation.RequestBody;
77+
import org.springframework.web.bind.annotation.RestController;
78+
79+
@RestController
80+
public class UserController implements UserApi {
81+
82+
@PostMapping("/users/{id}")
83+
String updateUser(
84+
@PathVariable("id") Long id,
85+
@RequestBody UserData request
86+
) {
87+
return "User " + id + " updated: " + request.getFirstName() + " " + request.getLastName();
88+
}
89+
}
90+
""",
91+
"""
92+
import org.springframework.web.bind.annotation.RestController;
93+
94+
@RestController
95+
public class UserController implements UserApi {
96+
97+
@Override
98+
public String updateUser(Long id, UserData request) {
99+
return "User " + id + " updated: " + request.getFirstName() + " " + request.getLastName();
100+
}
101+
}
102+
"""
103+
)
104+
);
105+
}
106+
}

0 commit comments

Comments
 (0)