diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-02-12 10:49:24 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-02-12 10:50:57 +0100 |
commit | c5dddfa9b31597b24a969df675b04f9f748239e6 (patch) | |
tree | a13733f9d044deb5eaa08627f66471ba881a9092 /sonar-batch | |
parent | 647690e2fc2d73191b018668e0ee7c75b1cc65a8 (diff) | |
download | sonarqube-c5dddfa9b31597b24a969df675b04f9f748239e6.tar.gz sonarqube-c5dddfa9b31597b24a969df675b04f9f748239e6.zip |
SONAR-926 Export path information for components in JsonReport
Diffstat (limited to 'sonar-batch')
9 files changed, 124 insertions, 175 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index f5112f7c20b..ab7733a95ab 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -28,7 +28,12 @@ import org.sonar.api.batch.rule.CheckFactory; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.FileExclusions; -import org.sonar.batch.*; +import org.sonar.batch.DefaultProjectClasspath; +import org.sonar.batch.DefaultSensorContext; +import org.sonar.batch.DefaultTimeMachine; +import org.sonar.batch.ProjectTree; +import org.sonar.batch.ResourceFilters; +import org.sonar.batch.ViolationFilters; import org.sonar.batch.bootstrap.BatchExtensionDictionnary; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; @@ -46,9 +51,19 @@ import org.sonar.batch.rule.ActiveRulesProvider; import org.sonar.batch.rule.ModuleQProfiles; import org.sonar.batch.rule.QProfileSensor; import org.sonar.batch.rule.RulesProfileProvider; -import org.sonar.batch.scan.filesystem.*; +import org.sonar.batch.scan.filesystem.ComponentIndexer; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; +import org.sonar.batch.scan.filesystem.DeprecatedFileFilters; +import org.sonar.batch.scan.filesystem.ExclusionFilters; +import org.sonar.batch.scan.filesystem.FileIndex; +import org.sonar.batch.scan.filesystem.FileSystemLogger; +import org.sonar.batch.scan.filesystem.InputFileBuilderFactory; +import org.sonar.batch.scan.filesystem.LanguageDetectionFactory; +import org.sonar.batch.scan.filesystem.ModuleFileSystemInitializer; +import org.sonar.batch.scan.filesystem.PreviousFileHashLoader; +import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter; +import org.sonar.batch.scan.filesystem.StatusDetectionFactory; import org.sonar.batch.scan.language.DefaultModuleLanguages; -import org.sonar.batch.scan.report.ComponentSelectorFactory; import org.sonar.batch.scan.report.JsonReport; import org.sonar.core.component.ScanPerspectives; import org.sonar.core.measure.MeasurementFilters; @@ -126,7 +141,6 @@ public class ModuleScanContainer extends ComponentContainer { // report JsonReport.class, - ComponentSelectorFactory.class, // issues IssuableFactory.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelector.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelector.java index 8542eb6476e..277b9c41f69 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelector.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelector.java @@ -20,15 +20,32 @@ package org.sonar.batch.scan.report; import org.sonar.api.issue.Issue; +import org.sonar.api.scan.filesystem.InputFile; +import org.sonar.batch.scan.filesystem.InputFileCache; import java.util.Set; abstract class ComponentSelector { + private final InputFileCache cache; + + ComponentSelector(InputFileCache cache) { + this.cache = cache; + } + + public InputFileCache getCache() { + return cache; + } + abstract void init(); abstract boolean register(Issue issue); abstract Set<String> componentKeys(); + InputFile component(String componentKey) { + String moduleKey = org.apache.commons.lang.StringUtils.substringBeforeLast(componentKey, ":"); + String path = org.apache.commons.lang.StringUtils.substringAfterLast(componentKey, ":"); + return cache.byPath(moduleKey, path); + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelectorFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelectorFactory.java deleted file mode 100644 index b384130468c..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelectorFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2013 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 org.sonar.api.BatchComponent; -import org.sonar.batch.bootstrap.AnalysisMode; -import org.sonar.batch.scan.filesystem.InputFileCache; - -public class ComponentSelectorFactory implements BatchComponent { - - private final InputFileCache fileCache; - private final AnalysisMode mode; - - public ComponentSelectorFactory(InputFileCache fileCache, AnalysisMode mode) { - this.fileCache = fileCache; - this.mode = mode; - } - - public ComponentSelector create() { - if (mode.isIncremental()) { - return new IncrementalComponentSelector(fileCache); - } - return new DefaultComponentSelector(); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/DefaultComponentSelector.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/DefaultComponentSelector.java deleted file mode 100644 index 5b7223ad200..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/DefaultComponentSelector.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2013 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 com.google.common.collect.Sets; -import org.sonar.api.issue.Issue; - -import java.util.Set; - -class DefaultComponentSelector extends ComponentSelector { - - private final Set<String> componentKeysWithIssue = Sets.newHashSet(); - - @Override - void init() { - } - - @Override - boolean register(Issue issue) { - componentKeysWithIssue.add(issue.componentKey()); - return true; - } - - @Override - Set<String> componentKeys() { - return componentKeysWithIssue; - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IncrementalComponentSelector.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IncrementalComponentSelector.java deleted file mode 100644 index 9c18af551fc..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IncrementalComponentSelector.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2013 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 org.sonar.api.scan.filesystem.InputFile; - -import com.google.common.collect.Sets; -import org.sonar.api.issue.Issue; -import org.sonar.api.scan.filesystem.internal.DefaultInputFile; -import org.sonar.batch.scan.filesystem.InputFileCache; - -import java.util.Set; - -class IncrementalComponentSelector extends ComponentSelector { - - private final InputFileCache cache; - private final Set<String> componentKeys = Sets.newHashSet(); - - IncrementalComponentSelector(InputFileCache cache) { - this.cache = cache; - } - - @Override - void init() { - for (InputFile inputFile : cache.all()) { - String status = inputFile.attribute(InputFile.ATTRIBUTE_STATUS); - if (status != null && !InputFile.STATUS_SAME.equals(status)) { - String componentKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY); - if (componentKey != null) { - componentKeys.add(componentKey); - } - } - } - } - - @Override - boolean register(Issue issue) { - return componentKeys.contains(issue.componentKey()); - } - - @Override - Set<String> componentKeys() { - return componentKeys; - } -} 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 0d85537d790..7c835ecce71 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 @@ -21,16 +21,20 @@ package org.sonar.batch.scan.report; import com.google.common.annotations.VisibleForTesting; import com.google.common.io.Closeables; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.config.Settings; import org.sonar.api.issue.internal.DefaultIssue; import org.sonar.api.platform.Server; +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.scan.filesystem.InputFile; import org.sonar.api.scan.filesystem.ModuleFileSystem; +import org.sonar.api.scan.filesystem.internal.DefaultInputFile; import org.sonar.api.user.User; import org.sonar.api.user.UserFinder; import org.sonar.api.utils.SonarException; @@ -39,8 +43,13 @@ import org.sonar.batch.bootstrap.AnalysisMode; import org.sonar.batch.events.BatchStepEvent; import org.sonar.batch.events.EventBus; import org.sonar.batch.issue.IssueCache; +import org.sonar.batch.scan.filesystem.InputFileCache; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -60,27 +69,23 @@ public class JsonReport implements BatchComponent { private final RuleFinder ruleFinder; private final IssueCache issueCache; private final EventBus eventBus; - private final ComponentSelector componentSelector; - private AnalysisMode analysisMode; - private UserFinder userFinder; + private final AnalysisMode analysisMode; + private final UserFinder userFinder; + private final InputFileCache fileCache; + private final Project rootModule; public JsonReport(Settings settings, ModuleFileSystem fileSystem, Server server, RuleFinder ruleFinder, IssueCache issueCache, - EventBus eventBus, ComponentSelectorFactory componentSelectorFactory, AnalysisMode mode, UserFinder userFinder) { - this(settings, fileSystem, server, ruleFinder, issueCache, eventBus, componentSelectorFactory.create(), mode, userFinder); - } - - @VisibleForTesting - JsonReport(Settings settings, ModuleFileSystem fileSystem, Server server, RuleFinder ruleFinder, IssueCache issueCache, - EventBus eventBus, ComponentSelector componentSelector, AnalysisMode analysisMode, UserFinder userFinder) { + EventBus eventBus, AnalysisMode analysisMode, UserFinder userFinder, Project rootModule, InputFileCache fileCache) { this.settings = settings; this.fileSystem = fileSystem; this.server = server; this.ruleFinder = ruleFinder; this.issueCache = issueCache; this.eventBus = eventBus; - this.componentSelector = componentSelector; this.analysisMode = analysisMode; this.userFinder = userFinder; + this.rootModule = rootModule; + this.fileCache = fileCache; } public void execute() { @@ -116,7 +121,6 @@ public class JsonReport implements BatchComponent { Set<RuleKey> ruleKeys = newHashSet(); Set<String> userLogins = newHashSet(); - componentSelector.init(); writeJsonIssues(json, ruleKeys, userLogins); writeJsonComponents(json); writeJsonRules(json, ruleKeys); @@ -132,7 +136,7 @@ public class JsonReport implements BatchComponent { private void writeJsonIssues(JsonWriter json, Set<RuleKey> ruleKeys, Set<String> logins) throws IOException { json.name("issues").beginArray(); for (DefaultIssue issue : getIssues()) { - if (issue.resolution() == null && componentSelector.register(issue)) { + if (issue.resolution() == null) { json .beginObject() .prop("key", issue.key()) @@ -165,15 +169,32 @@ public class JsonReport implements BatchComponent { private void writeJsonComponents(JsonWriter json) throws IOException { json.name("components").beginArray(); - for (String componentKey : componentSelector.componentKeys()) { + // Dump modules + writeJsonModuleComponents(json, rootModule); + // TODO we need to dump directories + for (InputFile inputFile : fileCache.all()) { json .beginObject() - .prop("key", componentKey) + .prop("key", inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY)) + .prop("path", inputFile.path()) + .prop("moduleKey", StringUtils.substringBeforeLast(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY), ":")) + .prop("status", inputFile.attribute(InputFile.ATTRIBUTE_STATUS)) .endObject(); } json.endArray(); } + private void writeJsonModuleComponents(JsonWriter json, Project module) { + json + .beginObject() + .prop("key", module.getEffectiveKey()) + .prop("path", module.getPath()) + .endObject(); + for (Project subModule : module.getModules()) { + writeJsonModuleComponents(json, subModule); + } + } + private void writeJsonRules(JsonWriter json, Set<RuleKey> ruleKeys) throws IOException { json.name("rules").beginArray(); for (RuleKey ruleKey : ruleKeys) { 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 3ed7a9ebfaf..e4b8a348509 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 @@ -29,16 +29,20 @@ import org.sonar.api.config.Settings; import org.sonar.api.issue.Issue; import org.sonar.api.issue.internal.DefaultIssue; import org.sonar.api.platform.Server; +import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; +import org.sonar.api.scan.filesystem.InputFile; import org.sonar.api.scan.filesystem.ModuleFileSystem; +import org.sonar.api.scan.filesystem.internal.DefaultInputFile; import org.sonar.api.user.User; import org.sonar.api.user.UserFinder; import org.sonar.batch.bootstrap.AnalysisMode; import org.sonar.batch.events.EventBus; import org.sonar.batch.issue.IssueCache; +import org.sonar.batch.scan.filesystem.InputFileCache; import org.sonar.core.user.DefaultUser; import org.sonar.test.TestUtils; @@ -82,14 +86,26 @@ public class JsonReportTest { mode = mock(AnalysisMode.class); when(mode.isPreview()).thenReturn(true); userFinder = mock(UserFinder.class); - jsonReport = new JsonReport(settings, fileSystem, server, ruleFinder, issueCache, mock(EventBus.class), new DefaultComponentSelector(), mode, userFinder); + InputFile inputFile = mock(InputFile.class); + when(inputFile.path()).thenReturn("src/main/java/org/apache/struts/Action.java"); + when(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY)).thenReturn("struts:src/main/java/org/apache/struts/Action.java"); + when(inputFile.attribute(InputFile.ATTRIBUTE_STATUS)).thenReturn(InputFile.STATUS_CHANGED); + InputFileCache fileCache = mock(InputFileCache.class); + when(fileCache.all()).thenReturn(Arrays.asList(inputFile)); + Project rootModule = new Project("struts"); + Project moduleA = new Project("struts-core"); + moduleA.setParent(rootModule).setPath("core"); + Project moduleB = new Project("struts-ui"); + moduleB.setParent(rootModule).setPath("ui"); + jsonReport = new JsonReport(settings, fileSystem, server, ruleFinder, issueCache, mock(EventBus.class), + mode, userFinder, rootModule, fileCache); } @Test public void should_write_json() throws Exception { DefaultIssue issue = new DefaultIssue() .setKey("200") - .setComponentKey("struts:/src/main/java/org/apache/struts/Action.java") + .setComponentKey("struts:src/main/java/org/apache/struts/Action.java") .setRuleKey(RuleKey.of("squid", "AvoidCycles")) .setMessage("There are 2 cycles") .setSeverity("MINOR") @@ -120,7 +136,7 @@ public class JsonReportTest { RuleKey ruleKey = RuleKey.of("squid", "AvoidCycles"); DefaultIssue issue = new DefaultIssue() .setKey("200") - .setComponentKey("struts:/src/main/java/org/apache/struts/Action.java") + .setComponentKey("struts:src/main/java/org/apache/struts/Action.java") .setRuleKey(ruleKey) .setStatus(Issue.STATUS_CLOSED) .setResolution(Issue.RESOLUTION_FIXED) diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report-without-resolved-issues.json b/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report-without-resolved-issues.json index 12f0bf5fee0..59c9c3272bb 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report-without-resolved-issues.json +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report-without-resolved-issues.json @@ -1,6 +1,22 @@ { "version": "3.6", "issues": [], - "components": [], + "components": [ + { + "key": "struts" + }, + { + "key": "struts-core", + "path": "core" + }, + { + "key": "struts-ui", + "path": "ui" + }, + { + "key": "struts:src/main/java/org/apache/struts/Action.java", + "path": "src/main/java/org/apache/struts/Action.java" + } +], "rules": [] } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report.json b/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report.json index 62bf4da8a75..7ff8f67abc0 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report.json +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/report/JsonReportTest/report.json @@ -1,7 +1,7 @@ {"version": "3.6", "issues": [ { "key": "200", - "component": "struts:/src/main/java/org/apache/struts/Action.java", + "component": "struts:src/main/java/org/apache/struts/Action.java", "line": 1, "message": "There are 2 cycles", "severity": "MINOR", @@ -16,7 +16,21 @@ } ], "components": [ { - "key": "struts:/src/main/java/org/apache/struts/Action.java" + "key": "struts" + }, + { + "key": "struts-core", + "path": "core" + }, + { + "key": "struts-ui", + "path": "ui" + }, + { + "key": "struts:src/main/java/org/apache/struts/Action.java", + "path": "src/main/java/org/apache/struts/Action.java", + "moduleKey": "struts", + "status": "CHANGED" } ], "rules": [ { |