Only flag @RequestMapping with single request method

This commit is contained in:
aboyko
2023-08-31 13:37:31 -04:00
parent 4093a0e1bc
commit 5b49715dd7
2 changed files with 113 additions and 9 deletions

View File

@@ -17,9 +17,11 @@ import java.util.List;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
@@ -90,13 +92,33 @@ public class NoRequestMappingAnnotationReconciler implements JdtAstReconciler {
}
private static boolean isRequestMappingAnnotation(CompilationUnit cu, Annotation a) {
String typeName = a.getTypeName().getFullyQualifiedName();
if (Annotations.SPRING_REQUEST_MAPPING.equals(typeName)) {
return true;
} else if (typeName.endsWith("RequestMapping")) {
ITypeBinding type = a.resolveTypeBinding();
if (type != null && Annotations.SPRING_REQUEST_MAPPING.equals(type.getQualifiedName())) {
return true;
// Consider only NormalAnnotation as we need to flag @RequestMapping with single method parameter value
if (a.isNormalAnnotation()) {
String typeName = a.getTypeName().getFullyQualifiedName();
if (Annotations.SPRING_REQUEST_MAPPING.equals(typeName)) {
return hasApplicableMethodParameter(a);
} else if (typeName.endsWith("RequestMapping")) {
ITypeBinding type = a.resolveTypeBinding();
if (type != null && Annotations.SPRING_REQUEST_MAPPING.equals(type.getQualifiedName())) {
return hasApplicableMethodParameter(a);
}
}
}
return false;
}
private static boolean hasApplicableMethodParameter(Annotation a) {
if (a.isNormalAnnotation()) {
for (Object o : ((NormalAnnotation) a).values()) {
if (o instanceof MemberValuePair) {
MemberValuePair pair = (MemberValuePair) o;
if ("method".equals(pair.getName().getIdentifier())) {
if (pair.getValue() instanceof ArrayInitializer) {
return ((ArrayInitializer) pair.getValue()).expressions().size() == 1;
}
return true;
}
}
}
}
return false;

View File

@@ -56,12 +56,13 @@ public class NoRequestMappingAnnotationReconcilerTest extends BaseReconcilerTest
package example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/hello")
class A {
@RequestMapping("/1")
@RequestMapping(value = "/1", method = RequestMethod.GET)
String hello1() {
return "1";
};
@@ -77,12 +78,93 @@ public class NoRequestMappingAnnotationReconcilerTest extends BaseReconcilerTest
assertEquals(Boot2JavaProblemType.JAVA_PRECISE_REQUEST_MAPPING, problem.getType());
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
assertEquals("@RequestMapping(\"/1\")", markedStr);
assertEquals("@RequestMapping(value = \"/1\", method = RequestMethod.GET)", markedStr);
assertEquals(2, problem.getQuickfixes().size());
}
@Test
void arrayMethodTest() throws Exception {
String source = """
package example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/hello")
class A {
@RequestMapping(value = "/1", method = { RequestMethod.GET })
String hello1() {
return "1";
};
}
""";
List<ReconcileProblem> problems = reconcile("A.java", source, false);
assertEquals(1, problems.size());
ReconcileProblem problem = problems.get(0);
assertEquals(Boot2JavaProblemType.JAVA_PRECISE_REQUEST_MAPPING, problem.getType());
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
assertEquals("@RequestMapping(value = \"/1\", method = { RequestMethod.GET })", markedStr);
assertEquals(2, problem.getQuickfixes().size());
}
@Test
void multiMethodTest() throws Exception {
String source = """
package example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/hello")
class A {
@RequestMapping(value = "/1", method = { RequestMethod.GET, RequestMethod.HEAD })
String hello1() {
return "1";
};
}
""";
List<ReconcileProblem> problems = reconcile("A.java", source, false);
assertEquals(0, problems.size());
}
@Test
void noMethodsNoProblems() throws Exception {
String source = """
package example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/hello")
class A {
@RequestMapping("/1")
String hello1() {
return "1";
};
}
""";
List<ReconcileProblem> problems = reconcile("A.java", source, false);
assertEquals(0, problems.size());
}
@Test
void noProblems() throws Exception {
String source = """