diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-07-27 16:25:31 +0200 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-07-28 14:54:10 +0200 |
commit | b36bc464f98e0136d41e60774093aa946b207999 (patch) | |
tree | fabae7651b0705f3fd74144399e57350bc064565 | |
parent | 7cb72d02dc84f620447d80b96cd518d8b7f54e9a (diff) | |
download | sonarqube-b36bc464f98e0136d41e60774093aa946b207999.tar.gz sonarqube-b36bc464f98e0136d41e60774093aa946b207999.zip |
SONAR-6713 Load rules in global container
50 files changed, 771 insertions, 103 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index a0f9cfdb4e8..fdd9505fac0 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -105,4 +105,5 @@ public class XooPlugin extends SonarPlugin { XooProjectBuilder.class, XooPostJob.class); } + } diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java index b7d826a03a8..74f4e2a7fee 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java @@ -76,7 +76,13 @@ public class XooRulesDefinition implements RulesDefinition { repo.createRule(CustomMessageSensor.RULE_KEY).setName("Issue With Custom Message") .setHtmlDescription("Generate an issue on each file with a custom message"); + + repo.createRule(RandomAccessSensor.RULE_KEY).setName("One Issue Per File with Random Access") + .setHtmlDescription("This issue is generated on each file"); + repo.createRule(DeprecatedResourceApiSensor.RULE_KEY).setName("Issue created using deprecated API") + .setHtmlDescription("Issue created using deprecated API"); + repo.done(); } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java index 556ce27aa88..30e8a45261d 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java @@ -37,7 +37,7 @@ public class XooRulesDefinitionTest { assertThat(repo).isNotNull(); assertThat(repo.name()).isEqualTo("Xoo"); assertThat(repo.language()).isEqualTo("xoo"); - assertThat(repo.rules()).hasSize(8); + assertThat(repo.rules()).hasSize(10); RulesDefinition.Rule rule = repo.rule(OneIssuePerLineSensor.RULE_KEY); assertThat(rule.name()).isNotEmpty(); diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/Rule.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/Rule.java new file mode 100644 index 00000000000..e1574f1c6be --- /dev/null +++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/Rule.java @@ -0,0 +1,74 @@ +/* + * 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.protocol.input; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +public class Rule { + private final String key; + private final String repo; + private final String internalKey; + private final String name; + private final String severity; + private final String lang; + + public Rule(String ruleKey, String repositoryKey, String internalKey, String name, @Nullable String severity, @Nullable String language) { + this.key = ruleKey; + this.repo = repositoryKey; + this.internalKey = internalKey; + this.name = name; + this.severity = severity; + this.lang = language; + } + + public String ruleKey() { + return key; + } + + public String repositoryKey() { + return repo; + } + + public String internalKey() { + return internalKey; + } + + public String name() { + return name; + } + + /** + * Is null on manual rules + */ + @CheckForNull + public String severity() { + return severity; + } + + /** + * Is null on manual rules + */ + @CheckForNull + public String language() { + return lang; + } + +} diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/RulesSearchResult.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/RulesSearchResult.java new file mode 100644 index 00000000000..91dccb179f7 --- /dev/null +++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/RulesSearchResult.java @@ -0,0 +1,45 @@ +/* + * 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.protocol.input; + +import java.util.List; + +import org.sonar.batch.protocol.GsonHelper; + +public class RulesSearchResult { + List<Rule> rules; + + public List<Rule> getRules() { + return rules; + } + + public void setRules(List<Rule> rules) { + this.rules = rules; + } + + public String toJson() { + return GsonHelper.create().toJson(this); + } + + public static RulesSearchResult fromJson(String json) { + return GsonHelper.create().fromJson(json, RulesSearchResult.class); + } + +} diff --git a/sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/RulesSearchResultTest.java b/sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/RulesSearchResultTest.java new file mode 100644 index 00000000000..0455cc2eeb1 --- /dev/null +++ b/sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/RulesSearchResultTest.java @@ -0,0 +1,56 @@ +/* + * 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.protocol.input; + +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.net.URL; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.sonar.test.JsonAssert; +import org.assertj.core.util.Lists; +import org.junit.Test; + +public class RulesSearchResultTest { + @Test + public void testJsonParsing() { + Rule rule1 = new Rule("squid:S1194", "squid", "S1194", "\"java.lang.Error\" should not be extended", "MAJOR", "java"); + Rule rule2 = new Rule("squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck", "squid", "ObjectFinalizeOverridenCallsSuperFinalizeCheck", + "super.finalize() should be called at the end of Object.finalize() implementations", "BLOCKER", "java"); + + RulesSearchResult rules = new RulesSearchResult(); + rules.setRules(Lists.newArrayList(rule1, rule2)); + + JsonAssert + .assertJson(getClass().getResource("RulesSearchTest/expected.json")) + .isSimilarTo(rules.toJson()); + } + + @Test + public void testJsonParsingEmpty() throws IOException { + URL resource = getClass().getResource("RulesSearchTest/empty.json"); + String json = IOUtils.toString(resource); + RulesSearchResult result = RulesSearchResult.fromJson(json); + + assertThat(result.getRules()).isEmpty(); + } +} diff --git a/sonar-batch-protocol/src/test/resources/org/sonar/batch/protocol/input/RulesSearchTest/empty.json b/sonar-batch-protocol/src/test/resources/org/sonar/batch/protocol/input/RulesSearchTest/empty.json new file mode 100644 index 00000000000..055fe8b8d63 --- /dev/null +++ b/sonar-batch-protocol/src/test/resources/org/sonar/batch/protocol/input/RulesSearchTest/empty.json @@ -0,0 +1 @@ +{"total":3225,"p":30,"ps":500,"rules":[]}
\ No newline at end of file diff --git a/sonar-batch-protocol/src/test/resources/org/sonar/batch/protocol/input/RulesSearchTest/expected.json b/sonar-batch-protocol/src/test/resources/org/sonar/batch/protocol/input/RulesSearchTest/expected.json new file mode 100644 index 00000000000..89350a7e331 --- /dev/null +++ b/sonar-batch-protocol/src/test/resources/org/sonar/batch/protocol/input/RulesSearchTest/expected.json @@ -0,0 +1 @@ +{"total":290,"p":1,"ps":2,"rules":[{"key":"squid:S1194","internalKey":"S1194","repo":"squid","name":"\"java.lang.Error\" should not be extended","severity":"MAJOR","lang":"java"},{"key":"squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck","internalKey":"ObjectFinalizeOverridenCallsSuperFinalizeCheck","repo":"squid","name":"super.finalize() should be called at the end of Object.finalize() implementations","severity":"BLOCKER","lang":"java"}]}
\ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java index cb6f40dafc1..acf0515fbf5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java @@ -42,8 +42,8 @@ public class BatchComponents { // only static stuff } - public static Collection all(GlobalMode analysisMode) { - List components = Lists.newArrayList( + public static Collection<Object> all(GlobalMode analysisMode) { + List<Object> components = Lists.newArrayList( DefaultResourceTypes.get(), // SCM ScmConfiguration.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java index cea1eabf7ba..db806c103c9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java @@ -19,6 +19,11 @@ */ package org.sonar.batch.bootstrap; +import org.sonar.batch.rule.RulesLoader; + +import org.sonar.batch.rule.DefaultRulesLoader; +import org.sonar.batch.rule.RulesProvider; + import java.util.List; import java.util.Map; import org.sonar.api.CoreProperties; @@ -81,6 +86,7 @@ public class GlobalContainer extends ComponentContainer { CachesManager.class, GlobalMode.class, GlobalSettings.class, + new RulesProvider(), ServerClient.class, Logback.class, DefaultServer.class, @@ -94,6 +100,7 @@ public class GlobalContainer extends ComponentContainer { new GlobalRepositoriesProvider(), UserRepository.class); addIfMissing(BatchPluginInstaller.class, PluginInstaller.class); + addIfMissing(DefaultRulesLoader.class, RulesLoader.class); addIfMissing(DefaultGlobalRepositoriesLoader.class, GlobalRepositoriesLoader.class); addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class); addIfMissing(DefaultServerIssuesLoader.class, ServerIssuesLoader.class); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java index b10f996f20f..197544db075 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java @@ -72,7 +72,7 @@ public class ServerClient { } public URI getURI(String pathStartingWithSlash) { - Preconditions.checkArgument(pathStartingWithSlash.startsWith("/"), "Path must start with slash /"); + Preconditions.checkArgument(pathStartingWithSlash.startsWith("/"), "Path must start with slash /: " + pathStartingWithSlash); String path = StringEscapeUtils.escapeHtml(pathStartingWithSlash); return URI.create(getURL() + path); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/cpd/CpdComponents.java b/sonar-batch/src/main/java/org/sonar/batch/cpd/CpdComponents.java index 7d6a6be2a94..a30c6d0d832 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cpd/CpdComponents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cpd/CpdComponents.java @@ -20,7 +20,9 @@ package org.sonar.batch.cpd; import com.google.common.collect.ImmutableList; + import java.util.List; + import org.sonar.batch.cpd.index.IndexFactory; public final class CpdComponents { @@ -28,7 +30,7 @@ public final class CpdComponents { private CpdComponents() { } - public static List all() { + public static List<? extends Object> all() { return ImmutableList.of( CpdSensor.class, CpdMappings.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java index 5fad21f0905..a27b4c272a3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java @@ -25,7 +25,6 @@ import org.sonar.api.batch.rule.ActiveRule; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.Rule; import org.sonar.api.batch.rule.Rules; -import org.sonar.api.batch.rule.internal.DefaultActiveRule; import org.sonar.api.resources.Project; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.MessageException; @@ -42,7 +41,7 @@ public class ModuleIssues { private final Project project; private final IssueFilters filters; - public ModuleIssues(ActiveRules activeRules, @Nullable Rules rules, IssueCache cache, Project project, IssueFilters filters) { + public ModuleIssues(ActiveRules activeRules, Rules rules, IssueCache cache, Project project, IssueFilters filters) { this.activeRules = activeRules; this.rules = rules; this.cache = cache; @@ -50,17 +49,10 @@ public class ModuleIssues { this.filters = filters; } - public ModuleIssues(ActiveRules activeRules, IssueCache cache, Project project, IssueFilters filters) { - this(activeRules, null, cache, project, filters); - } - public boolean initAndAddIssue(DefaultIssue issue) { RuleKey ruleKey = issue.ruleKey(); - Rule rule = null; - if (rules != null) { - rule = rules.find(ruleKey); - validateRule(issue, rule); - } + Rule rule = rules.find(ruleKey); + validateRule(issue, rule); ActiveRule activeRule = activeRules.find(ruleKey); if (activeRule == null) { // rule does not exist or is not enabled -> ignore the issue @@ -86,7 +78,7 @@ public class ModuleIssues { private void updateIssue(DefaultIssue issue, @Nullable Rule rule, ActiveRule activeRule) { if (Strings.isNullOrEmpty(issue.message())) { - issue.setMessage(((DefaultActiveRule) activeRule).name()); + issue.setMessage(rule.name()); } if (project != null) { issue.setCreationDate(project.getAnalysisDate()); diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java index 370c3f32ca9..6cf1c15157d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java @@ -19,8 +19,15 @@ */ package org.sonar.batch.mediumtest; +import org.sonar.api.server.rule.RulesDefinition.Repository; + +import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.batch.protocol.input.RulesSearchResult; +import org.sonar.batch.rule.RulesLoader; +import org.sonar.batch.protocol.input.Rule; import com.google.common.base.Function; import com.google.common.io.Files; + import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; @@ -29,9 +36,11 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; + import org.sonar.api.CoreProperties; import org.sonar.api.SonarPlugin; import org.sonar.api.batch.bootstrap.ProjectReactor; @@ -78,6 +87,7 @@ public class BatchMediumTester { private final FakeServerIssuesLoader serverIssues = new FakeServerIssuesLoader(); private final FakeServerLineHashesLoader serverLineHashes = new FakeServerLineHashesLoader(); private final Map<String, String> bootstrapProperties = new HashMap<>(); + private final FakeRulesLoader rulesLoader = new FakeRulesLoader(); private LogOutput logOutput = null; public BatchMediumTester build() { @@ -116,6 +126,30 @@ public class BatchMediumTester { return this; } + public BatchMediumTesterBuilder addRule(Rule rule) { + rulesLoader.addRule(rule); + return this; + } + + public BatchMediumTesterBuilder addRules(List<Rule> rules) { + for (Rule r : rules) { + rulesLoader.addRule(r); + } + return this; + } + + public BatchMediumTesterBuilder addRules(RulesDefinition rulesDefinition) { + RulesDefinition.Context context = new RulesDefinition.Context(); + rulesDefinition.define(context); + List<Repository> repositories = context.repositories(); + for (Repository repo : repositories) { + for (RulesDefinition.Rule rule : repo.rules()) { + this.addRule(new Rule(rule.repository().key() + ":" + rule.key(), rule.repository().key(), rule.internalKey(), rule.name(), rule.severity(), repo.language())); + } + } + return this; + } + public BatchMediumTesterBuilder addDefaultQProfile(String language, String name) { addQProfile(language, name); globalRefProvider.globalSettings().put("sonar.profile." + language, name); @@ -171,6 +205,7 @@ public class BatchMediumTester { builder.projectRefProvider, builder.serverIssues, builder.serverLineHashes, + builder.rulesLoader, new DefaultDebtModel()) .setBootstrapProperties(builder.bootstrapProperties) .setLogOutput(builder.logOutput) @@ -223,6 +258,23 @@ public class BatchMediumTester { } } + private static class FakeRulesLoader implements RulesLoader { + private List<Rule> rules = new LinkedList<>(); + + public FakeRulesLoader addRule(Rule rule) { + rules.add(rule); + return this; + } + + @Override + public RulesSearchResult load() { + RulesSearchResult r = new RulesSearchResult(); + r.setRules(rules); + return r; + } + + } + private static class FakeGlobalRepositoriesLoader implements GlobalRepositoriesLoader { private int metricId = 1; diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java index 388faf11b6a..564ce0f3658 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java @@ -64,5 +64,4 @@ public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoad throw MessageException.of("No quality profiles has been found this project, you probably don't have any language plugin suitable for this analysis."); } } - } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java index 532547dc16d..5bb0a4a86bd 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java @@ -44,7 +44,7 @@ public class ActiveRulesProvider extends ProviderAdapter { return singleton; } - private ActiveRules load(ProjectRepositories ref) { + private static ActiveRules load(ProjectRepositories ref) { ActiveRulesBuilder builder = new ActiveRulesBuilder(); for (ActiveRule activeRule : ref.activeRules()) { NewActiveRule newActiveRule = builder.create(RuleKey.of(activeRule.repositoryKey(), activeRule.ruleKey())); diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultRulesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultRulesLoader.java new file mode 100644 index 00000000000..9ab9c176ae6 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultRulesLoader.java @@ -0,0 +1,54 @@ +/* + * 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.rule; + +import org.sonar.batch.protocol.input.Rule; + +import org.sonar.batch.protocol.input.RulesSearchResult; +import org.sonar.batch.bootstrap.WSLoader; + +public class DefaultRulesLoader implements RulesLoader { + private static final String RULES_SEARCH_URL = "/api/rules/search?ps=500&f=repo,name,internalKey,severity,lang"; + + private final WSLoader wsLoader; + + public DefaultRulesLoader(WSLoader wsLoader) { + this.wsLoader = wsLoader; + } + + @Override + public RulesSearchResult load() { + + RulesSearchResult rules = RulesSearchResult.fromJson(wsLoader.loadString(getUrl(1))); + + for (int i = 2; i < 100; i++) { + RulesSearchResult moreRules = RulesSearchResult.fromJson(wsLoader.loadString(getUrl(i))); + if (moreRules.getRules().isEmpty()) { + break; + } + rules.getRules().addAll(moreRules.getRules()); + } + return rules; + } + + private String getUrl(int page) { + return RULES_SEARCH_URL + "&p=" + page; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/RuleFinderCompatibility.java b/sonar-batch/src/main/java/org/sonar/batch/rule/RuleFinderCompatibility.java index 6dab1413350..fc0f28ed66e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/RuleFinderCompatibility.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/RuleFinderCompatibility.java @@ -19,13 +19,12 @@ */ package org.sonar.batch.rule; +import org.sonar.api.batch.rule.Rules; + import com.google.common.base.Function; import com.google.common.collect.Collections2; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; -import org.sonar.api.batch.rule.ActiveRule; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.internal.DefaultActiveRule; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; @@ -46,10 +45,10 @@ import java.util.Collections; */ public class RuleFinderCompatibility implements RuleFinder { - private final ActiveRules activeRules; + private final Rules rules; - public RuleFinderCompatibility(ActiveRules activeRules) { - this.activeRules = activeRules; + public RuleFinderCompatibility(Rules rules) { + this.rules = rules; } @Override @@ -64,7 +63,7 @@ public class RuleFinderCompatibility implements RuleFinder { @Override public Rule findByKey(RuleKey key) { - return toRule(activeRules.find(key)); + return toRule(rules.find(key)); } @Override @@ -96,28 +95,27 @@ public class RuleFinderCompatibility implements RuleFinder { } private Collection<Rule> byRepository(RuleQuery query) { - return Collections2.transform(activeRules.findByRepository(query.getRepositoryKey()), new Function<ActiveRule, Rule>() { + return Collections2.transform(rules.findByRepository(query.getRepositoryKey()), new Function<org.sonar.api.batch.rule.Rule, Rule>() { @Override - public Rule apply(@Nonnull ActiveRule input) { + public Rule apply(@Nonnull org.sonar.api.batch.rule.Rule input) { return toRule(input); } }); } private Collection<Rule> byKey(RuleQuery query) { - Rule rule = toRule(activeRules.find(RuleKey.of(query.getRepositoryKey(), query.getKey()))); + Rule rule = toRule(rules.find(RuleKey.of(query.getRepositoryKey(), query.getKey()))); return rule != null ? Arrays.asList(rule) : Collections.<Rule>emptyList(); } private Collection<Rule> byInternalKey(RuleQuery query) { - Rule rule = toRule(activeRules.findByInternalKey(query.getRepositoryKey(), query.getConfigKey())); + Rule rule = toRule(rules.findByInternalKey(query.getRepositoryKey(), query.getConfigKey())); return rule != null ? Arrays.asList(rule) : Collections.<Rule>emptyList(); } @CheckForNull - private Rule toRule(@Nullable ActiveRule rule) { - DefaultActiveRule ar = (DefaultActiveRule) rule; - return ar == null ? null : Rule.create(ar.ruleKey().repository(), ar.ruleKey().rule()).setName(ar.name()).setConfigKey(ar.internalKey()).setLanguage(ar.language()); + private static Rule toRule(@Nullable org.sonar.api.batch.rule.Rule ar) { + return ar == null ? null : Rule.create(ar.key().repository(), ar.key().rule()).setName(ar.name()).setConfigKey(ar.internalKey()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesLoader.java new file mode 100644 index 00000000000..84a937b05e5 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesLoader.java @@ -0,0 +1,26 @@ +/* + * 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.rule; + +import org.sonar.batch.protocol.input.RulesSearchResult; + +public interface RulesLoader { + RulesSearchResult load(); +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java new file mode 100644 index 00000000000..c864489149c --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java @@ -0,0 +1,53 @@ +/* + * 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.rule; + +import org.picocontainer.injectors.ProviderAdapter; + +import org.sonar.api.rule.RuleKey; +import org.sonar.api.batch.rule.internal.RulesBuilder; +import org.sonar.api.batch.rule.internal.NewRule; +import org.sonar.batch.protocol.input.Rule; +import org.sonar.api.batch.rule.Rules; + +public class RulesProvider extends ProviderAdapter { + private Rules singleton = null; + + public Rules provide(RulesLoader ref) { + if (singleton == null) { + singleton = load(ref); + } + return singleton; + } + + private static Rules load(RulesLoader ref) { + RulesBuilder builder = new RulesBuilder(); + + for (Rule inputRule : ref.load().getRules()) { + NewRule newRule = builder.add(RuleKey.parse(inputRule.ruleKey())); + newRule.setName(inputRule.name()); + newRule.setSeverity(inputRule.severity()); + newRule.setInternalKey(inputRule.internalKey()); + } + + return builder.build(); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index 1e0b5d4571b..30bd5a2ff26 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -132,7 +132,7 @@ public class ProjectScanContainer extends ComponentContainer { ProjectExclusions.class, ProjectReactorValidator.class, new ProjectRepositoriesProvider(), - new WSLoaderProjectProvider(), + new ProjectWSLoaderProvider(), DefaultResourceCreationLock.class, CodeColorizers.class, MetricProvider.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java new file mode 100644 index 00000000000..e3caa1daaba --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java @@ -0,0 +1,58 @@ +/* + * 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.scan; + +import org.picocontainer.injectors.ProviderAdapter; + +import java.util.Map; + +import org.sonar.batch.bootstrap.AnalysisProperties; +import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.bootstrap.WSLoader; +import org.sonar.home.cache.PersistentCache; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.batch.bootstrap.WSLoader.LoadStrategy; + +public class ProjectWSLoaderProvider extends ProviderAdapter { + private WSLoader wsLoader; + + public WSLoader provide(AnalysisProperties props, AnalysisMode mode, PersistentCache cache, ServerClient client) { + if (wsLoader == null) { + // recreate cache directory if needed for this analysis + cache.reconfigure(); + wsLoader = new WSLoader(isCacheEnabled(props.properties(), mode.isPreview()), cache, client); + wsLoader.setStrategy(getStrategy(mode)); + } + return wsLoader; + } + + private static LoadStrategy getStrategy(AnalysisMode mode) { + if (mode.isQuick()) { + return LoadStrategy.CACHE_FIRST; + } + + return LoadStrategy.SERVER_FIRST; + } + + private static boolean isCacheEnabled(Map<String, String> props, boolean isPreview) { + String enableOffline = props.get("sonar.enableOffline"); + return isPreview && "true".equals(enableOffline); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java index c087219e1f2..1f2b551ef2f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java @@ -19,9 +19,10 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + import com.google.common.collect.Maps; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.batch.index.BatchComponent; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java index 43e423e7fa7..9be4093233a 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java @@ -19,6 +19,9 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + +import org.sonar.api.batch.rule.Rules; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.BatchSide; @@ -26,8 +29,6 @@ import org.sonar.api.issue.Issue; import org.sonar.core.issue.DefaultIssue; import org.sonar.api.resources.Project; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; import org.sonar.api.rules.RulePriority; import org.sonar.batch.DefaultProjectTree; import org.sonar.batch.index.BatchComponent; @@ -43,14 +44,14 @@ public class IssuesReportBuilder { private static final Logger LOG = LoggerFactory.getLogger(IssuesReportBuilder.class); private final IssueCache issueCache; - private final RuleFinder ruleFinder; + private final Rules rules; private final BatchComponentCache resourceCache; private final DefaultProjectTree projectTree; private final InputPathCache inputPathCache; - public IssuesReportBuilder(IssueCache issueCache, RuleFinder ruleFinder, BatchComponentCache resourceCache, DefaultProjectTree projectTree, InputPathCache inputPathCache) { + public IssuesReportBuilder(IssueCache issueCache, Rules rules, BatchComponentCache resourceCache, DefaultProjectTree projectTree, InputPathCache inputPathCache) { this.issueCache = issueCache; - this.ruleFinder = ruleFinder; + this.rules = rules; this.resourceCache = resourceCache; this.projectTree = projectTree; this.inputPathCache = inputPathCache; @@ -98,8 +99,7 @@ public class IssuesReportBuilder { @CheckForNull private Rule findRule(Issue issue) { - RuleKey ruleKey = issue.ruleKey(); - return ruleFinder.findByKey(ruleKey); + return rules.find(issue.ruleKey()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java index b13b5468d67..7dd9db0d18d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java @@ -19,6 +19,9 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + +import org.sonar.api.batch.rule.Rules; import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @@ -31,8 +34,6 @@ import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.internal.DefaultActiveRule; import org.sonar.api.config.Settings; import org.sonar.core.issue.DefaultIssue; import org.sonar.api.platform.Server; @@ -72,18 +73,18 @@ public class JSONReport implements Reporter { private final Settings settings; private final FileSystem fileSystem; private final Server server; - private final ActiveRules activeRules; + private final Rules rules; private final IssueCache issueCache; private final InputPathCache fileCache; private final Project rootModule; private final UserRepository userRepository; - public JSONReport(Settings settings, FileSystem fileSystem, Server server, ActiveRules activeRules, IssueCache issueCache, + public JSONReport(Settings settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache, Project rootModule, InputPathCache fileCache, UserRepository userRepository) { this.settings = settings; this.fileSystem = fileSystem; this.server = server; - this.activeRules = activeRules; + this.rules = rules; this.issueCache = issueCache; this.rootModule = rootModule; this.fileCache = fileCache; @@ -214,7 +215,7 @@ public class JSONReport implements Reporter { json.endArray(); } - private void writeUsers(JsonWriter json, Collection<BatchInput.User> users) throws IOException { + private static void writeUsers(JsonWriter json, Collection<BatchInput.User> users) throws IOException { json.name("users").beginArray(); for (BatchInput.User user : users) { json @@ -227,7 +228,7 @@ public class JSONReport implements Reporter { } private String getRuleName(RuleKey ruleKey) { - DefaultActiveRule rule = (DefaultActiveRule) activeRules.find(ruleKey); + Rule rule = rules.find(ruleKey); return rule != null ? rule.name() : null; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportRuleKey.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportRuleKey.java index 99549c2ac1d..0373e62c504 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportRuleKey.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportRuleKey.java @@ -19,9 +19,10 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.builder.ToStringBuilder; -import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; /** @@ -68,7 +69,7 @@ public class ReportRuleKey implements Comparable<ReportRuleKey> { @Override public int compareTo(ReportRuleKey o) { if (severity == o.getSeverity()) { - return getRule().ruleKey().toString().compareTo(o.getRule().ruleKey().toString()); + return getRule().key().toString().compareTo(o.getRule().key().toString()); } return o.getSeverity().compareTo(severity); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportSummary.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportSummary.java index 18e964fa262..680b4f086ec 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportSummary.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportSummary.java @@ -19,9 +19,10 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + import com.google.common.collect.Maps; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import java.util.ArrayList; @@ -49,12 +50,12 @@ public class ReportSummary { initMaps(reportRuleKey); ruleReportByRuleKey.get(reportRuleKey).getTotal().incrementCountInCurrentAnalysis(); total.incrementCountInCurrentAnalysis(); - totalByRuleKey.get(rule.ruleKey().toString()).incrementCountInCurrentAnalysis(); + totalByRuleKey.get(rule.key().toString()).incrementCountInCurrentAnalysis(); totalBySeverity.get(severity.toString()).incrementCountInCurrentAnalysis(); if (issue.isNew()) { total.incrementNewIssuesCount(); ruleReportByRuleKey.get(reportRuleKey).getTotal().incrementNewIssuesCount(); - totalByRuleKey.get(rule.ruleKey().toString()).incrementNewIssuesCount(); + totalByRuleKey.get(rule.key().toString()).incrementNewIssuesCount(); totalBySeverity.get(severity.toString()).incrementNewIssuesCount(); } } @@ -72,7 +73,7 @@ public class ReportSummary { initMaps(reportRuleKey); total.incrementResolvedIssuesCount(); ruleReportByRuleKey.get(reportRuleKey).getTotal().incrementResolvedIssuesCount(); - totalByRuleKey.get(rule.ruleKey().toString()).incrementResolvedIssuesCount(); + totalByRuleKey.get(rule.key().toString()).incrementResolvedIssuesCount(); totalBySeverity.get(severity.toString()).incrementResolvedIssuesCount(); } @@ -80,8 +81,8 @@ public class ReportSummary { if (!ruleReportByRuleKey.containsKey(reportRuleKey)) { ruleReportByRuleKey.put(reportRuleKey, new RuleReport(reportRuleKey)); } - if (!totalByRuleKey.containsKey(reportRuleKey.getRule().ruleKey().toString())) { - totalByRuleKey.put(reportRuleKey.getRule().ruleKey().toString(), new IssueVariation()); + if (!totalByRuleKey.containsKey(reportRuleKey.getRule().key().toString())) { + totalByRuleKey.put(reportRuleKey.getRule().key().toString(), new IssueVariation()); } if (!totalBySeverity.containsKey(reportRuleKey.getSeverity().toString())) { totalBySeverity.put(reportRuleKey.getSeverity().toString(), new IssueVariation()); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ResourceReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ResourceReport.java index 4a4329f908d..2a6135e5c17 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ResourceReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ResourceReport.java @@ -19,9 +19,10 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + import com.google.common.collect.Maps; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.batch.index.BatchComponent; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleNameProvider.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleNameProvider.java index 6fa0a7da42e..9f61793cb73 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleNameProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleNameProvider.java @@ -19,26 +19,27 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + +import org.sonar.api.batch.rule.Rules; import org.apache.commons.lang.StringEscapeUtils; import org.sonar.api.batch.BatchSide; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; import javax.annotation.CheckForNull; @BatchSide public class RuleNameProvider { - private RuleFinder ruleFinder; + private Rules rules; - public RuleNameProvider(RuleFinder ruleFinder) { - this.ruleFinder = ruleFinder; + public RuleNameProvider(Rules rules) { + this.rules = rules; } @CheckForNull private String nameFromDB(RuleKey ruleKey) { - Rule r = ruleFinder.findByKey(ruleKey); - return r != null ? r.getName() : null; + Rule r = rules.find(ruleKey); + return r != null ? r.name() : null; } public String nameForHTML(RuleKey ruleKey) { @@ -52,8 +53,7 @@ public class RuleNameProvider { } public String nameForHTML(Rule rule) { - String name = nameFromDB(RuleKey.of(rule.getRepositoryKey(), rule.getKey())); - return StringEscapeUtils.escapeHtml(name != null ? name : rule.getName()); + return StringEscapeUtils.escapeHtml(rule.name()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleReport.java index 1ddf1b38282..16d6b4cf999 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/RuleReport.java @@ -19,8 +19,9 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.Rule; + import org.apache.commons.lang.builder.ToStringBuilder; -import org.sonar.api.rules.Rule; public final class RuleReport { private final ReportRuleKey reportRuleKey; diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java index 3199c7c8f03..a602f1f6549 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java @@ -86,7 +86,7 @@ public class ModuleIssuesTest { @Test public void fail_if_rule_has_no_name_and_issue_has_no_message() { - ruleBuilder.add(RuleKey.of("squid", "AvoidCycle")); + ruleBuilder.add(SQUID_RULE_KEY).setInternalKey(SQUID_RULE_KEY.rule()); initModuleIssues(); DefaultIssue issue = new DefaultIssue().setRuleKey(SQUID_RULE_KEY).setMessage(""); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java index 8287a310bfb..f73d1c60f46 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.deprecated; +import org.sonar.xoo.rule.XooRulesDefinition; + import com.google.common.collect.ImmutableMap; import java.io.File; import java.io.IOException; @@ -42,6 +44,7 @@ public class DeprecatedApiMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) + .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") .activateRule(new ActiveRule("xoo", "DeprecatedResourceApi", null, "One issue per line", "MAJOR", null, "xoo")) .build(); @@ -82,9 +85,9 @@ public class DeprecatedApiMediumTest { .start(); assertThat(result.issues()).extracting("componentKey", "message", "line").containsOnly( - tuple("com.foo.project:src/sample.xoo", "One issue per line", null), + tuple("com.foo.project:src/sample.xoo", "Issue created using deprecated API", null), tuple("com.foo.project:src/sample.xoo", "Issue created using deprecated API", 1), - tuple("com.foo.project:src/package/sample.xoo", "One issue per line", null), + tuple("com.foo.project:src/package/sample.xoo", "Issue created using deprecated API", null), tuple("com.foo.project:src/package/sample.xoo", "Issue created using deprecated API", 1), tuple("com.foo.project:src", "Issue created using deprecated API", null), tuple("com.foo.project:src/package", "Issue created using deprecated API", null)); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java index 05c1efa99de..2beb8f133b5 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.fs; +import org.sonar.xoo.rule.XooRulesDefinition; + import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -44,6 +46,7 @@ public class ProjectBuilderMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) + .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)) .setPreviousAnalysisDate(new Date()) diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java index 4e75ffc5474..f27f72c5769 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.fs; +import org.sonar.xoo.rule.XooRulesDefinition; + import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -49,6 +51,7 @@ public class RandomFsAccessMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") + .addRules(new XooRulesDefinition()) .activateRule(new ActiveRule("xoo", "RandomAccessIssue", null, "One issue per line", "MAJOR", null, "xoo")) .build(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java index 5cc57070ce5..7d39819f825 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java @@ -19,6 +19,9 @@ */ package org.sonar.batch.mediumtest.issues; +import org.sonar.batch.protocol.input.Rule; + +import org.sonar.xoo.rule.XooRulesDefinition; import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -42,7 +45,10 @@ public class ChecksMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) + .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") + .addRule(new Rule("xoo:TemplateRule_1234", "xoo", "TemplateRule_1234", "A template rule", "MAJOR", "xoo")) + .addRule(new Rule("xoo:TemplateRule_1235", "xoo", "TemplateRule_1235", "Another template rule", "MAJOR", "xoo")) .activateRule(new ActiveRule("xoo", "TemplateRule_1234", "TemplateRule", "A template rule", "MAJOR", null, "xoo").addParam("line", "1")) .activateRule(new ActiveRule("xoo", "TemplateRule_1235", "TemplateRule", "Another template rule", "MAJOR", null, "xoo").addParam("line", "2")) .build(); 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 8f46a5d0800..6898c5bfcc9 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 @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.issues; +import org.sonar.xoo.rule.XooRulesDefinition; + import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -44,6 +46,7 @@ public class IssuesMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") + .addRules(new XooRulesDefinition()) .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) .build(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java index 10aef4cb60d..2d389a5d8cf 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.issues; +import org.sonar.xoo.rule.XooRulesDefinition; + import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -43,6 +45,7 @@ public class IssuesOnDirMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") + .addRules(new XooRulesDefinition()) .activateRule(new ActiveRule("xoo", "OneIssueOnDirPerFile", null, "One issue per line", "MINOR", "xoo", "xoo")) .build(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java index 749260c4233..c07dd6cdbc6 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java @@ -19,7 +19,12 @@ */ package org.sonar.batch.mediumtest.issues; +import org.sonar.xoo.rule.XooRulesDefinition; + +import org.sonar.batch.protocol.input.Rule; + import java.io.File; + import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; @@ -29,7 +34,6 @@ import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.xoo.XooPlugin; - import static org.assertj.core.api.Assertions.assertThat; public class MultilineIssuesMediumTest { @@ -39,6 +43,8 @@ public class MultilineIssuesMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) + .addRules(new XooRulesDefinition()) + .addRule(new Rule("xoo:MultilineIssue", "xoo", null, "Multinile Issue", "MAJOR", "xoo")) .addDefaultQProfile("xoo", "Sonar Way") .activateRule(new ActiveRule("xoo", "MultilineIssue", null, "Multinile Issue", "MAJOR", null, "xoo")) .build(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java index 385023ec1e3..3f7be697caf 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.preview; +import org.sonar.xoo.rule.XooRulesDefinition; + import com.google.common.collect.ImmutableMap; import org.junit.After; import org.junit.Before; @@ -48,6 +50,7 @@ public class EmptyFileTest { public BatchMediumTester tester = BatchMediumTester.builder() .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)) .registerPlugin("xoo", new XooPlugin()) + .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo")) .setPreviousAnalysisDate(new Date()) diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.java index 1f1539388f3..86697dcea42 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.preview; +import org.sonar.xoo.rule.XooRulesDefinition; + import com.google.common.collect.ImmutableMap; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; @@ -63,6 +65,7 @@ public class IncrementalModeMediumTest { .builder() .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL)) .registerPlugin("xoo", new XooPlugin()) + .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo")) .activateRule(new ActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null)) diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java index ab2157d056d..acf1f5b588b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java @@ -19,12 +19,14 @@ */ package org.sonar.batch.mediumtest.preview; +import org.sonar.batch.protocol.input.Rule; + +import org.sonar.xoo.rule.XooRulesDefinition; import com.google.common.collect.ImmutableMap; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; @@ -46,10 +48,10 @@ import static org.assertj.core.api.Assertions.assertThat; public class PreviewAndReportsMediumTest { - @Rule + @org.junit.Rule public TemporaryFolder temp = new TemporaryFolder(); - @Rule + @org.junit.Rule public LogTester logTester = new LogTester(); private static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); @@ -66,6 +68,8 @@ public class PreviewAndReportsMediumTest { .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)) .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") + .addRules(new XooRulesDefinition()) + .addRule(new Rule("manual:MyManualIssue", "manual", "MyManualIssue", "My manual issue", "MAJOR", null)) .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo")) .activateRule(new ActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null)) .setPreviousAnalysisDate(new Date()) diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/DefaultRulesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/DefaultRulesLoaderTest.java new file mode 100644 index 00000000000..49ecaa0bcc9 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/DefaultRulesLoaderTest.java @@ -0,0 +1,62 @@ +/* + * 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.rule; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.Arrays; +import java.util.LinkedList; + +import static org.mockito.Matchers.contains; +import static org.assertj.core.api.Assertions.assertThat; +import org.sonar.batch.bootstrap.WSLoader; +import org.junit.Test; +import org.sonar.batch.protocol.input.Rule; +import org.sonar.batch.protocol.input.RulesSearchResult; + +public class DefaultRulesLoaderTest { + @Test + public void testLoadingJson() throws IOException { + Rule rule1 = new Rule("squid:S1194", "squid", "S1194", "\"java.lang.Error\" should not be extended", "MAJOR", "java"); + Rule rule2 = new Rule("squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck", "squid", "ObjectFinalizeOverridenCallsSuperFinalizeCheck", + "super.finalize() should be called at the end of Object.finalize() implementations", "BLOCKER", "java"); + + // generate json + RulesSearchResult rulesSearch = new RulesSearchResult(); + rulesSearch.setRules(Arrays.asList(rule1, rule2)); + String json = rulesSearch.toJson(); + + RulesSearchResult empty = new RulesSearchResult(); + empty.setRules(new LinkedList<Rule>()); + String emptyJson = empty.toJson(); + + WSLoader wsLoader = mock(WSLoader.class); + when(wsLoader.loadString(contains("p=1"))).thenReturn(json); + when(wsLoader.loadString(contains("p=2"))).thenReturn(emptyJson); + + // load + RulesLoader loader = new DefaultRulesLoader(wsLoader); + RulesSearchResult rules = loader.load(); + + assertThat(rules.toJson()).isEqualTo(json); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/RuleFinderCompatibilityTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/RuleFinderCompatibilityTest.java index 1c61c091b68..268de8b4e0f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/RuleFinderCompatibilityTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/RuleFinderCompatibilityTest.java @@ -19,15 +19,15 @@ */ package org.sonar.batch.rule; +import org.sonar.api.batch.rule.internal.RulesBuilder; + +import org.sonar.api.batch.rule.Rules; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleQuery; - import static org.assertj.core.api.Assertions.assertThat; public class RuleFinderCompatibilityTest { @@ -35,20 +35,18 @@ public class RuleFinderCompatibilityTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private ActiveRules activeRules = new ActiveRulesBuilder() - .create(RuleKey.of("repo1", "rule1")) - .activate() - .create(RuleKey.of("repo1", "rule2")) - .setInternalKey("rule2_internal") - .activate() - .create(RuleKey.of("repo2", "rule1")) - .activate() - .build(); + private Rules rules; private RuleFinderCompatibility ruleFinder; @Before public void prepare() { - ruleFinder = new RuleFinderCompatibility(activeRules); + RulesBuilder builder = new RulesBuilder(); + builder.add(RuleKey.of("repo1", "rule1")); + builder.add(RuleKey.of("repo1", "rule2")).setInternalKey("rule2_internal"); + builder.add(RuleKey.of("repo2", "rule1")); + rules = builder.build(); + + ruleFinder = new RuleFinderCompatibility(rules); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java new file mode 100644 index 00000000000..84e36977b7c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java @@ -0,0 +1,61 @@ +/* + * 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.rule; + +import org.assertj.core.api.Condition; + +import org.sonar.api.batch.rule.Rules; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.mock; +import org.sonar.batch.protocol.input.Rule; +import org.sonar.batch.protocol.input.RulesSearchResult; +import org.junit.Test; + +public class RulesProviderTest { + @Test + public void testRuleTranslation() { + final Rule testRule = new Rule("repo1:key1", "repo1", "key1", "name", "severity", "language"); + + RulesSearchResult loadResult = new RulesSearchResult(); + loadResult.setRules(Arrays.asList(testRule)); + RulesLoader loader = mock(RulesLoader.class); + when(loader.load()).thenReturn(loadResult); + + RulesProvider provider = new RulesProvider(); + Rules rules = provider.provide(loader); + + assertThat(rules.findAll()).hasSize(1); + assertThat(rules.findAll()).are(new Condition<org.sonar.api.batch.rule.Rule>() { + + @Override + public boolean matches(org.sonar.api.batch.rule.Rule value) { + return value.key().rule().equals(testRule.internalKey()) && + value.internalKey().equals(testRule.internalKey()) && + value.name().equals(testRule.name()) && + value.severity().equals(testRule.severity()) && + value.key().repository().equals(testRule.repositoryKey()); + } + }); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java index afc0d4c39aa..544b1c065b3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java @@ -19,6 +19,9 @@ */ package org.sonar.batch.scan.report; +import org.sonar.api.batch.rule.internal.RulesBuilder; + +import org.sonar.api.batch.rule.Rules; import com.google.common.collect.Lists; import com.google.common.io.Resources; import org.junit.Before; @@ -29,8 +32,6 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.config.Settings; import org.sonar.api.issue.Issue; import org.sonar.core.issue.DefaultIssue; @@ -68,7 +69,7 @@ public class JSONReportTest { Resource resource = mock(Resource.class); DefaultFileSystem fs; Server server = mock(Server.class); - ActiveRules activeRules = mock(ActiveRules.class); + Rules rules = mock(Rules.class); Settings settings = new Settings(); IssueCache issueCache = mock(IssueCache.class); private UserRepository userRepository; @@ -91,10 +92,11 @@ public class JSONReportTest { moduleA.setParent(rootModule).setPath("core"); Project moduleB = new Project("struts-ui"); moduleB.setParent(rootModule).setPath("ui"); - activeRules = new ActiveRulesBuilder() - .create(RuleKey.of("squid", "AvoidCycles")).setName("Avoid Cycles").activate() - .build(); - jsonReport = new JSONReport(settings, fs, server, activeRules, issueCache, rootModule, fileCache, userRepository); + + RulesBuilder builder = new RulesBuilder(); + builder.add(RuleKey.of("squid", "AvoidCycles")).setName("Avoid Cycles"); + rules = builder.build(); + jsonReport = new JSONReport(settings, fs, server, rules, issueCache, rootModule, fileCache, userRepository); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/RuleNameProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/RuleNameProviderTest.java new file mode 100644 index 00000000000..fb7e399068f --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/RuleNameProviderTest.java @@ -0,0 +1,67 @@ +/* + * 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.scan.report; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThat; + +import static org.mockito.Matchers.any; + +import org.sonar.api.rule.RuleKey; +import org.sonar.api.batch.rule.Rule; +import org.junit.Test; +import org.junit.Before; +import org.sonar.api.batch.rule.Rules; + +public class RuleNameProviderTest { + RuleNameProvider provider; + Rules rules; + Rule rule; + RuleKey ruleKey; + + @Before + public void setUp() { + ruleKey = mock(RuleKey.class); + rule = mock(Rule.class); + rules = mock(Rules.class); + provider = new RuleNameProvider(rules); + + when(ruleKey.rule()).thenReturn("ruleKey"); + when(ruleKey.repository()).thenReturn("repoKey"); + + when(rule.name()).thenReturn("name"); + when(rule.key()).thenReturn(ruleKey); + + when(rules.find(any(RuleKey.class))).thenReturn(rule); + } + + @Test + public void testNameForHTML() { + assertThat(provider.nameForHTML(rule)).isEqualTo(rule.name()); + assertThat(provider.nameForHTML(ruleKey)).isEqualTo(rule.name()); + } + + @Test + public void testNameForJS() { + assertThat(provider.nameForJS("repoKey:ruleKey")).isEqualTo(rule.name()); + } + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java index 3a8bb05e407..f05b73e8324 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java @@ -49,4 +49,6 @@ public interface Rules { */ Collection<Rule> findByRepository(String repository); + Rule findByInternalKey(String repository, String internalKey); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java index b8b271e481d..83e6a69f37f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java @@ -30,7 +30,6 @@ import java.util.Map; @Immutable public class DefaultActiveRule implements ActiveRule { private final RuleKey ruleKey; - private final String name; private final String severity; private final String internalKey; private final String language; @@ -39,7 +38,6 @@ public class DefaultActiveRule implements ActiveRule { DefaultActiveRule(NewActiveRule newActiveRule) { this.severity = newActiveRule.severity; - this.name = newActiveRule.name; this.internalKey = newActiveRule.internalKey; this.templateRuleKey = newActiveRule.templateRuleKey; this.ruleKey = newActiveRule.ruleKey; @@ -52,10 +50,6 @@ public class DefaultActiveRule implements ActiveRule { return ruleKey; } - public String name() { - return name; - } - @Override public String severity() { return severity; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java index 3c14387a31c..1ef36b3e63d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java @@ -19,10 +19,12 @@ */ package org.sonar.api.batch.rule.internal; +import org.sonar.api.batch.rule.Rule; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Table; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ListMultimap; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.rule.Rule; import org.sonar.api.batch.rule.Rules; import org.sonar.api.rule.RuleKey; @@ -36,14 +38,22 @@ class DefaultRules implements Rules { // TODO use disk-backed cache (persistit) instead of full in-memory cache ? private final ListMultimap<String, Rule> rulesByRepository; + private final Table<String, String, Rule> rulesByRepositoryAndInternalKey; DefaultRules(Collection<NewRule> newRules) { ImmutableListMultimap.Builder<String, Rule> builder = ImmutableListMultimap.builder(); + ImmutableTable.Builder<String, String, Rule> tableBuilder = ImmutableTable.builder(); + for (NewRule newRule : newRules) { DefaultRule r = new DefaultRule(newRule); builder.put(r.key().repository(), r); + if (r.internalKey() != null) { + tableBuilder.put(r.key().repository(), r.internalKey(), r); + } } + rulesByRepository = builder.build(); + rulesByRepositoryAndInternalKey = tableBuilder.build(); } @Override @@ -66,4 +76,9 @@ class DefaultRules implements Rules { public Collection<Rule> findByRepository(String repository) { return rulesByRepository.get(repository); } + + @Override + public Rule findByInternalKey(String repository, String internalKey) { + return rulesByRepositoryAndInternalKey.get(repository, internalKey); + } } 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 726395963ab..14382e88265 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 @@ -63,7 +63,6 @@ public class ActiveRulesBuilderTest { ActiveRule squid1 = activeRules.find(RuleKey.of("squid", "S0001")); assertThat(squid1.ruleKey().repository()).isEqualTo("squid"); assertThat(squid1.ruleKey().rule()).isEqualTo("S0001"); - assertThat(((DefaultActiveRule) squid1).name()).isEqualTo("My Rule"); assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL); assertThat(squid1.internalKey()).isEqualTo("__S0001__"); assertThat(squid1.params()).hasSize(1); |