Skip to content

Commit

Permalink
feat: Détection des annotations ManyToOne, OneToMany et ManyToMany da…
Browse files Browse the repository at this point in the history
…ns l'entité liée au Repository
  • Loading branch information
SamuelMartinCaps committed Apr 6, 2023
1 parent 6d70458 commit 029b379
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Optional;


import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.tree.*;

@Rule(key = "EC206",
Expand All @@ -23,6 +28,12 @@ public class AvoidNPlusOneQueryProblemCheck extends IssuableSubscriptionVisitor
private static final String LEFT_JOIN = "LEFT JOIN";
private static final String VALUE = "value";

private static final List<String> SPRING_PROBLEMATIC_ANNOTATIONS = List.of(
"javax.persistence.OneToMany",
"javax.persistence.ManyToOne",
"javax.persistence.ManyToMany"
);

private final AvoidNPlusOneQueryProblemCheckVisitor visitorInFile = new AvoidNPlusOneQueryProblemCheckVisitor();

@Override
Expand All @@ -32,11 +43,39 @@ public List<Tree.Kind> nodesToVisit() {

@Override
public void visitNode(Tree tree) {
if (((ClassTree) tree).symbol().type().isSubtypeOf(SPRING_REPOSITORY)) {
ClassTree classTree = (ClassTree) tree;

if (isSpringRepository(classTree) && hasManyToOneAnnotations(classTree)) {
tree.accept(visitorInFile);
}
}

private boolean hasManyToOneAnnotations(ClassTree classTree) {
Optional<Type> crudRepositoryInterface = classTree.symbol().interfaces().stream()
.filter(t -> t.isSubtypeOf(SPRING_REPOSITORY))
.findFirst();

return crudRepositoryInterface.map(type -> type
.typeArguments()
.get(0)
.symbol()
.declaration()
.members()
.stream()
.filter(t -> t.is(Tree.Kind.VARIABLE))
.anyMatch(t -> ((VariableTree) t).modifiers()
.annotations()
.stream()
.anyMatch(a ->
SPRING_PROBLEMATIC_ANNOTATIONS.stream().anyMatch(a.symbolType()::isSubtypeOf)
)))
.orElse(false);
}

private static boolean isSpringRepository(ClassTree classTree) {
return classTree.symbol().type().isSubtypeOf(SPRING_REPOSITORY);
}

private class AvoidNPlusOneQueryProblemCheckVisitor extends BaseTreeVisitor {

@Override
Expand Down
27 changes: 27 additions & 0 deletions java-plugin/src/test/files/AvoidNPlusOneQueryProblemBad.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import org.springframework.data.repository.CrudRepository;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.OneToMany;

public interface UserRepository extends CrudRepository<User, Long> {

Expand All @@ -12,6 +14,31 @@ public interface UserRepository extends CrudRepository<User, Long> {
List<User> findAllWithRoles();
}

@Entity
public class User {

@OneToMany
private List<Role> roles;

public List<Role> getRoles() {
return roles;
}

public void setRoles(List<Role> roles) {
this.roles = roles;
}
}

@Entity
public class Role {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.junit.jupiter.api.Test;
import org.sonar.java.checks.verifier.CheckVerifier;

class AvoidOnePlusOneQueryProblemTest {
class AvoidNPlusOneQueryProblemTest {

/**
* @formatter:off
Expand Down

0 comments on commit 029b379

Please sign in to comment.