1 package de.example.custom.java.checks;
3 import java.util.ArrayList;
6 import org.sonar.api.utils.log.Logger;
7 import org.sonar.api.utils.log.Loggers;
8 import org.sonar.check.Rule;
9 import org.sonar.java.model.ModifiersUtils;
10 import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
11 import org.sonar.plugins.java.api.JavaFileScannerContext;
12 import org.sonar.plugins.java.api.tree.ClassTree;
13 import org.sonar.plugins.java.api.tree.Modifier;
14 import org.sonar.plugins.java.api.tree.ModifiersTree;
15 import org.sonar.plugins.java.api.tree.Tree;
16 import org.sonar.plugins.java.api.tree.Tree.Kind;
17 import org.sonar.plugins.java.api.tree.VariableTree;
19 import com.google.common.collect.ImmutableList;
21 @Rule(key = "GUJ0002")
22 public class SpringServiceInstanceFieldCheck extends IssuableSubscriptionVisitor {
23 private static final Logger LOG = Loggers.get(SpringServiceInstanceFieldCheck.class);
25 private final List<VariableTree> issuableVariables = new ArrayList<>();
27 private boolean isSpringService = false;
30 public void scanFile(JavaFileScannerContext context) {
31 if (context.getSemanticModel() == null) {
34 super.scanFile(context);
36 if (this.isSpringService) {
37 reportIssuesOnVariable();
42 public List<Kind> nodesToVisit() {
43 return ImmutableList.of(Kind.CLASS, Kind.VARIABLE);
47 public void visitNode(Tree tree) {
49 if (tree.is(Kind.CLASS) && isSpringService((ClassTree) tree)) {
50 this.isSpringService = true;
51 } else if (tree.is(Kind.VARIABLE)) {
52 VariableTree variable = (VariableTree) tree;
53 isOwnedByASpringService(variable);
54 if (isOwnedByASpringService(variable) && !isStaticOrFinal(variable)) {
55 issuableVariables.add(variable);
61 private static boolean isOwnedByASpringService(VariableTree variable) {
62 if (variable.symbol().owner().metadata().isAnnotatedWith("javax.inject.Named") ||
63 variable.symbol().owner().metadata().isAnnotatedWith("org.springframework.stereotype.Service")) {
70 private static boolean isSpringService(ClassTree tree) {
71 if (tree.symbol().metadata().isAnnotatedWith("javax.inject.Named") ||
72 tree.symbol().metadata().isAnnotatedWith("org.springframework.stereotype.Service")) {
79 private static boolean isStaticOrFinal(VariableTree variable) {
80 ModifiersTree modifiers = variable.modifiers();
81 return ModifiersUtils.hasModifier(modifiers, Modifier.STATIC)
82 || ModifiersUtils.hasModifier(modifiers, Modifier.FINAL);
85 private void reportIssuesOnVariable() {
86 for (VariableTree variable : issuableVariables) {
87 reportIssue(variable.simpleName(),
88 "Remove this mutable service instance fields or make it \"static\" and/or \"final\"");
90 issuableVariables.clear();