eb3de5fbc8693443c21c609db8c98684a7272004
[JavaForFun] /
1 package de.example.custom.java.checks;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
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;
18
19 import com.google.common.collect.ImmutableList;
20
21 @Rule(key = "GUJ0002")
22 public class SpringServiceInstanceFieldCheck extends IssuableSubscriptionVisitor {
23         private static final Logger LOG = Loggers.get(SpringServiceInstanceFieldCheck.class);
24
25         private final List<VariableTree> issuableVariables = new ArrayList<>();
26
27         private boolean isSpringService = false;
28
29         @Override
30         public void scanFile(JavaFileScannerContext context) {
31                 if (context.getSemanticModel() == null) {
32                         return;
33                 }
34                 super.scanFile(context);
35
36                 if (this.isSpringService) {
37                         reportIssuesOnVariable();
38                 }
39         }
40
41         @Override
42         public List<Kind> nodesToVisit() {
43                 return ImmutableList.of(Kind.CLASS, Kind.VARIABLE);
44         }
45
46         @Override
47         public void visitNode(Tree tree) {
48
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);
56                         }
57                 }
58
59         }
60
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")) {
64                         return true;
65                 }
66
67                 return false;
68         }
69
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")) {
73                         return true;
74                 }
75
76                 return false;
77         }
78
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);
83         }
84
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\"");
89                 }
90                 issuableVariables.clear();
91         }
92
93 }