From: Julien HENRY Date: Tue, 22 Jul 2014 13:09:38 +0000 (+0200) Subject: SONAR-5389 Allow to find an active rule by internal key X-Git-Tag: 4.5-RC1~429 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b436be2b5062426442dc76fac074c71062cc8da3;p=sonarqube.git SONAR-5389 Allow to find an active rule by internal key --- diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java index 545bacaa005..0c2c4a6356a 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java @@ -24,6 +24,7 @@ import org.apache.commons.lang.StringUtils; import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.CoreProperties; import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.internal.DefaultActiveRules; import org.sonar.api.config.Settings; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.rules.ActiveRule; @@ -76,7 +77,7 @@ public class RulesProfileProvider extends ProviderAdapter { // TODO deprecatedProfile.setVersion(qProfile.version()); deprecatedProfile.setName(qProfile.getName()); deprecatedProfile.setLanguage(qProfile.getLanguage()); - for (org.sonar.api.batch.rule.ActiveRule activeRule : activeRules.findByLanguage(qProfile.getLanguage())) { + for (org.sonar.api.batch.rule.ActiveRule activeRule : ((DefaultActiveRules) activeRules).findByLanguage(qProfile.getLanguage())) { Rule rule = ruleFinder.findByKey(activeRule.ruleKey()); ActiveRule deprecatedActiveRule = deprecatedProfile.activateRule(rule, RulePriority.valueOf(activeRule.severity())); for (Map.Entry param : activeRule.params().entrySet()) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java index e0536f66d43..3fec3ccb251 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java @@ -45,7 +45,7 @@ public class IssuesMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", "MAJOR", "xoo", "xoo")) + .activateRule(new ActiveRule("xoo", "OneIssuePerLine", "MAJOR", "OneIssuePerLine.internal", "xoo")) .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @@ -70,6 +70,18 @@ public class IssuesMediumTest { assertThat(result.issues()).hasSize(24); } + @Test + public void findActiveRuleByInternalKey() throws Exception { + File projectDir = new File(IssuesMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + + TaskResult result = tester + .newScanTask(new File(projectDir, "sonar-project.properties")) + .property("sonar.xoo.internalKey", "OneIssuePerLine.internal") + .start(); + + assertThat(result.issues()).hasSize(24 /* 24 lines */+ 3 /* 3 files */); + } + @Test public void testOverrideQProfileSeverity() throws Exception { File projectDir = new File(IssuesMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java index 37abfffed29..f281ea09899 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java @@ -23,6 +23,7 @@ import org.sonar.api.SonarPlugin; import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo; import org.sonar.batch.mediumtest.xoo.plugin.lang.MeasureSensor; import org.sonar.batch.mediumtest.xoo.plugin.lang.ScmActivitySensor; +import org.sonar.batch.mediumtest.xoo.plugin.rule.CreateIssueByInternalKeySensor; import org.sonar.batch.mediumtest.xoo.plugin.rule.OneIssueOnDirPerFileSensor; import org.sonar.batch.mediumtest.xoo.plugin.rule.OneIssuePerLineSensor; @@ -39,9 +40,10 @@ public final class XooPlugin extends SonarPlugin { ScmActivitySensor.class, Xoo.class, - // rules + // sensors OneIssuePerLineSensor.class, - OneIssueOnDirPerFileSensor.class + OneIssueOnDirPerFileSensor.class, + CreateIssueByInternalKeySensor.class ); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/rule/CreateIssueByInternalKeySensor.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/rule/CreateIssueByInternalKeySensor.java new file mode 100644 index 00000000000..1ee150a5c01 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/rule/CreateIssueByInternalKeySensor.java @@ -0,0 +1,60 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.mediumtest.xoo.plugin.rule; + +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.rule.ActiveRule; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo; +import org.sonar.batch.mediumtest.xoo.plugin.base.XooConstants; + +public class CreateIssueByInternalKeySensor implements Sensor { + + private static final String INTERNAL_KEY_PROPERTY = "sonar.xoo.internalKey"; + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor + .name("CreateIssueByInternalKeySensor") + .workOnLanguages(Xoo.KEY) + .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST); + } + + @Override + public void execute(SensorContext context) { + for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) { + createIssues(file, context); + } + } + + private void createIssues(InputFile file, SensorContext context) { + ActiveRule rule = context.activeRules().findByInternalKey(XooConstants.REPOSITORY_KEY, + context.settings().getString(INTERNAL_KEY_PROPERTY)); + if (rule != null) { + context.addIssue(context.issueBuilder() + .ruleKey(rule.ruleKey()) + .onFile(file) + .message("This issue is generated on each file") + .build()); + } + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRules.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRules.java index 17a885f0677..20a2fb19a4e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRules.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRules.java @@ -23,6 +23,7 @@ import org.sonar.api.BatchComponent; import org.sonar.api.rule.RuleKey; import javax.annotation.CheckForNull; + import java.util.Collection; /** @@ -56,7 +57,17 @@ public interface ActiveRules extends BatchComponent { /** * The active rules for a given language, like java + * @deprecated since 4.5 Not sure rules will continue to be linked to a language */ + @Deprecated Collection findByLanguage(String language); + /** + * Find a {@link ActiveRule} by the associated internal key. null + * is returned if the rule does not exist or if the rule is not activated + * on any Quality profile associated with the module. + */ + @CheckForNull + ActiveRule findByInternalKey(String repository, String internalKey); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java index 86807ff737f..91b5cafda55 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java @@ -21,20 +21,23 @@ package org.sonar.api.batch.rule.internal; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ListMultimap; -import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.rule.ActiveRule; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.rule.RuleKey; import javax.annotation.concurrent.Immutable; + import java.util.Collection; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @Immutable -class DefaultActiveRules implements ActiveRules { +public class DefaultActiveRules implements ActiveRules { // TODO use disk-backed cache (persistit) instead of full in-memory cache ? private final ListMultimap activeRulesByRepository; + private final Map> activeRulesByRepositoryAndKey = new HashMap>(); + private final Map> activeRulesByRepositoryAndInternalKey = new HashMap>(); private final ListMultimap activeRulesByLanguage; public DefaultActiveRules(Collection newActiveRules) { @@ -43,9 +46,18 @@ class DefaultActiveRules implements ActiveRules { for (NewActiveRule newAR : newActiveRules) { DefaultActiveRule ar = new DefaultActiveRule(newAR); repoBuilder.put(ar.ruleKey().repository(), ar); - if (ar.language()!=null) { + if (ar.language() != null) { langBuilder.put(ar.language(), ar); } + if (!activeRulesByRepositoryAndKey.containsKey(ar.ruleKey().repository())) { + activeRulesByRepositoryAndKey.put(ar.ruleKey().repository(), new HashMap()); + activeRulesByRepositoryAndInternalKey.put(ar.ruleKey().repository(), new HashMap()); + } + activeRulesByRepositoryAndKey.get(ar.ruleKey().repository()).put(ar.ruleKey().rule(), ar); + String internalKey = ar.internalKey(); + if (internalKey != null) { + activeRulesByRepositoryAndInternalKey.get(ar.ruleKey().repository()).put(internalKey, ar); + } } activeRulesByRepository = repoBuilder.build(); activeRulesByLanguage = langBuilder.build(); @@ -53,13 +65,7 @@ class DefaultActiveRules implements ActiveRules { @Override public ActiveRule find(RuleKey ruleKey) { - List rules = activeRulesByRepository.get(ruleKey.repository()); - for (ActiveRule rule : rules) { - if (StringUtils.equals(rule.ruleKey().rule(), ruleKey.rule())) { - return rule; - } - } - return null; + return activeRulesByRepositoryAndKey.containsKey(ruleKey.repository()) ? activeRulesByRepositoryAndKey.get(ruleKey.repository()).get(ruleKey.rule()) : null; } @Override @@ -76,4 +82,9 @@ class DefaultActiveRules implements ActiveRules { public Collection findByLanguage(String language) { return activeRulesByLanguage.get(language); } + + @Override + public ActiveRule findByInternalKey(String repository, String internalKey) { + return activeRulesByRepositoryAndInternalKey.containsKey(repository) ? activeRulesByRepositoryAndInternalKey.get(repository).get(internalKey) : null; + } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java index c308024616f..584b1ea7663 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java @@ -52,6 +52,7 @@ public class ActiveRulesBuilderTest { assertThat(activeRules.findAll()).hasSize(3); assertThat(activeRules.findByRepository("squid")).hasSize(2); assertThat(activeRules.findByRepository("findbugs")).hasSize(1); + assertThat(activeRules.findByInternalKey("squid", "__S0001__")).isNotNull(); assertThat(activeRules.findByRepository("unknown")).isEmpty(); ActiveRule squid1 = activeRules.find(RuleKey.of("squid", "S0001"));