sonar Java plugin: multiple improvements
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 21 Aug 2016 16:33:13 +0000 (18:33 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 21 Aug 2016 16:33:13 +0000 (18:33 +0200)
Sonar/Plugins/sonar-custom-java-plugin/pom.xml
Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/SpringServiceInstanceFieldCheck.java
Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomRulesDefinition.java

index 2514114..7f222a8 100644 (file)
   </properties>
 
   <dependencies>
-    <dependency>
-      <groupId>org.sonarsource.sonarqube</groupId>
-      <artifactId>sonar-plugin-api</artifactId>
-      <version>${sonar.apiVersion}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.sonarsource.java</groupId>
-      <artifactId>sonar-java-plugin</artifactId>
-      <type>sonar-plugin</type>
-      <version>${java.plugin.version}</version>
-      <scope>provided</scope>
-    </dependency>
+       <dependency>
+               <groupId>org.sonarsource.sonarqube</groupId>
+               <artifactId>sonar-plugin-api</artifactId>
+               <version>${sonar.apiVersion}</version>
+               <scope>provided</scope>
+       </dependency>
+       <dependency>
+               <groupId>org.sonarsource.java</groupId>
+               <artifactId>sonar-java-plugin</artifactId>
+               <type>sonar-plugin</type>
+               <version>${java.plugin.version}</version>
+               <scope>provided</scope>
+               <exclusions>
+                       <!-- We are already using our required guava version -->
+                       <exclusion>
+                               <groupId>com.google.guava</groupId>
+                               <artifactId>guava</artifactId>
+                       </exclusion>
+               </exclusions>
+       </dependency>
+       <dependency>
+           <groupId>org.sonarsource.sslr-squid-bridge</groupId>
+           <artifactId>sslr-squid-bridge</artifactId>
+           <version>2.6.1</version>
+           <exclusions>
+               <!-- We are already using our required guava version -->
+               <exclusion>
+                       <groupId>com.google.guava</groupId>
+                       <artifactId>guava</artifactId>
+               </exclusion>
+            </exclusions>
+       </dependency>
       <dependency>
         <groupId>com.google.code.gson</groupId>
         <artifactId>gson</artifactId>
         <version>2.6.2</version>
-        <scope>compile</scope>
       </dependency>
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
       <version>19.0</version>
     </dependency>
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>2.6</version>
-    </dependency>
-
-          <dependency>
-      <groupId>org.sonarsource.java</groupId>
-      <artifactId>java-frontend</artifactId>
-      <version>${java.plugin.version}</version>
-    </dependency>
       
     
 
index eb3de5f..a5f23e6 100644 (file)
@@ -6,6 +6,7 @@ import java.util.List;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
 import org.sonar.java.model.ModifiersUtils;
 import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
 import org.sonar.plugins.java.api.JavaFileScannerContext;
@@ -16,15 +17,24 @@ import org.sonar.plugins.java.api.tree.Tree;
 import org.sonar.plugins.java.api.tree.Tree.Kind;
 import org.sonar.plugins.java.api.tree.VariableTree;
 
+import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 
 @Rule(key = "GUJ0002")
 public class SpringServiceInstanceFieldCheck extends IssuableSubscriptionVisitor {
        private static final Logger LOG = Loggers.get(SpringServiceInstanceFieldCheck.class);
+       private static final Splitter ANNOTATIONS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
+       private static final String DEFAULT = "javax.inject.Named, org.springframework.stereotype.Service";
 
        private final List<VariableTree> issuableVariables = new ArrayList<>();
 
        private boolean isSpringService = false;
+       
+       @RuleProperty(
+               key = "annotations",
+               description = "Annotations to be checked. Multiple values comma separated.",
+               defaultValue = "" + DEFAULT)
+       public String annotations = DEFAULT;
 
        @Override
        public void scanFile(JavaFileScannerContext context) {
@@ -58,25 +68,29 @@ public class SpringServiceInstanceFieldCheck extends IssuableSubscriptionVisitor
 
        }
 
-       private static boolean isOwnedByASpringService(VariableTree variable) {
-               if (variable.symbol().owner().metadata().isAnnotatedWith("javax.inject.Named") ||
-                               variable.symbol().owner().metadata().isAnnotatedWith("org.springframework.stereotype.Service")) {
-                       return true;
+       private boolean isOwnedByASpringService(VariableTree variable) {
+               List<String> annotationsToBeChecked = ANNOTATIONS_SPLITTER.splitToList(annotations);
+               for (String annotation : annotationsToBeChecked) {
+                       if (variable.symbol().owner().metadata().isAnnotatedWith(annotation)) {
+                               return true;
+                       }
                }
 
                return false;
        }
 
-       private static boolean isSpringService(ClassTree tree) {
-               if (tree.symbol().metadata().isAnnotatedWith("javax.inject.Named") ||
-                               tree.symbol().metadata().isAnnotatedWith("org.springframework.stereotype.Service")) {
-                       return true;
+       private boolean isSpringService(ClassTree tree) {
+               List<String> annotationsToBeChecked = ANNOTATIONS_SPLITTER.splitToList(annotations);
+               for (String annotation : annotationsToBeChecked) {
+                       if (tree.symbol().metadata().isAnnotatedWith(annotation)) {
+                               return true;
+                       }
                }
 
                return false;
        }
 
-       private static boolean isStaticOrFinal(VariableTree variable) {
+       private boolean isStaticOrFinal(VariableTree variable) {
                ModifiersTree modifiers = variable.modifiers();
                return ModifiersUtils.hasModifier(modifiers, Modifier.STATIC)
                                || ModifiersUtils.hasModifier(modifiers, Modifier.FINAL);
index ac2faf0..bcb4f95 100644 (file)
@@ -6,7 +6,6 @@ import java.util.List;
 
 import javax.annotation.Nullable;
 
-import org.apache.commons.lang.StringUtils;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.rule.RulesDefinition;
@@ -17,6 +16,7 @@ import org.sonar.squidbridge.annotations.RuleTemplate;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
 import com.google.common.collect.Iterables;
 import com.google.common.io.Resources;
 import com.google.gson.Gson;
@@ -52,7 +52,7 @@ public class CustomRulesDefinition implements RulesDefinition {
       throw new IllegalArgumentException("No Rule annotation was found on " + ruleClass);
     }
     String ruleKey = ruleAnnotation.key();
-    if (StringUtils.isEmpty(ruleKey)) {
+    if (Strings.isNullOrEmpty(ruleKey)) {
       throw new IllegalArgumentException("No key is defined in Rule annotation of " + ruleClass);
     }
     NewRule rule = repository.rule(ruleKey);
@@ -67,11 +67,6 @@ public class CustomRulesDefinition implements RulesDefinition {
 
   private void ruleMetadata(Class<?> ruleClass, NewRule rule) {
     String metadataKey = rule.key();
-    org.sonar.java.RspecKey rspecKeyAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.java.RspecKey.class);
-    if (rspecKeyAnnotation != null) {
-      metadataKey = rspecKeyAnnotation.value();
-      rule.setInternalKey(metadataKey);
-    }
     addHtmlDescription(rule, metadataKey);
     addMetadata(rule, metadataKey);