</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>
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;
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) {
}
- 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);
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;
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;
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);
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);