aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine/src/main/java
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2017-01-17 17:45:09 +0100
committerDuarte Meneses <duarte.meneses@sonarsource.com>2017-01-27 16:26:30 +0100
commiteea589c564a924993e8edba9d8fa9691e756bce4 (patch)
treec112f6d41d7f4dfeb7ad8d14f895e1b879a68411 /sonar-scanner-engine/src/main/java
parent211a993bd85b5d12ace1686b133677381da8c597 (diff)
downloadsonarqube-eea589c564a924993e8edba9d8fa9691e756bce4.tar.gz
sonarqube-eea589c564a924993e8edba9d8fa9691e756bce4.zip
Refactor resources API
Diffstat (limited to 'sonar-scanner-engine/src/main/java')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultProjectTree.java101
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectAnalysisInfo.java (renamed from sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectConfigurator.java)38
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnary.java22
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java26
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java8
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java77
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/perspectives/ScannerPerspectives.java30
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponent.java84
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponentCache.java72
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/index/Bucket.java99
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/index/DefaultIndex.java262
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java17
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DeprecatedIssueAdapterForFilter.java18
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java27
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueTransformer.java6
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java21
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/IssueTransition.java29
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java29
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/ServerIssueRepository.java15
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/TaskResult.java8
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java14
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/InitializersExecutor.java14
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PostJobsExecutor.java10
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/ProjectAnalysisEvent.java10
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java14
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobContext.java12
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/profiling/PhasesSumUpTimeProfiler.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java163
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java26
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java23
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java27
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java26
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionAndCoveragePublisher.java20
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java58
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java119
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java27
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java31
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/BatchIdGenerator.java31
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ComponentIndexer.java68
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java25
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java61
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java6
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java (renamed from sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputPathCache.java)73
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java (renamed from sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputFileCache.java)32
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ConsoleReport.java6
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReport.java19
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReportBuilder.java37
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java23
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ResourceReport.java41
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/SourceProvider.java6
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java11
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmSensor.java16
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java6
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java13
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/source/CodeColorizerSensor.java10
58 files changed, 922 insertions, 1164 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultProjectTree.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultProjectTree.java
deleted file mode 100644
index c412cd15ead..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultProjectTree.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang.ObjectUtils;
-import org.picocontainer.Startable;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.resources.Project;
-import org.sonar.scanner.scan.ImmutableProjectReactor;
-
-public class DefaultProjectTree implements Startable {
-
- private final ProjectConfigurator configurator;
- private final ImmutableProjectReactor projectReactor;
-
- private List<Project> projects;
- private Map<ProjectDefinition, Project> projectsByDef;
-
- public DefaultProjectTree(ImmutableProjectReactor projectReactor, ProjectConfigurator projectConfigurator) {
- this.projectReactor = projectReactor;
- this.configurator = projectConfigurator;
- }
-
- @Override
- public void start() {
- doStart(projectReactor.getProjects());
- }
-
- @Override
- public void stop() {
- // Nothing to do
- }
-
- void doStart(Collection<ProjectDefinition> definitions) {
- projects = Lists.newArrayList();
- projectsByDef = Maps.newHashMap();
-
- for (ProjectDefinition def : definitions) {
- Project project = configurator.create(def);
- projectsByDef.put(def, project);
- projects.add(project);
- }
-
- for (Map.Entry<ProjectDefinition, Project> entry : projectsByDef.entrySet()) {
- ProjectDefinition def = entry.getKey();
- Project project = entry.getValue();
- for (ProjectDefinition module : def.getSubProjects()) {
- projectsByDef.get(module).setParent(project);
- }
- }
-
- // Configure
- for (Project project : projects) {
- configurator.configure(project);
- }
- }
-
- public List<Project> getProjects() {
- return projects;
- }
-
- public Project getRootProject() {
- for (Project project : projects) {
- if (project.getParent() == null) {
- return project;
- }
- }
- throw new IllegalStateException("Can not find the root project from the list of Maven modules");
- }
-
- public ProjectDefinition getProjectDefinition(Project project) {
- for (Map.Entry<ProjectDefinition, Project> entry : projectsByDef.entrySet()) {
- if (ObjectUtils.equals(entry.getValue(), project)) {
- return entry.getKey();
- }
- }
- throw new IllegalStateException("Can not find ProjectDefinition for " + project);
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectConfigurator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectAnalysisInfo.java
index 16ef6131a23..3441db14cef 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectConfigurator.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ProjectAnalysisInfo.java
@@ -20,12 +20,10 @@
package org.sonar.scanner;
import java.util.Date;
-import org.apache.commons.lang.StringUtils;
+import org.picocontainer.Startable;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Project;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.System2;
@@ -34,29 +32,24 @@ import org.sonar.api.utils.System2;
*
*/
@ScannerSide
-public class ProjectConfigurator {
-
+public class ProjectAnalysisInfo implements Startable {
private final System2 system2;
private Settings settings;
- public ProjectConfigurator(Settings settings, System2 system2) {
+ private Date analysisDate;
+ private String analysisVersion;
+
+ public ProjectAnalysisInfo(Settings settings, System2 system2) {
this.settings = settings;
this.system2 = system2;
}
- public Project create(ProjectDefinition definition) {
- Project project = new Project(definition.getKey(), definition.getBranch(), definition.getName());
- project.setDescription(StringUtils.defaultString(definition.getDescription()));
- project.setOriginalName(definition.getOriginalName());
- return project;
+ public Date analysisDate() {
+ return analysisDate;
}
- public ProjectConfigurator configure(Project project) {
- Date analysisDate = loadAnalysisDate();
- project
- .setAnalysisDate(analysisDate)
- .setAnalysisVersion(loadAnalysisVersion());
- return this;
+ public String analysisVersion() {
+ return analysisVersion;
}
private Date loadAnalysisDate() {
@@ -78,4 +71,15 @@ public class ProjectConfigurator {
private String loadAnalysisVersion() {
return settings.getString(CoreProperties.PROJECT_VERSION_PROPERTY);
}
+
+ @Override
+ public void start() {
+ this.analysisDate = loadAnalysisDate();
+ this.analysisVersion = loadAnalysisVersion();
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do
+ }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnary.java
index 1ffe0400337..1fbeed00db8 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnary.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnary.java
@@ -36,6 +36,7 @@ import org.sonar.api.batch.CheckProject;
import org.sonar.api.batch.DependedUpon;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.batch.Phase;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.postjob.PostJob;
import org.sonar.api.batch.postjob.PostJobContext;
import org.sonar.api.batch.sensor.Sensor;
@@ -61,7 +62,8 @@ public class ScannerExtensionDictionnary {
private final PostJobContext postJobContext;
private final PostJobOptimizer postJobOptimizer;
- public ScannerExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext sensorContext, SensorOptimizer sensorOptimizer, PostJobContext postJobContext,
+ public ScannerExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext sensorContext,
+ SensorOptimizer sensorOptimizer, PostJobContext postJobContext,
PostJobOptimizer postJobOptimizer) {
this.componentContainer = componentContainer;
this.sensorContext = sensorContext;
@@ -70,8 +72,8 @@ public class ScannerExtensionDictionnary {
this.postJobOptimizer = postJobOptimizer;
}
- public <T> Collection<T> select(Class<T> type, @Nullable Project project, boolean sort, @Nullable ExtensionMatcher matcher) {
- List<T> result = getFilteredExtensions(type, project, matcher);
+ public <T> Collection<T> select(Class<T> type, @Nullable DefaultInputModule module, boolean sort, @Nullable ExtensionMatcher matcher) {
+ List<T> result = getFilteredExtensions(type, module, matcher);
if (sort) {
return sort(result);
}
@@ -92,13 +94,13 @@ public class ScannerExtensionDictionnary {
return Phase.Name.DEFAULT;
}
- private <T> List<T> getFilteredExtensions(Class<T> type, @Nullable Project project, @Nullable ExtensionMatcher matcher) {
+ private <T> List<T> getFilteredExtensions(Class<T> type, @Nullable DefaultInputModule module, @Nullable ExtensionMatcher matcher) {
List<T> result = Lists.newArrayList();
for (Object extension : getExtensions(type)) {
if (org.sonar.api.batch.Sensor.class.equals(type) && extension instanceof Sensor) {
extension = new SensorWrapper((Sensor) extension, sensorContext, sensorOptimizer);
}
- if (shouldKeep(type, extension, project, matcher)) {
+ if (shouldKeep(type, extension, module, matcher)) {
result.add((T) extension);
}
}
@@ -106,7 +108,7 @@ public class ScannerExtensionDictionnary {
// Retrieve new Sensors and wrap then in SensorWrapper
for (Object extension : getExtensions(Sensor.class)) {
extension = new SensorWrapper((Sensor) extension, sensorContext, sensorOptimizer);
- if (shouldKeep(type, extension, project, matcher)) {
+ if (shouldKeep(type, extension, module, matcher)) {
result.add((T) extension);
}
}
@@ -115,7 +117,7 @@ public class ScannerExtensionDictionnary {
// Retrieve new PostJob and wrap then in PostJobWrapper
for (Object extension : getExtensions(PostJob.class)) {
extension = new PostJobWrapper((PostJob) extension, postJobContext, postJobOptimizer);
- if (shouldKeep(type, extension, project, matcher)) {
+ if (shouldKeep(type, extension, module, matcher)) {
result.add((T) extension);
}
}
@@ -253,12 +255,12 @@ public class ScannerExtensionDictionnary {
}
}
- private static boolean shouldKeep(Class type, Object extension, @Nullable Project project, @Nullable ExtensionMatcher matcher) {
+ private boolean shouldKeep(Class type, Object extension, @Nullable DefaultInputModule module, @Nullable ExtensionMatcher matcher) {
boolean keep = (ClassUtils.isAssignable(extension.getClass(), type)
|| (org.sonar.api.batch.Sensor.class.equals(type) && ClassUtils.isAssignable(extension.getClass(), Sensor.class)))
&& (matcher == null || matcher.accept(extension));
- if (keep && project != null && ClassUtils.isAssignable(extension.getClass(), CheckProject.class)) {
- keep = ((CheckProject) extension).shouldExecuteOnProject(project);
+ if (keep && module != null && ClassUtils.isAssignable(extension.getClass(), CheckProject.class)) {
+ keep = ((CheckProject) extension).shouldExecuteOnProject(new Project(module.definition()));
}
return keep;
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java
index db8ba5417cb..451d0a92642 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java
@@ -30,7 +30,10 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
@@ -40,12 +43,11 @@ import org.sonar.duplications.index.CloneGroup;
import org.sonar.duplications.index.ClonePart;
import org.sonar.duplications.index.PackedMemoryCloneIndex.ResourceBlocks;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Duplicate;
import org.sonar.scanner.protocol.output.ScannerReport.Duplication;
import org.sonar.scanner.report.ReportPublisher;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.util.ProgressReport;
import static com.google.common.collect.FluentIterable.from;
@@ -64,17 +66,17 @@ public class CpdExecutor {
private final SonarCpdBlockIndex index;
private final ReportPublisher publisher;
- private final BatchComponentCache batchComponentCache;
+ private final InputComponentStore componentStore;
private final Settings settings;
private final ProgressReport progressReport;
private int count;
private int total;
- public CpdExecutor(Settings settings, SonarCpdBlockIndex index, ReportPublisher publisher, BatchComponentCache batchComponentCache) {
+ public CpdExecutor(Settings settings, SonarCpdBlockIndex index, ReportPublisher publisher, InputComponentStore inputComponentCache) {
this.settings = settings;
this.index = index;
this.publisher = publisher;
- this.batchComponentCache = batchComponentCache;
+ this.componentStore = inputComponentCache;
this.progressReport = new ProgressReport("CPD computation", TimeUnit.SECONDS.toMillis(10));
}
@@ -106,13 +108,13 @@ public class CpdExecutor {
@VisibleForTesting
void runCpdAnalysis(ExecutorService executorService, String componentKey, final Collection<Block> fileBlocks, long timeout) {
- BatchComponent component = batchComponentCache.get(componentKey);
+ DefaultInputComponent component = (DefaultInputComponent) componentStore.getByKey(componentKey);
if (component == null) {
LOG.error("Resource not found in component cache: {}. Skipping CPD computation for it", componentKey);
return;
}
- InputFile inputFile = (InputFile) component.inputComponent();
+ InputFile inputFile = (InputFile) component;
LOG.debug("Detection of duplications for {}", inputFile.absolutePath());
progressReport.message(String.format("%d/%d - current file: %s", count, total, inputFile.absolutePath()));
@@ -156,9 +158,9 @@ public class CpdExecutor {
}
@VisibleForTesting
- final void saveDuplications(final BatchComponent component, List<CloneGroup> duplications) {
+ final void saveDuplications(final DefaultInputComponent component, List<CloneGroup> duplications) {
if (duplications.size() > MAX_CLONE_GROUP_PER_FILE) {
- LOG.warn("Too many duplication groups on file " + component.inputComponent() + ". Keep only the first " + MAX_CLONE_GROUP_PER_FILE +
+ LOG.warn("Too many duplication groups on file " + component + ". Keep only the first " + MAX_CLONE_GROUP_PER_FILE +
" groups.");
}
Iterable<ScannerReport.Duplication> reportDuplications = from(duplications)
@@ -177,7 +179,7 @@ public class CpdExecutor {
publisher.getWriter().writeComponentDuplications(component.batchId(), reportDuplications);
}
- private Duplication toReportDuplication(BatchComponent component, Duplication.Builder dupBuilder, Duplicate.Builder blockBuilder, CloneGroup input) {
+ private Duplication toReportDuplication(InputComponent component, Duplication.Builder dupBuilder, Duplicate.Builder blockBuilder, CloneGroup input) {
dupBuilder.clear();
ClonePart originBlock = input.getOriginPart();
blockBuilder.clear();
@@ -190,7 +192,7 @@ public class CpdExecutor {
if (!duplicate.equals(originBlock)) {
clonePartCount++;
if (clonePartCount > MAX_CLONE_PART_PER_GROUP) {
- LOG.warn("Too many duplication references on file " + component.inputComponent() + " for block at line " +
+ LOG.warn("Too many duplication references on file " + component + " for block at line " +
originBlock.getStartLine() + ". Keep only the first "
+ MAX_CLONE_PART_PER_GROUP + " references.");
break;
@@ -198,7 +200,7 @@ public class CpdExecutor {
blockBuilder.clear();
String componentKey = duplicate.getResourceId();
if (!component.key().equals(componentKey)) {
- BatchComponent sameProjectComponent = batchComponentCache.get(componentKey);
+ DefaultInputComponent sameProjectComponent = (DefaultInputComponent) componentStore.getByKey(componentKey);
blockBuilder.setOtherFileRef(sameProjectComponent.batchId());
}
dupBuilder.addDuplicate(blockBuilder
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java
index 619a06e4c20..3e701877e4f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java
@@ -27,6 +27,7 @@ import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;
@@ -34,7 +35,6 @@ import org.sonar.duplications.index.AbstractCloneIndex;
import org.sonar.duplications.index.CloneIndex;
import org.sonar.duplications.index.PackedMemoryCloneIndex;
import org.sonar.duplications.index.PackedMemoryCloneIndex.ResourceBlocks;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.FileStructure;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.report.ReportPublisher;
@@ -43,20 +43,18 @@ public class SonarCpdBlockIndex extends AbstractCloneIndex {
private final CloneIndex mem = new PackedMemoryCloneIndex();
private final ReportPublisher publisher;
- private final BatchComponentCache batchComponentCache;
private final Settings settings;
// Files already tokenized
private final Set<InputFile> indexedFiles = new HashSet<>();
- public SonarCpdBlockIndex(ReportPublisher publisher, BatchComponentCache batchComponentCache, Settings settings) {
+ public SonarCpdBlockIndex(ReportPublisher publisher, Settings settings) {
this.publisher = publisher;
- this.batchComponentCache = batchComponentCache;
this.settings = settings;
}
public void insert(InputFile inputFile, Collection<Block> blocks) {
if (isCrossProjectDuplicationEnabled(settings)) {
- int id = batchComponentCache.get(inputFile).batchId();
+ int id = ((DefaultInputFile) inputFile).batchId();
if (publisher.getWriter().hasComponentData(FileStructure.Domain.CPD_TEXT_BLOCKS, id)) {
throw new UnsupportedOperationException("Trying to save CPD tokens twice for the same file is not supported: " + inputFile.absolutePath());
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java
index 4b19f7d70d2..1908cf638b2 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java
@@ -26,7 +26,6 @@ import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.InputPath;
@@ -37,86 +36,83 @@ import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.core.component.ComponentKeys;
import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.sensor.DefaultSensorContext;
public class DeprecatedSensorContext extends DefaultSensorContext implements SensorContext {
-
private final DefaultIndex index;
- private final Project project;
+ private final InputModule module;
- public DeprecatedSensorContext(InputModule module, DefaultIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules,
+ public DeprecatedSensorContext(InputModule module, DefaultIndex index, Settings settings, FileSystem fs, ActiveRules activeRules,
AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime) {
super(module, settings, fs, activeRules, analysisMode, sensorStorage, sonarRuntime);
this.index = index;
- this.project = project;
-
- }
-
- public Project getProject() {
- return project;
+ this.module = module;
}
@Override
public Resource getParent(Resource reference) {
- return index.getParent(reference);
+ return index.getParent(reference.getEffectiveKey());
}
@Override
public Collection<Resource> getChildren(Resource reference) {
- return index.getChildren(reference);
+ return index.getChildren(reference.getEffectiveKey());
}
@Override
public <G extends Serializable> Measure<G> getMeasure(Metric<G> metric) {
- return index.getMeasure(project, metric);
+ return index.getMeasure(module.key(), metric);
+ }
+
+ private String getEffectiveKey(Resource r) {
+ if (r.getEffectiveKey() != null) {
+ return r.getEffectiveKey();
+ }
+
+ if (ResourceUtils.isProject(r) || /* For technical projects */ResourceUtils.isRootProject(r)) {
+ return r.getKey();
+ } else {
+ return ComponentKeys.createEffectiveKey(module.key(), r);
+ }
}
@Override
public <M> M getMeasures(MeasuresFilter<M> filter) {
- return index.getMeasures(project, filter);
+ return index.getMeasures(module.key(), filter);
}
@Override
public Measure saveMeasure(Measure measure) {
- return index.addMeasure(project, measure);
+ return index.addMeasure(module.key(), measure);
}
@Override
public Measure saveMeasure(Metric metric, Double value) {
- return index.addMeasure(project, new Measure(metric, value));
+ return index.addMeasure(module.key(), new Measure(metric, value));
}
@Override
public <G extends Serializable> Measure<G> getMeasure(Resource resource, Metric<G> metric) {
- return index.getMeasure(resource, metric);
+ return index.getMeasure(resource.getEffectiveKey(), metric);
}
@Override
public String saveResource(Resource resource) {
- Resource persistedResource = index.addResource(resource);
- if (persistedResource != null) {
- return persistedResource.getEffectiveKey();
- }
- return null;
- }
-
- public boolean saveResource(Resource resource, Resource parentReference) {
- return index.index(resource, parentReference);
+ throw new UnsupportedOperationException("No longer possible to save resources");
}
@Override
public Resource getResource(Resource resource) {
- return index.getResource(resource);
+ return index.getResource(getEffectiveKey(resource));
}
@Override
public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
- return index.getMeasures(resource, filter);
+ return index.getMeasures(getEffectiveKey(resource), filter);
}
@Override
@@ -126,9 +122,9 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen
}
@Override
- public Measure saveMeasure(Resource resource, Measure measure) {
+ public Measure saveMeasure(@Nullable Resource resource, Measure measure) {
Resource resourceOrProject = resourceOrProject(resource);
- return index.addMeasure(resourceOrProject, measure);
+ return index.addMeasure(getEffectiveKey(resourceOrProject), measure);
}
@Override
@@ -138,7 +134,7 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen
private Resource resourceOrProject(@Nullable Resource resource) {
if (resource == null) {
- return project;
+ return index.getResource(module.key());
}
Resource indexedResource = getResource(resource);
return indexedResource != null ? indexedResource : resource;
@@ -147,24 +143,17 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen
@Override
public Measure saveMeasure(InputFile inputFile, Metric metric, Double value) {
Measure<?> measure = new Measure(metric, value);
- return saveMeasure(getResource(inputFile), measure);
+ return saveMeasure(inputFile, measure);
}
@Override
public Measure saveMeasure(InputFile inputFile, Measure measure) {
- return saveMeasure(getResource(inputFile), measure);
+ return index.addMeasure(inputFile.key(), measure);
}
@Override
public Resource getResource(InputPath inputPath) {
- Resource r;
- if (inputPath instanceof InputDir) {
- r = Directory.create(((InputDir) inputPath).relativePath());
- } else if (inputPath instanceof InputFile) {
- r = File.create(((InputFile) inputPath).relativePath());
- } else {
- throw new IllegalArgumentException("Unknow input path type: " + inputPath);
- }
+ Resource r = index.toResource(inputPath);
return getResource(r);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/perspectives/ScannerPerspectives.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/perspectives/ScannerPerspectives.java
index 1903ef38b12..f15ba18ea66 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/perspectives/ScannerPerspectives.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/perspectives/ScannerPerspectives.java
@@ -23,21 +23,27 @@ import com.google.common.collect.Maps;
import java.util.Map;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.component.Perspective;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.resources.Resource;
-import org.sonar.scanner.index.BatchComponentCache;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.core.component.ComponentKeys;
import org.sonar.scanner.index.DefaultIndex;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
public class ScannerPerspectives implements ResourcePerspectives {
private final Map<Class<?>, PerspectiveBuilder<?>> builders = Maps.newHashMap();
private final DefaultIndex resourceIndex;
- private final BatchComponentCache componentCache;
+ private final InputComponentStore componentStore;
+ private final DefaultInputModule module;
- public ScannerPerspectives(PerspectiveBuilder[] builders, DefaultIndex resourceIndex, BatchComponentCache componentCache) {
+ public ScannerPerspectives(PerspectiveBuilder[] builders, DefaultInputModule module, DefaultIndex resourceIndex, InputComponentStore componentStore) {
this.resourceIndex = resourceIndex;
- this.componentCache = componentCache;
+ this.componentStore = componentStore;
+ this.module = module;
+
for (PerspectiveBuilder builder : builders) {
this.builders.put(builder.getPerspectiveClass(), builder);
}
@@ -48,15 +54,27 @@ public class ScannerPerspectives implements ResourcePerspectives {
public <P extends Perspective> P as(Class<P> perspectiveClass, Resource resource) {
Resource indexedResource = resource;
if (resource.getEffectiveKey() == null) {
- indexedResource = resourceIndex.getResource(resource);
+ indexedResource = resourceIndex.getResource(getEffectiveKey(resource));
}
if (indexedResource != null) {
PerspectiveBuilder<P> builder = builderFor(perspectiveClass);
- return builder.loadPerspective(perspectiveClass, componentCache.get(indexedResource).inputComponent());
+ return builder.loadPerspective(perspectiveClass, componentStore.getByKey(indexedResource.getEffectiveKey()));
}
return null;
}
+ private String getEffectiveKey(Resource r) {
+ if (r.getEffectiveKey() != null) {
+ return r.getEffectiveKey();
+ }
+
+ if (ResourceUtils.isProject(r) || /* For technical projects */ResourceUtils.isRootProject(r)) {
+ return r.getKey();
+ } else {
+ return ComponentKeys.createEffectiveKey(module.key(), r);
+ }
+ }
+
@Override
public <P extends Perspective> P as(Class<P> perspectiveClass, InputPath inputPath) {
PerspectiveBuilder<P> builder = builderFor(perspectiveClass);
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponent.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponent.java
deleted file mode 100644
index bf522d96bdc..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponent.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.index;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.sonar.api.batch.fs.InputComponent;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-
-public class BatchComponent {
-
- private final int batchId;
- private final Resource r;
- private final BatchComponent parent;
- private final Collection<BatchComponent> children = new ArrayList<>();
- private InputComponent inputComponent;
-
- public BatchComponent(int batchId, Resource r, @Nullable BatchComponent parent) {
- this.batchId = batchId;
- this.r = r;
- this.parent = parent;
- if (parent != null) {
- parent.children.add(this);
- }
- }
-
- public String key() {
- return r.getEffectiveKey();
- }
-
- public int batchId() {
- return batchId;
- }
-
- public Resource resource() {
- return r;
- }
-
- @CheckForNull
- public BatchComponent parent() {
- return parent;
- }
-
- public Collection<BatchComponent> children() {
- return children;
- }
-
- public boolean isFile() {
- return this.inputComponent.isFile();
- }
-
- public BatchComponent setInputComponent(InputComponent inputComponent) {
- this.inputComponent = inputComponent;
- return this;
- }
-
- public InputComponent inputComponent() {
- return inputComponent;
- }
-
- public boolean isProjectOrModule() {
- return ResourceUtils.isProject(r);
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponentCache.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponentCache.java
deleted file mode 100644
index 0a2248c9fb5..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/BatchComponentCache.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.index;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
-import java.util.Collection;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.batch.fs.InputComponent;
-import org.sonar.api.resources.Resource;
-
-@ScannerSide
-public class BatchComponentCache {
- // components by key
- private final Map<String, BatchComponent> components = Maps.newLinkedHashMap();
-
- private BatchComponent root;
-
- @CheckForNull
- public BatchComponent get(String componentKey) {
- return components.get(componentKey);
- }
-
- public BatchComponent get(Resource resource) {
- return components.get(resource.getEffectiveKey());
- }
-
- public BatchComponent get(InputComponent inputComponent) {
- return components.get(inputComponent.key());
- }
-
- public BatchComponent add(Resource resource, @Nullable Resource parentResource) {
- String componentKey = resource.getEffectiveKey();
- Preconditions.checkState(!Strings.isNullOrEmpty(componentKey), "Missing resource effective key");
- BatchComponent parent = parentResource != null ? get(parentResource.getEffectiveKey()) : null;
- BatchComponent batchComponent = new BatchComponent(components.size() + 1, resource, parent);
- components.put(componentKey, batchComponent);
- if (parent == null) {
- root = batchComponent;
- }
- return batchComponent;
- }
-
- public Collection<BatchComponent> all() {
- return components.values();
- }
-
- public BatchComponent getRoot() {
- return root;
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/Bucket.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/Bucket.java
deleted file mode 100644
index 72f41198053..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/Bucket.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.index;
-
-import com.google.common.collect.Lists;
-import org.sonar.api.resources.Resource;
-
-import javax.annotation.Nullable;
-
-import java.util.Collections;
-import java.util.List;
-
-public final class Bucket {
-
- private Resource resource;
-
- private Bucket parent;
- private List<Bucket> children;
-
- public Bucket(Resource resource) {
- this.resource = resource;
- }
-
- public Resource getResource() {
- return resource;
- }
-
- public Bucket setParent(@Nullable Bucket parent) {
- this.parent = parent;
- if (parent != null) {
- parent.addChild(this);
- }
- return this;
- }
-
- private Bucket addChild(Bucket child) {
- if (children == null) {
- children = Lists.newArrayList();
- }
- children.add(child);
- return this;
- }
-
- private void removeChild(Bucket child) {
- if (children != null) {
- children.remove(child);
- }
- }
-
- public List<Bucket> getChildren() {
- return children == null ? Collections.<Bucket>emptyList() : children;
- }
-
- public Bucket getParent() {
- return parent;
- }
-
- public void clear() {
- children = null;
- if (parent != null) {
- parent.removeChild(this);
- parent = null;
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- Bucket that = (Bucket) o;
- return resource.equals(that.resource);
- }
-
- @Override
- public int hashCode() {
- return resource.hashCode();
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/DefaultIndex.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/DefaultIndex.java
index a1db20b949e..48ba1cbf2ab 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/DefaultIndex.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/index/DefaultIndex.java
@@ -19,146 +19,70 @@
*/
package org.sonar.scanner.index;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+
import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
+
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.InputDir;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputComponentTree;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.MeasuresFilters;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metric.ValueType;
+import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.core.component.ComponentKeys;
import org.sonar.core.util.stream.Collectors;
-import org.sonar.scanner.DefaultProjectTree;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.scan.measure.MeasureCache;
import org.sonar.scanner.sensor.DefaultSensorStorage;
public class DefaultIndex {
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultIndex.class);
-
- private final BatchComponentCache componentCache;
+ private final InputComponentStore componentStore;
private final MeasureCache measureCache;
- private final DefaultProjectTree projectTree;
private final MetricFinder metricFinder;
// caches
private DefaultSensorStorage sensorStorage;
- private Project currentProject;
- private Map<Resource, Bucket> buckets = Maps.newLinkedHashMap();
- public DefaultIndex(BatchComponentCache componentCache, DefaultProjectTree projectTree, MeasureCache measureCache, MetricFinder metricFinder) {
- this.componentCache = componentCache;
- this.projectTree = projectTree;
+ private InputComponentTree tree;
+
+ public DefaultIndex(InputComponentStore componentStore, InputComponentTree tree, MeasureCache measureCache, MetricFinder metricFinder) {
+ this.componentStore = componentStore;
+ this.tree = tree;
this.measureCache = measureCache;
this.metricFinder = metricFinder;
}
- public void start() {
- Project rootProject = projectTree.getRootProject();
- if (StringUtils.isNotBlank(rootProject.getKey())) {
- doStart(rootProject);
- }
- }
-
- void doStart(Project rootProject) {
- Bucket bucket = new Bucket(rootProject);
- addBucket(rootProject, bucket);
- BatchComponent component = componentCache.add(rootProject, null);
- component.setInputComponent(new DefaultInputModule(rootProject.getEffectiveKey()));
- currentProject = rootProject;
-
- for (Project module : rootProject.getModules()) {
- addModule(rootProject, module);
- }
- }
-
- private void addBucket(Resource resource, Bucket bucket) {
- buckets.put(resource, bucket);
- }
-
- private void addModule(Project parent, Project module) {
- ProjectDefinition parentDefinition = projectTree.getProjectDefinition(parent);
- java.io.File parentBaseDir = parentDefinition.getBaseDir();
- ProjectDefinition moduleDefinition = projectTree.getProjectDefinition(module);
- java.io.File moduleBaseDir = moduleDefinition.getBaseDir();
- module.setPath(new PathResolver().relativePath(parentBaseDir, moduleBaseDir));
- addResource(module);
- for (Project submodule : module.getModules()) {
- addModule(module, submodule);
- }
- }
-
- public Project getProject() {
- return currentProject;
- }
-
- public void setCurrentProject(Project project, DefaultSensorStorage sensorStorage) {
- this.currentProject = project;
-
+ public void setCurrentProject(DefaultSensorStorage sensorStorage) {
// the following components depend on the current module, so they need to be reloaded.
this.sensorStorage = sensorStorage;
}
- /**
- * Keep only project stuff
- */
- public void clear() {
- Iterator<Map.Entry<Resource, Bucket>> it = buckets.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<Resource, Bucket> entry = it.next();
- Resource resource = entry.getKey();
- if (!ResourceUtils.isSet(resource)) {
- entry.getValue().clear();
- it.remove();
- }
-
- }
- }
-
@CheckForNull
- public Measure getMeasure(Resource resource, org.sonar.api.batch.measure.Metric<?> metric) {
- return getMeasures(resource, MeasuresFilters.metric(metric));
+ public Measure getMeasure(String key, org.sonar.api.batch.measure.Metric<?> metric) {
+ return getMeasures(key, MeasuresFilters.metric(metric));
}
@CheckForNull
- public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
- // Reload resource so that effective key is populated
- Resource indexedResource = getResource(resource);
- if (indexedResource == null) {
- return null;
- }
+ public <M> M getMeasures(String key, MeasuresFilter<M> filter) {
Collection<DefaultMeasure<?>> unfiltered = new ArrayList<>();
if (filter instanceof MeasuresFilters.MetricFilter) {
// optimization
- DefaultMeasure<?> byMetric = measureCache.byMetric(indexedResource.getEffectiveKey(), ((MeasuresFilters.MetricFilter<M>) filter).filterOnMetricKey());
+ DefaultMeasure<?> byMetric = measureCache.byMetric(key, ((MeasuresFilters.MetricFilter<M>) filter).filterOnMetricKey());
if (byMetric != null) {
unfiltered.add(byMetric);
}
} else {
- for (DefaultMeasure<?> measure : measureCache.byComponentKey(indexedResource.getEffectiveKey())) {
+ for (DefaultMeasure<?> measure : measureCache.byComponentKey(key)) {
unfiltered.add(measure);
}
}
@@ -196,10 +120,10 @@ public class DefaultIndex {
}
}
- public Measure addMeasure(Resource resource, Measure measure) {
- Bucket bucket = getBucket(resource);
- if (bucket == null) {
- return measure;
+ public Measure addMeasure(String key, Measure measure) {
+ InputComponent component = componentStore.getByKey(key);
+ if (component == null) {
+ throw new IllegalStateException("Invalid component key: " + key);
}
if (sensorStorage.isDeprecatedMetric(measure.getMetricKey())) {
// Ignore deprecated metrics
@@ -228,130 +152,52 @@ public class DefaultIndex {
} else {
throw new UnsupportedOperationException("Unsupported type :" + metric.valueType());
}
- sensorStorage.saveMeasure(componentCache.get(resource).inputComponent(), newMeasure);
+ sensorStorage.saveMeasure(component, newMeasure);
return measure;
}
- public Dependency addDependency(Dependency dependency) {
- return dependency;
- }
-
- public Set<Resource> getResources() {
- return buckets.keySet();
- }
-
- public String getSource(Resource reference) {
- Resource resource = getResource(reference);
- if (resource instanceof File) {
- File file = (File) resource;
- Project module = currentProject;
- ProjectDefinition def = projectTree.getProjectDefinition(module);
- try {
- return FileUtils.readFileToString(new java.io.File(def.getBaseDir(), file.getPath()));
- } catch (IOException e) {
- throw new IllegalStateException("Unable to read file content " + reference, e);
- }
- }
- return null;
- }
-
- /**
- * Does nothing if the resource is already registered.
- */
- public Resource addResource(Resource resource) {
- Bucket bucket = doIndex(resource);
- return bucket != null ? bucket.getResource() : null;
- }
-
@CheckForNull
- public <R extends Resource> R getResource(@Nullable R reference) {
- Bucket bucket = getBucket(reference);
- if (bucket != null) {
- return (R) bucket.getResource();
- }
- return null;
- }
-
- public List<Resource> getChildren(Resource resource) {
- List<Resource> children = Lists.newLinkedList();
- Bucket bucket = getBucket(resource);
- if (bucket != null) {
- for (Bucket childBucket : bucket.getChildren()) {
- children.add(childBucket.getResource());
- }
+ public Resource getParent(String key) {
+ InputComponent component = componentStore.getByKey(key);
+ if (component == null) {
+ return null;
}
- return children;
- }
-
- public Resource getParent(Resource resource) {
- Bucket bucket = getBucket(resource);
- if (bucket != null && bucket.getParent() != null) {
- return bucket.getParent().getResource();
+ InputComponent parent = tree.getParent(component);
+ if (parent == null) {
+ return null;
}
- return null;
- }
-
- public boolean index(Resource resource) {
- Bucket bucket = doIndex(resource);
- return bucket != null;
- }
- private Bucket doIndex(Resource resource) {
- if (resource.getParent() != null) {
- doIndex(resource.getParent());
- }
- return doIndex(resource, resource.getParent());
+ return toResource(parent);
}
- public boolean index(Resource resource, Resource parentReference) {
- Bucket bucket = doIndex(resource, parentReference);
- return bucket != null;
+ public Collection<Resource> getChildren(String key) {
+ InputComponent component = componentStore.getByKey(key);
+ Collection<InputComponent> children = tree.getChildren(component);
+ return children.stream().map(this::toResource).collect(Collectors.toList());
}
- private Bucket doIndex(Resource resource, @Nullable Resource parentReference) {
- Bucket bucket = getBucket(resource);
- if (bucket != null) {
- return bucket;
- }
-
- if (StringUtils.isBlank(resource.getKey())) {
- LOG.warn("Unable to index a resource without key: {}", resource);
- return null;
- }
-
- Resource parent = (Resource) ObjectUtils.defaultIfNull(parentReference, currentProject);
-
- Bucket parentBucket = getBucket(parent);
- if (parentBucket == null && parent != null) {
- LOG.warn("Resource ignored, parent is not indexed: {}", resource);
- return null;
- }
-
- if (ResourceUtils.isProject(resource) || /* For technical projects */ResourceUtils.isRootProject(resource)) {
- resource.setEffectiveKey(resource.getKey());
+ public Resource toResource(InputComponent inputComponent) {
+ Resource r;
+ if (inputComponent instanceof InputDir) {
+ r = Directory.create(((InputDir) inputComponent).relativePath());
+ } else if (inputComponent instanceof InputFile) {
+ r = File.create(((InputFile) inputComponent).relativePath());
+ } else if (inputComponent instanceof InputModule) {
+ r = new Project(((DefaultInputModule) inputComponent).definition());
} else {
- resource.setEffectiveKey(ComponentKeys.createEffectiveKey(currentProject, resource));
- }
- bucket = new Bucket(resource).setParent(parentBucket);
- addBucket(resource, bucket);
-
- Resource parentResource = parentBucket != null ? parentBucket.getResource() : null;
- BatchComponent component = componentCache.add(resource, parentResource);
- if (ResourceUtils.isProject(resource)) {
- component.setInputComponent(new DefaultInputModule(resource.getEffectiveKey()));
+ throw new IllegalArgumentException("Unknow input path type: " + inputComponent);
}
- return bucket;
+ r.setEffectiveKey(inputComponent.key());
+ return r;
}
- private Bucket getBucket(@Nullable Resource reference) {
- if (reference == null) {
+ @CheckForNull
+ public Resource getResource(String key) {
+ InputComponent component = componentStore.getByKey(key);
+ if (component == null) {
return null;
}
- if (StringUtils.isNotBlank(reference.getKey())) {
- return buckets.get(reference);
- }
- return null;
+ return toResource(component);
}
-
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java
index b0cc7c3bb0d..06782401e14 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java
@@ -22,21 +22,24 @@ package org.sonar.scanner.issue;
import java.util.Date;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.resources.Project;
+import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.scan.issue.filter.FilterableIssue;
+import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.protocol.output.ScannerReport.Issue;
public class DefaultFilterableIssue implements FilterableIssue {
private final Issue rawIssue;
- private final Project project;
+ private final ProjectAnalysisInfo projectAnalysisInfo;
private final String componentKey;
+ private DefaultInputModule module;
- public DefaultFilterableIssue(Project project, Issue rawIssue, String componentKey) {
- this.project = project;
+ public DefaultFilterableIssue(InputModule module, ProjectAnalysisInfo projectAnalysisInfo, Issue rawIssue, String componentKey) {
+ this.module = (DefaultInputModule) module;
+ this.projectAnalysisInfo = projectAnalysisInfo;
this.rawIssue = rawIssue;
this.componentKey = componentKey;
-
}
@Override
@@ -76,12 +79,12 @@ public class DefaultFilterableIssue implements FilterableIssue {
@Override
public Date creationDate() {
- return project.getAnalysisDate();
+ return projectAnalysisInfo.analysisDate();
}
@Override
public String projectKey() {
- return project.getEffectiveKey();
+ return module.key();
}
@Override
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DeprecatedIssueAdapterForFilter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DeprecatedIssueAdapterForFilter.java
index d52ed3ad19e..00cf22d19b2 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DeprecatedIssueAdapterForFilter.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DeprecatedIssueAdapterForFilter.java
@@ -24,23 +24,29 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
+
+import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueComment;
-import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.Duration;
+import org.sonar.scanner.ProjectAnalysisInfo;
/**
* @deprecated since 5.3
*/
@Deprecated
class DeprecatedIssueAdapterForFilter implements Issue {
- private final Project project;
private final org.sonar.scanner.protocol.output.ScannerReport.Issue rawIssue;
private final String componentKey;
+ private DefaultInputModule module;
+ private ProjectAnalysisInfo projectAnalysisInfo;
- DeprecatedIssueAdapterForFilter(Project project, org.sonar.scanner.protocol.output.ScannerReport.Issue rawIssue, String componentKey) {
- this.project = project;
+ DeprecatedIssueAdapterForFilter(InputModule module, ProjectAnalysisInfo projectAnalysisInfo, org.sonar.scanner.protocol.output.ScannerReport.Issue rawIssue,
+ String componentKey) {
+ this.module = (DefaultInputModule) module;
+ this.projectAnalysisInfo = projectAnalysisInfo;
this.rawIssue = rawIssue;
this.componentKey = componentKey;
}
@@ -113,7 +119,7 @@ class DeprecatedIssueAdapterForFilter implements Issue {
@Override
public Date creationDate() {
- return project.getAnalysisDate();
+ return projectAnalysisInfo.analysisDate();
}
@Override
@@ -169,7 +175,7 @@ class DeprecatedIssueAdapterForFilter implements Issue {
@Override
public String projectKey() {
- return project.getEffectiveKey();
+ return module.definition().getKeyWithBranch();
}
@Override
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java
index 346f3803464..f485dec405c 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java
@@ -22,39 +22,42 @@ package org.sonar.scanner.issue;
import org.sonar.api.scan.issue.filter.FilterableIssue;
import org.sonar.api.scan.issue.filter.IssueFilterChain;
+import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.issue.Issue;
import org.sonar.api.scan.issue.filter.IssueFilter;
-import org.sonar.api.resources.Project;
@ScannerSide
public class IssueFilters {
private final IssueFilter[] filters;
private final org.sonar.api.issue.batch.IssueFilter[] deprecatedFilters;
- private final Project project;
+ private final InputModule module;
+ private final ProjectAnalysisInfo projectAnalysisInfo;
- public IssueFilters(Project project, IssueFilter[] exclusionFilters, org.sonar.api.issue.batch.IssueFilter[] filters) {
- this.project = project;
+ public IssueFilters(InputModule module, ProjectAnalysisInfo projectAnalysisInfo, IssueFilter[] exclusionFilters, org.sonar.api.issue.batch.IssueFilter[] filters) {
+ this.module = module;
this.filters = exclusionFilters;
this.deprecatedFilters = filters;
+ this.projectAnalysisInfo = projectAnalysisInfo;
}
- public IssueFilters(Project project, IssueFilter[] filters) {
- this(project, filters, new org.sonar.api.issue.batch.IssueFilter[0]);
+ public IssueFilters(InputModule module, ProjectAnalysisInfo projectAnalysisInfo, IssueFilter[] filters) {
+ this(module, projectAnalysisInfo, filters, new org.sonar.api.issue.batch.IssueFilter[0]);
}
- public IssueFilters(Project project, org.sonar.api.issue.batch.IssueFilter[] deprecatedFilters) {
- this(project, new IssueFilter[0], deprecatedFilters);
+ public IssueFilters(InputModule module, ProjectAnalysisInfo projectAnalysisInfo, org.sonar.api.issue.batch.IssueFilter[] deprecatedFilters) {
+ this(module, projectAnalysisInfo, new IssueFilter[0], deprecatedFilters);
}
- public IssueFilters(Project project) {
- this(project, new IssueFilter[0], new org.sonar.api.issue.batch.IssueFilter[0]);
+ public IssueFilters(InputModule module, ProjectAnalysisInfo projectAnalysisInfo) {
+ this(module, projectAnalysisInfo, new IssueFilter[0], new org.sonar.api.issue.batch.IssueFilter[0]);
}
public boolean accept(String componentKey, ScannerReport.Issue rawIssue) {
IssueFilterChain filterChain = new DefaultIssueFilterChain(filters);
- FilterableIssue fIssue = new DefaultFilterableIssue(project, rawIssue, componentKey);
+ FilterableIssue fIssue = new DefaultFilterableIssue(module, projectAnalysisInfo, rawIssue, componentKey);
if (filterChain.accept(fIssue)) {
return acceptDeprecated(componentKey, rawIssue);
}
@@ -63,7 +66,7 @@ public class IssueFilters {
}
public boolean acceptDeprecated(String componentKey, ScannerReport.Issue rawIssue) {
- Issue issue = new DeprecatedIssueAdapterForFilter(project, rawIssue, componentKey);
+ Issue issue = new DeprecatedIssueAdapterForFilter(module, projectAnalysisInfo, rawIssue, componentKey);
return new DeprecatedIssueFilterChain(deprecatedFilters).accept(issue);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueTransformer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueTransformer.java
index 2c2a31535c7..cf6e5ec30c6 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueTransformer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueTransformer.java
@@ -26,11 +26,11 @@ import java.util.Date;
import java.util.List;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.util.Uuids;
-import org.sonar.scanner.index.BatchComponent;
import org.sonar.scanner.issue.tracking.SourceHashHolder;
import org.sonar.scanner.issue.tracking.TrackedIssue;
import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue;
@@ -73,7 +73,7 @@ public class IssueTransformer {
issue.setResolution(Issue.RESOLUTION_REMOVED);
}
- public static Collection<TrackedIssue> toTrackedIssue(BatchComponent component, Collection<ScannerReport.Issue> rawIssues, @Nullable SourceHashHolder hashes) {
+ public static Collection<TrackedIssue> toTrackedIssue(InputComponent component, Collection<ScannerReport.Issue> rawIssues, @Nullable SourceHashHolder hashes) {
List<TrackedIssue> issues = new ArrayList<>(rawIssues.size());
for (ScannerReport.Issue issue : rawIssues) {
@@ -83,7 +83,7 @@ public class IssueTransformer {
return issues;
}
- public static TrackedIssue toTrackedIssue(BatchComponent component, ScannerReport.Issue rawIssue, @Nullable SourceHashHolder hashes) {
+ public static TrackedIssue toTrackedIssue(InputComponent component, ScannerReport.Issue rawIssue, @Nullable SourceHashHolder hashes) {
RuleKey ruleKey = RuleKey.of(rawIssue.getRuleRepository(), rawIssue.getRuleKey());
Preconditions.checkNotNull(component.key(), "Component key must be set");
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java
index 3fe3d2ef369..e618b1ddb96 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java
@@ -20,8 +20,8 @@
package org.sonar.scanner.issue;
import com.google.common.base.Strings;
-import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.Rule;
@@ -30,8 +30,6 @@ import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.issue.Issue.Flow;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.Constants.Severity;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.IssueLocation;
@@ -46,19 +44,16 @@ public class ModuleIssues {
private final Rules rules;
private final IssueFilters filters;
private final ReportPublisher reportPublisher;
- private final BatchComponentCache componentCache;
- public ModuleIssues(ActiveRules activeRules, Rules rules, IssueFilters filters, ReportPublisher reportPublisher, BatchComponentCache componentCache) {
+ public ModuleIssues(ActiveRules activeRules, Rules rules, IssueFilters filters, ReportPublisher reportPublisher) {
this.activeRules = activeRules;
this.rules = rules;
this.filters = filters;
this.reportPublisher = reportPublisher;
- this.componentCache = componentCache;
}
public boolean initAndAddIssue(Issue issue) {
- InputComponent inputComponent = issue.primaryLocation().inputComponent();
- BatchComponent component = componentCache.get(inputComponent);
+ DefaultInputComponent inputComponent = (DefaultInputComponent) issue.primaryLocation().inputComponent();
Rule rule = validateRule(issue);
ActiveRule activeRule = activeRules.find(issue.ruleKey());
@@ -81,7 +76,7 @@ public class ModuleIssues {
builder.setMsg(primaryMessage);
locationBuilder.setMsg(primaryMessage);
- locationBuilder.setComponentRef(component.batchId());
+ locationBuilder.setComponentRef(inputComponent.batchId());
TextRange primaryTextRange = issue.primaryLocation().textRange();
if (primaryTextRange != null) {
builder.setTextRange(toProtobufTextRange(textRangeBuilder, primaryTextRange));
@@ -94,7 +89,7 @@ public class ModuleIssues {
ScannerReport.Issue rawIssue = builder.build();
if (filters.accept(inputComponent.key(), rawIssue)) {
- write(component, rawIssue);
+ write(inputComponent.batchId(), rawIssue);
return true;
}
return false;
@@ -107,7 +102,7 @@ public class ModuleIssues {
flowBuilder.clear();
for (org.sonar.api.batch.sensor.issue.IssueLocation location : flow.locations()) {
locationBuilder.clear();
- locationBuilder.setComponentRef(componentCache.get(location.inputComponent()).batchId());
+ locationBuilder.setComponentRef(((DefaultInputComponent) location.inputComponent()).batchId());
String message = location.message();
if (message != null) {
locationBuilder.setMsg(message);
@@ -144,8 +139,8 @@ public class ModuleIssues {
return rule;
}
- public void write(BatchComponent component, ScannerReport.Issue rawIssue) {
- reportPublisher.getWriter().appendComponentIssue(component.batchId(), rawIssue);
+ public void write(int batchId, ScannerReport.Issue rawIssue) {
+ reportPublisher.getWriter().appendComponentIssue(batchId, rawIssue);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/IssueTransition.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/IssueTransition.java
index 9c3da91e702..99c47fb064b 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/IssueTransition.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/IssueTransition.java
@@ -20,15 +20,16 @@
package org.sonar.scanner.issue.tracking;
import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.resources.Project;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.core.util.CloseableIterator;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
+import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.issue.IssueCache;
import org.sonar.scanner.issue.IssueTransformer;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.report.ReportPublisher;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.util.ProgressReport;
import javax.annotation.Nullable;
@@ -41,23 +42,23 @@ import java.util.concurrent.TimeUnit;
@ScannerSide
public class IssueTransition {
private final IssueCache issueCache;
- private final BatchComponentCache componentCache;
+ private final InputComponentStore inputComponentStore;
private final ReportPublisher reportPublisher;
private final Date analysisDate;
@Nullable
private final LocalIssueTracking localIssueTracking;
- public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, ReportPublisher reportPublisher,
+ public IssueTransition(InputComponentStore inputComponentCache, ProjectAnalysisInfo projectAnalysisInfo, IssueCache issueCache, ReportPublisher reportPublisher,
@Nullable LocalIssueTracking localIssueTracking) {
- this.componentCache = componentCache;
+ this.inputComponentStore = inputComponentCache;
this.issueCache = issueCache;
this.reportPublisher = reportPublisher;
this.localIssueTracking = localIssueTracking;
- this.analysisDate = ((Project) componentCache.getRoot().resource()).getAnalysisDate();
+ this.analysisDate = projectAnalysisInfo.analysisDate();
}
- public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, ReportPublisher reportPublisher) {
- this(componentCache, issueCache, reportPublisher, null);
+ public IssueTransition(InputComponentStore inputComponentCache, ProjectAnalysisInfo projectAnalysisInfo, IssueCache issueCache, ReportPublisher reportPublisher) {
+ this(inputComponentCache, projectAnalysisInfo, issueCache, reportPublisher, null);
}
public void execute() {
@@ -66,7 +67,7 @@ public class IssueTransition {
}
ScannerReportReader reader = new ScannerReportReader(reportPublisher.getReportDir());
- int nbComponents = componentCache.all().size();
+ int nbComponents = inputComponentStore.all().size();
if (nbComponents == 0) {
return;
@@ -77,8 +78,8 @@ public class IssueTransition {
int count = 0;
try {
- for (BatchComponent component : componentCache.all()) {
- trackIssues(reader, component);
+ for (InputComponent component : inputComponentStore.all()) {
+ trackIssues(reader, (DefaultInputComponent) component);
count++;
progressReport.message(count + "/" + nbComponents + " components tracked");
}
@@ -87,7 +88,7 @@ public class IssueTransition {
}
}
- public void trackIssues(ScannerReportReader reader, BatchComponent component) {
+ public void trackIssues(ScannerReportReader reader, DefaultInputComponent component) {
// raw issues = all the issues created by rule engines during this module scan and not excluded by filters
List<ScannerReport.Issue> rawIssues = new LinkedList<>();
try (CloseableIterator<ScannerReport.Issue> it = reader.readComponentIssues(component.batchId())) {
@@ -110,7 +111,7 @@ public class IssueTransition {
}
}
- private static List<TrackedIssue> doTransition(List<ScannerReport.Issue> rawIssues, BatchComponent component) {
+ private static List<TrackedIssue> doTransition(List<ScannerReport.Issue> rawIssues, InputComponent component) {
List<TrackedIssue> issues = new ArrayList<>(rawIssues.size());
for (ScannerReport.Issue issue : rawIssues) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java
index e83785cf44b..465d4bbce7c 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java
@@ -20,6 +20,8 @@
package org.sonar.scanner.issue.tracking;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -30,17 +32,18 @@ import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Status;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.InputComponentTree;
import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.api.batch.rule.ActiveRules;
-import org.sonar.api.resources.ResourceUtils;
import org.sonar.core.issue.tracking.Input;
import org.sonar.core.issue.tracking.Tracker;
import org.sonar.core.issue.tracking.Tracking;
import org.sonar.scanner.analysis.DefaultAnalysisMode;
-import org.sonar.scanner.index.BatchComponent;
import org.sonar.scanner.issue.IssueTransformer;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.repository.ProjectRepositories;
@@ -52,13 +55,15 @@ public class LocalIssueTracking {
private final ActiveRules activeRules;
private final ServerIssueRepository serverIssueRepository;
private final DefaultAnalysisMode mode;
+ private final InputComponentTree componentTree;
private boolean hasServerAnalysis;
- public LocalIssueTracking(Tracker<TrackedIssue, ServerIssueFromWs> tracker, ServerLineHashesLoader lastLineHashes,
+ public LocalIssueTracking(Tracker<TrackedIssue, ServerIssueFromWs> tracker, ServerLineHashesLoader lastLineHashes, InputComponentTree componentTree,
ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) {
this.tracker = tracker;
this.lastLineHashes = lastLineHashes;
+ this.componentTree = componentTree;
this.serverIssueRepository = serverIssueRepository;
this.mode = mode;
this.activeRules = activeRules;
@@ -71,7 +76,7 @@ public class LocalIssueTracking {
}
}
- public List<TrackedIssue> trackIssues(BatchComponent component, Collection<ScannerReport.Issue> reportIssues, Date analysisDate) {
+ public List<TrackedIssue> trackIssues(InputComponent component, Collection<ScannerReport.Issue> reportIssues, Date analysisDate) {
List<TrackedIssue> trackedIssues = new LinkedList<>();
if (hasServerAnalysis) {
// all the issues that are not closed in db before starting this module scan, including manual issues
@@ -96,7 +101,8 @@ public class LocalIssueTracking {
}
}
- if (hasServerAnalysis && ResourceUtils.isRootProject(component.resource())) {
+ if (hasServerAnalysis && componentTree.getParent(component) == null) {
+ Preconditions.checkState(component instanceof InputModule, "Object without parent is of type: " + component.getClass());
// issues that relate to deleted components
addIssuesOnDeletedComponents(trackedIssues);
}
@@ -127,9 +133,9 @@ public class LocalIssueTracking {
return new IssueTrackingInput<>(rIssues, baseHashes);
}
- private boolean shouldCopyServerIssues(BatchComponent component) {
+ private boolean shouldCopyServerIssues(InputComponent component) {
if (!mode.scanAllFiles() && component.isFile()) {
- InputFile inputFile = (InputFile) component.inputComponent();
+ InputFile inputFile = (InputFile) component;
if (inputFile.status() == Status.SAME) {
return true;
}
@@ -155,19 +161,16 @@ public class LocalIssueTracking {
}
@CheckForNull
- private SourceHashHolder loadSourceHashes(BatchComponent component) {
+ private SourceHashHolder loadSourceHashes(InputComponent component) {
SourceHashHolder sourceHashHolder = null;
if (component.isFile()) {
- DefaultInputFile file = (DefaultInputFile) component.inputComponent();
- if (file == null) {
- throw new IllegalStateException("Resource " + component.resource() + " was not found in InputPath cache");
- }
+ DefaultInputFile file = (DefaultInputFile) component;
sourceHashHolder = new SourceHashHolder(file, lastLineHashes);
}
return sourceHashHolder;
}
- private Collection<ServerIssueFromWs> loadServerIssues(BatchComponent component) {
+ private Collection<ServerIssueFromWs> loadServerIssues(InputComponent component) {
Collection<ServerIssueFromWs> serverIssues = new ArrayList<>();
for (org.sonar.scanner.protocol.input.ScannerInput.ServerIssue previousIssue : serverIssueRepository.byComponent(component)) {
serverIssues.add(new ServerIssueFromWs(previousIssue));
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/ServerIssueRepository.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/ServerIssueRepository.java
index 116955cc6ea..f706da4e545 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/ServerIssueRepository.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/ServerIssueRepository.java
@@ -22,16 +22,17 @@ package org.sonar.scanner.issue.tracking;
import com.google.common.base.Function;
import javax.annotation.Nullable;
import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.core.component.ComponentKeys;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue;
import org.sonar.scanner.repository.ServerIssuesLoader;
import org.sonar.scanner.scan.ImmutableProjectReactor;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.storage.Storage;
import org.sonar.scanner.storage.Storages;
@@ -46,9 +47,9 @@ public class ServerIssueRepository {
private Storage<ServerIssue> issuesCache;
private final ServerIssuesLoader previousIssuesLoader;
private final ImmutableProjectReactor reactor;
- private final BatchComponentCache resourceCache;
+ private final InputComponentStore resourceCache;
- public ServerIssueRepository(Storages caches, ServerIssuesLoader previousIssuesLoader, ImmutableProjectReactor reactor, BatchComponentCache resourceCache) {
+ public ServerIssueRepository(Storages caches, ServerIssuesLoader previousIssuesLoader, ImmutableProjectReactor reactor, InputComponentStore resourceCache) {
this.caches = caches;
this.previousIssuesLoader = previousIssuesLoader;
this.reactor = reactor;
@@ -63,8 +64,8 @@ public class ServerIssueRepository {
profiler.stopInfo();
}
- public Iterable<ServerIssue> byComponent(BatchComponent component) {
- return issuesCache.values(component.batchId());
+ public Iterable<ServerIssue> byComponent(InputComponent component) {
+ return issuesCache.values(((DefaultInputComponent) component).batchId());
}
private class SaveIssueConsumer implements Function<ServerIssue, Void> {
@@ -75,7 +76,7 @@ public class ServerIssueRepository {
return null;
}
String componentKey = ComponentKeys.createEffectiveKey(issue.getModuleKey(), issue.hasPath() ? issue.getPath() : null);
- BatchComponent r = resourceCache.get(componentKey);
+ DefaultInputComponent r = (DefaultInputComponent) resourceCache.getByKey(componentKey);
if (r == null) {
// Deleted resource
issuesCache.put(0, issue.getKey(), issue);
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/TaskResult.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/TaskResult.java
index 879e4a016fd..0366c780caa 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/TaskResult.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/TaskResult.java
@@ -50,7 +50,7 @@ import org.sonar.scanner.protocol.output.ScannerReport.Symbol;
import org.sonar.scanner.report.ReportPublisher;
import org.sonar.scanner.report.ScannerReportUtils;
import org.sonar.scanner.scan.ProjectScanContainer;
-import org.sonar.scanner.scan.filesystem.InputPathCache;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.protocol.output.ScannerReportReader;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
@@ -87,9 +87,9 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver
private void storeReportComponents(int componentRef, String parentModuleKey, String branch) {
Component component = getReportReader().readComponent(componentRef);
if (isNotEmpty(component.getKey())) {
- reportComponents.put(component.getKey() + (isNotEmpty(branch) ? (":" + branch) : ""), component);
+ reportComponents.put(component.getKey(), component);
} else {
- reportComponents.put(parentModuleKey + (isNotEmpty(branch) ? (":" + branch) : "") + ":" + component.getPath(), component);
+ reportComponents.put(parentModuleKey + ":" + component.getPath(), component);
}
for (int childId : component.getChildRefList()) {
storeReportComponents(childId, isNotEmpty(component.getKey()) ? component.getKey() : parentModuleKey, branch);
@@ -102,7 +102,7 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver
}
private void storeFs(ProjectScanContainer container) {
- InputPathCache inputFileCache = container.getComponentByType(InputPathCache.class);
+ InputComponentStore inputFileCache = container.getComponentByType(InputComponentStore.class);
for (InputFile inputPath : inputFileCache.allFiles()) {
inputFiles.put(inputPath.relativePath(), inputPath);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java
index ec6ca476708..ede6ae406fc 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java
@@ -20,10 +20,9 @@
package org.sonar.scanner.phases;
import org.sonar.api.batch.SensorContext;
-import org.sonar.api.resources.Project;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.scanner.events.BatchStepEvent;
import org.sonar.scanner.events.EventBus;
-import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
import org.sonar.scanner.rule.QProfileVerifier;
import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
@@ -36,21 +35,18 @@ public abstract class AbstractPhaseExecutor {
private final InitializersExecutor initializersExecutor;
private final SensorsExecutor sensorsExecutor;
private final SensorContext sensorContext;
- private final DefaultIndex index;
private final FileSystemLogger fsLogger;
private final DefaultModuleFileSystem fs;
private final QProfileVerifier profileVerifier;
private final IssueExclusionsLoader issueExclusionsLoader;
public AbstractPhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
- SensorContext sensorContext, DefaultIndex index,
- EventBus eventBus, FileSystemLogger fsLogger, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
+ SensorContext sensorContext, EventBus eventBus, FileSystemLogger fsLogger, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
IssueExclusionsLoader issueExclusionsLoader) {
this.postJobsExecutor = postJobsExecutor;
this.initializersExecutor = initializersExecutor;
this.sensorsExecutor = sensorsExecutor;
this.sensorContext = sensorContext;
- this.index = index;
this.eventBus = eventBus;
this.fsLogger = fsLogger;
this.fs = fs;
@@ -61,7 +57,7 @@ public abstract class AbstractPhaseExecutor {
/**
* Executed on each module
*/
- public final void execute(Project module) {
+ public final void execute(DefaultInputModule module) {
eventBus.fireEvent(new ProjectAnalysisEvent(module, true));
executeInitializersPhase();
@@ -77,7 +73,7 @@ public abstract class AbstractPhaseExecutor {
sensorsExecutor.execute(sensorContext);
- if (module.isRoot()) {
+ if (module.definition().getParent() == null) {
executeOnRoot();
postJobsExecutor.execute(sensorContext);
}
@@ -111,7 +107,7 @@ public abstract class AbstractPhaseExecutor {
private void cleanMemory() {
String cleanMemory = "Clean memory";
eventBus.fireEvent(new BatchStepEvent(cleanMemory, true));
- index.clear();
+ //index.clear();
eventBus.fireEvent(new BatchStepEvent(cleanMemory, false));
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/InitializersExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/InitializersExecutor.java
index 91cf3e899a0..cc0f7bf14a9 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/InitializersExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/InitializersExecutor.java
@@ -22,6 +22,7 @@ package org.sonar.scanner.phases;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.Initializer;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
@@ -34,23 +35,24 @@ public class InitializersExecutor {
private static final Logger LOG = Loggers.get(SensorsExecutor.class);
- private Project project;
- private ScannerExtensionDictionnary selector;
- private EventBus eventBus;
+ private final DefaultInputModule module;
+ private final ScannerExtensionDictionnary selector;
+ private final EventBus eventBus;
- public InitializersExecutor(ScannerExtensionDictionnary selector, Project project, EventBus eventBus) {
+ public InitializersExecutor(ScannerExtensionDictionnary selector, DefaultInputModule module, EventBus eventBus) {
this.selector = selector;
- this.project = project;
+ this.module = module;
this.eventBus = eventBus;
}
public void execute() {
- Collection<Initializer> initializers = selector.select(Initializer.class, project, true, null);
+ Collection<Initializer> initializers = selector.select(Initializer.class, module, true, null);
eventBus.fireEvent(new InitializersPhaseEvent(Lists.newArrayList(initializers), true));
if (LOG.isDebugEnabled()) {
LOG.debug("Initializers : {}", StringUtils.join(initializers, " -> "));
}
+ Project project = new Project(module.definition());
for (Initializer initializer : initializers) {
eventBus.fireEvent(new InitializerExecutionEvent(initializer, true));
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java
index ff4943453cb..c68bf066b49 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java
@@ -24,7 +24,6 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.SensorContext;
import org.sonar.scanner.events.BatchStepEvent;
import org.sonar.scanner.events.EventBus;
-import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.issue.IssueCallback;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
import org.sonar.scanner.issue.tracking.IssueTransition;
@@ -43,9 +42,9 @@ public final class IssuesPhaseExecutor extends AbstractPhaseExecutor {
private final IssueCallback issueCallback;
public IssuesPhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext,
- DefaultIndex index, EventBus eventBus, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
+ EventBus eventBus, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
IssueExclusionsLoader issueExclusionsLoader, IssueTransition localIssueTracking, IssueCallback issueCallback) {
- super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, index, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader);
+ super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader);
this.eventBus = eventBus;
this.issuesReport = jsonReport;
this.localIssueTracking = localIssueTracking;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PostJobsExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PostJobsExecutor.java
index 23fe945516f..881a81df796 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PostJobsExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PostJobsExecutor.java
@@ -25,6 +25,7 @@ import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.PostJob;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
@@ -37,17 +38,17 @@ public class PostJobsExecutor {
private static final Logger LOG = Loggers.get(PostJobsExecutor.class);
private final ScannerExtensionDictionnary selector;
- private final Project project;
+ private final DefaultInputModule module;
private final EventBus eventBus;
- public PostJobsExecutor(ScannerExtensionDictionnary selector, Project project, EventBus eventBus) {
+ public PostJobsExecutor(ScannerExtensionDictionnary selector, DefaultInputModule module, EventBus eventBus) {
this.selector = selector;
- this.project = project;
+ this.module = module;
this.eventBus = eventBus;
}
public void execute(SensorContext context) {
- Collection<PostJob> postJobs = selector.select(PostJob.class, project, true, null);
+ Collection<PostJob> postJobs = selector.select(PostJob.class, module, true, null);
eventBus.fireEvent(new PostJobPhaseEvent(Lists.newArrayList(postJobs), true));
execute(context, postJobs);
@@ -57,6 +58,7 @@ public class PostJobsExecutor {
private void execute(SensorContext context, Collection<PostJob> postJobs) {
logPostJobs(postJobs);
+ Project project = new Project(module.definition());
for (PostJob postJob : postJobs) {
LOG.info("Executing post-job {}", ScannerUtils.describe(postJob));
eventBus.fireEvent(new PostJobExecutionEvent(postJob, true));
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/ProjectAnalysisEvent.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/ProjectAnalysisEvent.java
index aca9dc99bd7..841e82c1e5b 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/ProjectAnalysisEvent.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/ProjectAnalysisEvent.java
@@ -20,21 +20,21 @@
package org.sonar.scanner.phases;
import org.sonar.api.batch.events.ProjectAnalysisHandler;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.resources.Project;
class ProjectAnalysisEvent extends AbstractPhaseEvent<ProjectAnalysisHandler>
implements ProjectAnalysisHandler.ProjectAnalysisEvent {
+ private DefaultInputModule module;
- private final Project project;
-
- ProjectAnalysisEvent(Project project, boolean start) {
+ ProjectAnalysisEvent(DefaultInputModule module, boolean start) {
super(start);
- this.project = project;
+ this.module = module;
}
@Override
public Project getProject() {
- return project;
+ return new Project(module.definition());
}
@Override
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java
index 7c3434af247..c0d769ac318 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java
@@ -23,7 +23,6 @@ import org.sonar.api.batch.SensorContext;
import org.sonar.scanner.cpd.CpdExecutor;
import org.sonar.scanner.events.BatchStepEvent;
import org.sonar.scanner.events.EventBus;
-import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
import org.sonar.scanner.report.ReportPublisher;
import org.sonar.scanner.rule.QProfileVerifier;
@@ -37,9 +36,9 @@ public final class PublishPhaseExecutor extends AbstractPhaseExecutor {
private final CpdExecutor cpdExecutor;
public PublishPhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext,
- DefaultIndex index, EventBus eventBus, ReportPublisher reportPublisher, FileSystemLogger fsLogger, DefaultModuleFileSystem fs,
+ EventBus eventBus, ReportPublisher reportPublisher, FileSystemLogger fsLogger, DefaultModuleFileSystem fs,
QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader, CpdExecutor cpdExecutor) {
- super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, index, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader);
+ super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader);
this.eventBus = eventBus;
this.reportPublisher = reportPublisher;
this.cpdExecutor = cpdExecutor;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java
index acaa8727cf9..dc8a96cc643 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Lists;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.resources.Project;
import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary;
import org.sonar.scanner.events.EventBus;
@@ -30,15 +31,14 @@ import java.util.Collection;
@ScannerSide
public class SensorsExecutor {
+ private final EventBus eventBus;
+ private final DefaultInputModule module;
+ private final ScannerExtensionDictionnary selector;
- private EventBus eventBus;
- private Project module;
- private ScannerExtensionDictionnary selector;
-
- public SensorsExecutor(ScannerExtensionDictionnary selector, Project project, EventBus eventBus) {
+ public SensorsExecutor(ScannerExtensionDictionnary selector, DefaultInputModule module, EventBus eventBus) {
this.selector = selector;
this.eventBus = eventBus;
- this.module = project;
+ this.module = module;
}
public void execute(SensorContext context) {
@@ -54,7 +54,7 @@ public class SensorsExecutor {
private void executeSensor(SensorContext context, Sensor sensor) {
eventBus.fireEvent(new SensorExecutionEvent(sensor, true));
- sensor.analyse(module, context);
+ sensor.analyse(new Project(module.definition()), context);
eventBus.fireEvent(new SensorExecutionEvent(sensor, false));
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobContext.java
index ee2c3d64238..7f43c5ac313 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobContext.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobContext.java
@@ -30,22 +30,21 @@ import org.sonar.api.batch.postjob.issue.PostJobIssue;
import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.Settings;
import org.sonar.api.rule.RuleKey;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.issue.IssueCache;
import org.sonar.scanner.issue.tracking.TrackedIssue;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
public class DefaultPostJobContext implements PostJobContext {
private final Settings settings;
private final IssueCache cache;
- private final BatchComponentCache resourceCache;
private final AnalysisMode analysisMode;
+ private InputComponentStore inputComponentCache;
- public DefaultPostJobContext(Settings settings, IssueCache cache, BatchComponentCache resourceCache, AnalysisMode analysisMode) {
+ public DefaultPostJobContext(Settings settings, IssueCache cache, InputComponentStore inputComponentCache, AnalysisMode analysisMode) {
this.settings = settings;
this.cache = cache;
- this.resourceCache = resourceCache;
+ this.inputComponentCache = inputComponentCache;
this.analysisMode = analysisMode;
}
@@ -100,8 +99,7 @@ public class DefaultPostJobContext implements PostJobContext {
@Override
public InputComponent inputComponent() {
- BatchComponent component = resourceCache.get(wrapped.componentKey());
- return component != null ? component.inputComponent() : null;
+ return inputComponentCache.getByKey(wrapped.componentKey());
}
@Override
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/profiling/PhasesSumUpTimeProfiler.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/profiling/PhasesSumUpTimeProfiler.java
index 8906535df07..5a923f01fde 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/profiling/PhasesSumUpTimeProfiler.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/profiling/PhasesSumUpTimeProfiler.java
@@ -71,7 +71,7 @@ public class PhasesSumUpTimeProfiler implements ProjectAnalysisHandler, SensorEx
private final System2 system;
private final File out;
-
+
public PhasesSumUpTimeProfiler(System2 system, GlobalProperties bootstrapProps) {
String workingDirPath = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.WORKING_DIRECTORY), CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE);
File workingDir = new File(workingDirPath).getAbsoluteFile();
@@ -115,7 +115,7 @@ public class PhasesSumUpTimeProfiler implements ProjectAnalysisHandler, SensorEx
String fileName = module.getKey() + "-profiler.properties";
dumpToFile(props, ScannerUtils.cleanKeyForFilename(fileName));
totalProfiling.merge(currentModuleProfiling);
- if (module.isRoot() && !module.getModules().isEmpty()) {
+ if (module.getParent() == null && !module.getModules().isEmpty()) {
dumpTotalExecutionSummary();
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java
index 1f5238b8a8d..1449657f23f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java
@@ -23,18 +23,19 @@ import javax.annotation.CheckForNull;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
+import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputComponentTree;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType;
import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink;
import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink.ComponentLinkType;
-import org.sonar.scanner.scan.ImmutableProjectReactor;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
/**
@@ -42,91 +43,109 @@ import org.sonar.scanner.protocol.output.ScannerReportWriter;
*/
public class ComponentsPublisher implements ReportPublisherStep {
- private final BatchComponentCache resourceCache;
- private final ImmutableProjectReactor reactor;
+ private InputComponentTree componentTree;
+ private InputModuleHierarchy moduleHierarchy;
- public ComponentsPublisher(ImmutableProjectReactor reactor, BatchComponentCache resourceCache) {
- this.reactor = reactor;
- this.resourceCache = resourceCache;
+ public ComponentsPublisher(InputModuleHierarchy moduleHierarchy, InputComponentTree inputComponentTree) {
+ this.moduleHierarchy = moduleHierarchy;
+ this.componentTree = inputComponentTree;
}
@Override
public void publish(ScannerReportWriter writer) {
- BatchComponent rootProject = resourceCache.get(reactor.getRoot().getKeyWithBranch());
- recursiveWriteComponent(rootProject, writer);
+ recursiveWriteComponent((DefaultInputComponent) moduleHierarchy.root(), writer);
}
- private void recursiveWriteComponent(BatchComponent batchComponent, ScannerReportWriter writer) {
- Resource r = batchComponent.resource();
+ private void recursiveWriteComponent(DefaultInputComponent component, ScannerReportWriter writer) {
ScannerReport.Component.Builder builder = ScannerReport.Component.newBuilder();
// non-null fields
- builder.setRef(batchComponent.batchId());
- builder.setType(getType(r));
+ builder.setRef(component.batchId());
+ builder.setType(getType(component));
// Don't set key on directories and files to save space since it can be deduced from path
- if (batchComponent.isProjectOrModule()) {
+ if (component instanceof InputModule) {
+ DefaultInputModule inputModule = (DefaultInputModule) component;
// Here we want key without branch
- ProjectDefinition def = reactor.getProjectDefinition(batchComponent.key());
- builder.setKey(def.getKey());
- }
+ builder.setKey(inputModule.key());
- // protocol buffers does not accept null values
+ // protocol buffers does not accept null values
+ String name = getName(inputModule);
+ if (name != null) {
+ builder.setName(name);
+ }
+ String description = getDescription(inputModule);
+ if (description != null) {
+ builder.setDescription(description);
+ }
- if (batchComponent.isFile()) {
- builder.setIsTest(ResourceUtils.isUnitTestFile(r));
- builder.setLines(((InputFile) batchComponent.inputComponent()).lines());
+ writeVersion(inputModule, builder);
}
- String name = getName(r);
- if (name != null) {
- builder.setName(name);
- }
- String description = getDescription(r);
- if (description != null) {
- builder.setDescription(description);
+
+ if (component.isFile()) {
+ InputFile file = (InputFile) component;
+ builder.setIsTest(file.type() == InputFile.Type.TEST);
+ builder.setLines(file.lines());
+
+ String lang = getLanguageKey(file);
+ if (lang != null) {
+ builder.setLanguage(lang);
+ }
}
- String path = r.getPath();
+
+ String path = getPath(component);
if (path != null) {
builder.setPath(path);
}
- String lang = getLanguageKey(r);
- if (lang != null) {
- builder.setLanguage(lang);
- }
- for (BatchComponent child : batchComponent.children()) {
- builder.addChildRef(child.batchId());
+
+ for (InputComponent child : componentTree.getChildren(component)) {
+ builder.addChildRef(((DefaultInputComponent) child).batchId());
}
- writeLinks(batchComponent, builder);
- writeVersion(batchComponent, builder);
+ writeLinks(component, builder);
writer.writeComponent(builder.build());
- for (BatchComponent child : batchComponent.children()) {
- recursiveWriteComponent(child, writer);
+ for (InputComponent child : componentTree.getChildren(component)) {
+ recursiveWriteComponent((DefaultInputComponent) child, writer);
}
}
- private void writeVersion(BatchComponent c, ScannerReport.Component.Builder builder) {
- if (c.isProjectOrModule()) {
- ProjectDefinition def = reactor.getProjectDefinition(c.key());
- String version = getVersion(def);
- if(version != null) {
- builder.setVersion(version);
+ private void writeVersion(DefaultInputModule module, ScannerReport.Component.Builder builder) {
+ ProjectDefinition def = module.definition();
+ String version = getVersion(def);
+ if (version != null) {
+ builder.setVersion(version);
+ }
+ }
+
+ @CheckForNull
+ private String getPath(InputComponent component) {
+ if (component instanceof InputPath) {
+ InputPath inputPath = (InputPath) component;
+ if (StringUtils.isEmpty(inputPath.relativePath())) {
+ return "/";
+ } else {
+ return inputPath.relativePath();
}
+ } else if (component instanceof InputModule) {
+ InputModule module = (InputModule) component;
+ return moduleHierarchy.relativePath(module);
}
+ throw new IllegalStateException("Unkown component: " + component.getClass());
}
private static String getVersion(ProjectDefinition def) {
String version = def.getOriginalVersion();
- if(StringUtils.isNotBlank(version)) {
+ if (StringUtils.isNotBlank(version)) {
return version;
}
-
+
return def.getParent() != null ? getVersion(def.getParent()) : null;
}
- private void writeLinks(BatchComponent c, ScannerReport.Component.Builder builder) {
- if (c.isProjectOrModule()) {
- ProjectDefinition def = reactor.getProjectDefinition(c.key());
+ private void writeLinks(InputComponent c, ScannerReport.Component.Builder builder) {
+ if (c instanceof InputModule) {
+ DefaultInputModule inputModule = (DefaultInputModule) c;
+ ProjectDefinition def = inputModule.definition();
ComponentLink.Builder linkBuilder = ComponentLink.newBuilder();
writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_HOME_PAGE, ComponentLinkType.HOME);
@@ -149,37 +168,35 @@ public class ComponentsPublisher implements ReportPublisherStep {
}
@CheckForNull
- private static String getLanguageKey(Resource r) {
- Language language = r.getLanguage();
- return ResourceUtils.isFile(r) && language != null ? language.getKey() : null;
+ private static String getLanguageKey(InputFile file) {
+ return file.language();
}
@CheckForNull
- private static String getName(Resource r) {
- if (ResourceUtils.isProject(r)) {
- Project project = (Project) r;
- return project.getOriginalName();
+ private static String getName(DefaultInputModule module) {
+ if (StringUtils.isNotEmpty(module.definition().getBranch())) {
+ return module.definition().getOriginalName() + " " + module.definition().getBranch();
+ } else {
+ return module.definition().getOriginalName();
}
- // Don't return name for directories and files since it can be guessed from the path
- return (ResourceUtils.isFile(r) || ResourceUtils.isDirectory(r)) ? null : r.getName();
}
@CheckForNull
- private static String getDescription(Resource r) {
- // Only for projets and modules
- return ResourceUtils.isProject(r) ? r.getDescription() : null;
+ private static String getDescription(DefaultInputModule module) {
+ return module.definition().getDescription();
}
- private static ComponentType getType(Resource r) {
- if (ResourceUtils.isFile(r)) {
+ private ComponentType getType(InputComponent r) {
+ if (r instanceof InputFile) {
return ComponentType.FILE;
- } else if (ResourceUtils.isDirectory(r)) {
+ } else if (r instanceof InputDir) {
return ComponentType.DIRECTORY;
- } else if (ResourceUtils.isModuleProject(r)) {
- return ComponentType.MODULE;
- } else if (ResourceUtils.isRootProject(r)) {
+ } else if ((r instanceof InputModule) && moduleHierarchy.isRoot((InputModule) r)) {
return ComponentType.PROJECT;
+ } else if (r instanceof InputModule) {
+ return ComponentType.MODULE;
}
+
throw new IllegalArgumentException("Unknown resource type: " + r);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java
index ba776070fa5..2060505fca8 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java
@@ -26,42 +26,40 @@ import java.util.Map;
import javax.annotation.Nonnull;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReport.LineCoverage;
import org.sonar.scanner.protocol.output.ScannerReport.LineCoverage.Builder;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.scan.measure.MeasureCache;
public class CoveragePublisher implements ReportPublisherStep {
- private final BatchComponentCache resourceCache;
+ private final InputComponentStore componentCache;
private final MeasureCache measureCache;
- public CoveragePublisher(BatchComponentCache resourceCache, MeasureCache measureCache) {
- this.resourceCache = resourceCache;
+ public CoveragePublisher(InputComponentStore componentCache, MeasureCache measureCache) {
+ this.componentCache = componentCache;
this.measureCache = measureCache;
}
@Override
public void publish(ScannerReportWriter writer) {
- for (final BatchComponent resource : resourceCache.all()) {
- if (!resource.isFile()) {
- continue;
- }
+ for (final InputFile file : componentCache.allFiles()) {
+ DefaultInputFile inputFile = (DefaultInputFile) file;
Map<Integer, LineCoverage.Builder> coveragePerLine = new LinkedHashMap<>();
- int lineCount = ((InputFile) resource.inputComponent()).lines();
- applyLineMeasure(resource.key(), lineCount, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, coveragePerLine,
+ int lineCount = inputFile.lines();
+ applyLineMeasure(inputFile.key(), lineCount, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, coveragePerLine,
(value, builder) -> builder.setHits(Integer.parseInt(value) > 0));
- applyLineMeasure(resource.key(), lineCount, CoreMetrics.CONDITIONS_BY_LINE_KEY, coveragePerLine,
+ applyLineMeasure(inputFile.key(), lineCount, CoreMetrics.CONDITIONS_BY_LINE_KEY, coveragePerLine,
(value, builder) -> builder.setConditions(Integer.parseInt(value)));
- applyLineMeasure(resource.key(), lineCount, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY, coveragePerLine,
+ applyLineMeasure(inputFile.key(), lineCount, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY, coveragePerLine,
(value, builder) -> builder.setCoveredConditions(Integer.parseInt(value)));
- writer.writeComponentCoverage(resource.batchId(), Iterables.transform(coveragePerLine.values(), BuildCoverage.INSTANCE));
+ writer.writeComponentCoverage(inputFile.batchId(), Iterables.transform(coveragePerLine.values(), BuildCoverage.INSTANCE));
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java
index 33f58a8db3f..30e649716d3 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java
@@ -24,8 +24,11 @@ import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.stream.StreamSupport;
+
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
@@ -34,8 +37,6 @@ import org.sonar.api.test.TestCase.Status;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.util.stream.Collectors;
import org.sonar.scanner.deprecated.test.TestPlanBuilder;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Measure.BoolValue;
import org.sonar.scanner.protocol.output.ScannerReport.Measure.DoubleValue;
@@ -43,6 +44,7 @@ import org.sonar.scanner.protocol.output.ScannerReport.Measure.IntValue;
import org.sonar.scanner.protocol.output.ScannerReport.Measure.LongValue;
import org.sonar.scanner.protocol.output.ScannerReport.Measure.StringValue;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.scan.measure.MeasureCache;
import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER;
@@ -66,12 +68,12 @@ import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES_KEY;
public class MeasuresPublisher implements ReportPublisherStep {
- private final BatchComponentCache componentCache;
+ private final InputComponentStore componentCache;
private final MeasureCache measureCache;
private final TestPlanBuilder testPlanBuilder;
- public MeasuresPublisher(BatchComponentCache resourceCache, MeasureCache measureCache, TestPlanBuilder testPlanBuilder) {
- this.componentCache = resourceCache;
+ public MeasuresPublisher(InputComponentStore componentCache, MeasureCache measureCache, TestPlanBuilder testPlanBuilder) {
+ this.componentCache = componentCache;
this.measureCache = measureCache;
this.testPlanBuilder = testPlanBuilder;
}
@@ -80,7 +82,8 @@ public class MeasuresPublisher implements ReportPublisherStep {
public void publish(ScannerReportWriter writer) {
final ScannerReport.Measure.Builder builder = ScannerReport.Measure.newBuilder();
- for (final BatchComponent component : componentCache.all()) {
+ for (final InputComponent c : componentCache.all()) {
+ DefaultInputComponent component = (DefaultInputComponent) c;
// Recompute all coverage measures from line data to take into account the possible merge of several reports
updateCoverageFromLineData(component);
// Recompute test execution measures from MutableTestPlan to take into account the possible merge of several reports
@@ -119,8 +122,8 @@ public class MeasuresPublisher implements ReportPublisherStep {
}
}
- private void updateTestExecutionFromTestPlan(final BatchComponent component) {
- final MutableTestPlan testPlan = testPlanBuilder.loadPerspective(MutableTestPlan.class, component.inputComponent());
+ private void updateTestExecutionFromTestPlan(final InputComponent component) {
+ final MutableTestPlan testPlan = testPlanBuilder.loadPerspective(MutableTestPlan.class, component);
if (testPlan == null || Iterables.isEmpty(testPlan.testCases())) {
return;
}
@@ -136,8 +139,8 @@ public class MeasuresPublisher implements ReportPublisherStep {
measureCache.put(component.key(), TEST_FAILURES_KEY, new DefaultMeasure<Integer>().forMetric(TEST_FAILURES).withValue((int) failedTests));
}
- private void updateCoverageFromLineData(final BatchComponent component) {
- if (!component.isFile() || ((InputFile) component.inputComponent()).type() != Type.MAIN) {
+ private void updateCoverageFromLineData(final InputComponent component) {
+ if (!component.isFile() || ((InputFile) component).type() != Type.MAIN) {
return;
}
DefaultMeasure<String> lineHitsMeasure = (DefaultMeasure<String>) measureCache.byMetric(component.key(), CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY);
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java
index 72fd40673fd..da0f2183943 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java
@@ -21,39 +21,38 @@ package org.sonar.scanner.report;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Project;
+import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
import org.sonar.scanner.rule.ModuleQProfiles;
import org.sonar.scanner.rule.QProfile;
-import org.sonar.scanner.scan.ImmutableProjectReactor;
public class MetadataPublisher implements ReportPublisherStep {
- private final BatchComponentCache componentCache;
- private final ImmutableProjectReactor reactor;
private final Settings settings;
private final ModuleQProfiles qProfiles;
+ private final ProjectAnalysisInfo projectAnalysisInfo;
+ private final InputModuleHierarchy moduleHierarchy;
- public MetadataPublisher(BatchComponentCache componentCache, ImmutableProjectReactor reactor, Settings settings, ModuleQProfiles qProfiles) {
- this.componentCache = componentCache;
- this.reactor = reactor;
+ public MetadataPublisher(ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy, Settings settings, ModuleQProfiles qProfiles) {
+ this.projectAnalysisInfo = projectAnalysisInfo;
+ this.moduleHierarchy = moduleHierarchy;
this.settings = settings;
this.qProfiles = qProfiles;
}
@Override
public void publish(ScannerReportWriter writer) {
- ProjectDefinition root = reactor.getRoot();
- BatchComponent rootProject = componentCache.getRoot();
+ DefaultInputModule rootProject = moduleHierarchy.root();
+ ProjectDefinition rootDef = rootProject.definition();
ScannerReport.Metadata.Builder builder = ScannerReport.Metadata.newBuilder()
- .setAnalysisDate(((Project) rootProject.resource()).getAnalysisDate().getTime())
+ .setAnalysisDate(projectAnalysisInfo.analysisDate().getTime())
// Here we want key without branch
- .setProjectKey(root.getKey())
+ .setProjectKey(rootDef.getKey())
.setCrossProjectDuplicationActivated(SonarCpdBlockIndex.isCrossProjectDuplicationEnabled(settings))
.setRootComponentRef(rootProject.batchId());
@@ -62,7 +61,7 @@ public class MetadataPublisher implements ReportPublisherStep {
builder.setOrganizationKey(organization);
}
- String branch = root.getBranch();
+ String branch = rootDef.getBranch();
if (branch != null) {
builder.setBranch(branch);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java
index 06c4893d6ea..b270567f86f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java
@@ -23,9 +23,10 @@ import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@@ -36,24 +37,21 @@ import java.nio.charset.StandardCharsets;
public class SourcePublisher implements ReportPublisherStep {
- private final BatchComponentCache resourceCache;
+ private final InputComponentStore componentCache;
- public SourcePublisher(BatchComponentCache resourceCache) {
- this.resourceCache = resourceCache;
+ public SourcePublisher(InputComponentStore componentCache) {
+ this.componentCache = componentCache;
}
@Override
public void publish(ScannerReportWriter writer) {
- for (final BatchComponent resource : resourceCache.all()) {
- if (!resource.isFile()) {
- continue;
- }
-
- InputFile inputFile = (InputFile) resource.inputComponent();
- File iofile = writer.getSourceFile(resource.batchId());
+ for (final InputFile file : componentCache.allFiles()) {
+ DefaultInputFile inputFile = (DefaultInputFile) file;
+ File iofile = writer.getSourceFile(inputFile.batchId());
int line = 0;
- try (FileOutputStream output = new FileOutputStream(iofile); BOMInputStream bomIn = new BOMInputStream(new FileInputStream(inputFile.file()),
- ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
+ try (FileOutputStream output = new FileOutputStream(iofile);
+ BOMInputStream bomIn = new BOMInputStream(new FileInputStream(inputFile.file()),
+ ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
BufferedReader reader = new BufferedReader(new InputStreamReader(bomIn, inputFile.charset()))) {
String lineStr = reader.readLine();
while (lineStr != null) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionAndCoveragePublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionAndCoveragePublisher.java
index 04ae3e824eb..70080c6a9a3 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionAndCoveragePublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionAndCoveragePublisher.java
@@ -23,29 +23,31 @@ import com.google.common.collect.Iterables;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.StreamSupport;
+
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.test.CoverageBlock;
import org.sonar.api.test.MutableTestCase;
import org.sonar.api.test.MutableTestPlan;
import org.sonar.api.test.TestCase;
import org.sonar.scanner.deprecated.test.DefaultTestable;
import org.sonar.scanner.deprecated.test.TestPlanBuilder;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.CoverageDetail;
import org.sonar.scanner.protocol.output.ScannerReport.Test;
import org.sonar.scanner.protocol.output.ScannerReport.Test.TestStatus;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
import static java.util.stream.Collectors.toList;
public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
- private final BatchComponentCache componentCache;
+ private final InputComponentStore componentStore;
private final TestPlanBuilder testPlanBuilder;
- public TestExecutionAndCoveragePublisher(BatchComponentCache resourceCache, TestPlanBuilder testPlanBuilder) {
- this.componentCache = resourceCache;
+ public TestExecutionAndCoveragePublisher(InputComponentStore componentStore, TestPlanBuilder testPlanBuilder) {
+ this.componentStore = componentStore;
this.testPlanBuilder = testPlanBuilder;
}
@@ -54,8 +56,9 @@ public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
final ScannerReport.Test.Builder testBuilder = ScannerReport.Test.newBuilder();
final ScannerReport.CoverageDetail.Builder builder = ScannerReport.CoverageDetail.newBuilder();
final ScannerReport.CoverageDetail.CoveredFile.Builder coveredBuilder = ScannerReport.CoverageDetail.CoveredFile.newBuilder();
- for (final BatchComponent component : componentCache.all()) {
- final MutableTestPlan testPlan = testPlanBuilder.loadPerspective(MutableTestPlan.class, component.inputComponent());
+ for (final InputComponent c : componentStore.all()) {
+ DefaultInputComponent component = (DefaultInputComponent) c;
+ final MutableTestPlan testPlan = testPlanBuilder.loadPerspective(MutableTestPlan.class, component);
if (testPlan == null || Iterables.isEmpty(testPlan.testCases())) {
continue;
}
@@ -81,7 +84,8 @@ public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
builder.setTestName(testName);
for (CoverageBlock block : testCase.coverageBlocks()) {
coveredBuilder.clear();
- coveredBuilder.setFileRef(componentCache.get(((DefaultTestable) block.testable()).inputFile().key()).batchId());
+ DefaultInputComponent c = (DefaultInputComponent) componentStore.getByKey(((DefaultTestable) block.testable()).inputFile().key());
+ coveredBuilder.setFileRef(c.batchId());
for (int line : block.lines()) {
coveredBuilder.addCoveredLine(line);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java
new file mode 100644
index 00000000000..bf5218f3714
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java
@@ -0,0 +1,58 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.CheckForNull;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.InputComponentTree;
+
+public class DefaultComponentTree implements InputComponentTree {
+ private Map<InputComponent, InputComponent> parents = new HashMap<>();
+ private Map<InputComponent, Set<InputComponent>> children = new HashMap<>();
+
+ public void index(InputComponent component, InputComponent parent) {
+ parents.put(component, parent);
+ Set<InputComponent> list = children.get(parent);
+ if (list == null) {
+ list = new LinkedHashSet<>();
+ children.put(parent, list);
+ }
+
+ list.add(component);
+ }
+
+ @Override
+ public Collection<InputComponent> getChildren(InputComponent component) {
+ return children.getOrDefault(component, Collections.emptySet());
+ }
+
+ @CheckForNull
+ @Override
+ public InputComponent getParent(InputComponent component) {
+ return parents.get(component);
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java
new file mode 100644
index 00000000000..f1f35acf1f9
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java
@@ -0,0 +1,119 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan;
+
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.CheckForNull;
+
+import org.sonar.api.Startable;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.scanner.scan.filesystem.BatchIdGenerator;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+public class DefaultInputModuleHierarchy implements InputModuleHierarchy, Startable {
+ private final PathResolver pathResolver = new PathResolver();
+ private final ImmutableProjectReactor projectReactor;
+ private final DefaultComponentTree componentTree;
+ private final BatchIdGenerator batchIdGenerator;
+
+ private DefaultInputModule root;
+ private Map<DefaultInputModule, DefaultInputModule> parents;
+ private Multimap<DefaultInputModule, DefaultInputModule> children;
+
+ public DefaultInputModuleHierarchy(ImmutableProjectReactor projectReactor, DefaultComponentTree componentTree, BatchIdGenerator batchIdGenerator) {
+ this.projectReactor = projectReactor;
+ this.componentTree = componentTree;
+ this.batchIdGenerator = batchIdGenerator;
+ }
+
+ @Override
+ public void start() {
+ doStart(projectReactor.getRoot());
+ }
+
+ void doStart(ProjectDefinition rootProjectDefinition) {
+ parents = new HashMap<>();
+ children = HashMultimap.create();
+ root = new DefaultInputModule(rootProjectDefinition, batchIdGenerator.get());
+ createChildren(root);
+ }
+
+ private void createChildren(DefaultInputModule parent) {
+ for (ProjectDefinition def : parent.definition().getSubProjects()) {
+ DefaultInputModule child = new DefaultInputModule(def, batchIdGenerator.get());
+ parents.put(child, parent);
+ children.put(parent, child);
+ componentTree.index(child, parent);
+ createChildren(child);
+ }
+ }
+
+ @Override
+ public DefaultInputModule root() {
+ return root;
+ }
+
+ @Override
+ public Collection<DefaultInputModule> children(InputModule component) {
+ return children.get((DefaultInputModule) component);
+ }
+
+ @Override
+ public DefaultInputModule parent(InputModule component) {
+ return parents.get(component);
+ }
+
+ @Override
+ public boolean isRoot(InputModule module) {
+ return root.equals(module);
+ }
+
+ @Override
+ @CheckForNull
+ public String relativePath(InputModule module) {
+ DefaultInputModule parent = parent(module);
+ if (parent == null) {
+ return null;
+ }
+ DefaultInputModule inputModule = (DefaultInputModule) module;
+
+ ProjectDefinition parentDefinition = parent.definition();
+ Path parentBaseDir = parentDefinition.getBaseDir().toPath();
+ ProjectDefinition moduleDefinition = inputModule.definition();
+ Path moduleBaseDir = moduleDefinition.getBaseDir().toPath();
+
+ return pathResolver.relativePath(parentBaseDir, moduleBaseDir);
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
index fa31b9c7419..35dabd15894 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
@@ -23,21 +23,18 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.rule.CheckFactory;
-import org.sonar.api.resources.Project;
import org.sonar.api.scan.filesystem.FileExclusions;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.scanner.DefaultFileLinesContextFactory;
-import org.sonar.scanner.DefaultProjectTree;
import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary;
import org.sonar.scanner.bootstrap.ExtensionInstaller;
import org.sonar.scanner.bootstrap.ExtensionUtils;
import org.sonar.scanner.deprecated.DeprecatedSensorContext;
import org.sonar.scanner.deprecated.perspectives.ScannerPerspectives;
import org.sonar.scanner.events.EventBus;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.issue.IssuableFactory;
import org.sonar.scanner.issue.IssueFilters;
@@ -59,7 +56,6 @@ import org.sonar.scanner.postjob.PostJobOptimizer;
import org.sonar.scanner.rule.QProfileVerifier;
import org.sonar.scanner.rule.RuleFinderCompatibility;
import org.sonar.scanner.rule.RulesProfileProvider;
-import org.sonar.scanner.scan.filesystem.ComponentIndexer;
import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.scanner.scan.filesystem.ExclusionFilters;
import org.sonar.scanner.scan.filesystem.FileIndexer;
@@ -68,7 +64,7 @@ import org.sonar.scanner.scan.filesystem.IndexedFileBuilderProvider;
import org.sonar.scanner.scan.filesystem.MetadataGeneratorProvider;
import org.sonar.scanner.scan.filesystem.LanguageDetectionFactory;
import org.sonar.scanner.scan.filesystem.ModuleFileSystemInitializer;
-import org.sonar.scanner.scan.filesystem.ModuleInputFileCache;
+import org.sonar.scanner.scan.filesystem.ModuleInputComponentStore;
import org.sonar.scanner.scan.filesystem.StatusDetectionFactory;
import org.sonar.scanner.scan.report.IssuesReports;
import org.sonar.scanner.sensor.DefaultSensorStorage;
@@ -79,31 +75,29 @@ import org.sonar.scanner.source.SymbolizableBuilder;
public class ModuleScanContainer extends ComponentContainer {
private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class);
- private final Project module;
+ private final DefaultInputModule module;
- public ModuleScanContainer(ProjectScanContainer parent, Project module) {
+ public ModuleScanContainer(ProjectScanContainer parent, DefaultInputModule module) {
super(parent);
this.module = module;
}
@Override
protected void doBeforeStart() {
- LOG.info("------------- Scan {}", module.getName());
+ LOG.info("------------- Scan {}", module.definition().getName());
addCoreComponents();
addExtensions();
}
private void addCoreComponents() {
- ProjectDefinition moduleDefinition = getComponentByType(DefaultProjectTree.class).getProjectDefinition(module);
add(
- moduleDefinition,
+ module.definition(),
module,
- getComponentByType(BatchComponentCache.class).get(module).inputComponent(),
ModuleSettings.class);
// hack to initialize settings before ExtensionProviders
ModuleSettings moduleSettings = getComponentByType(ModuleSettings.class);
- module.setSettings(moduleSettings);
+ //module.setSettings(moduleSettings);
if (getComponentByType(AnalysisMode.class).isIssues()) {
add(IssuesPhaseExecutor.class,
@@ -120,7 +114,7 @@ public class ModuleScanContainer extends ComponentContainer {
InitializersExecutor.class,
// file system
- ModuleInputFileCache.class,
+ ModuleInputComponentStore.class,
FileExclusions.class,
ExclusionFilters.class,
new MetadataGeneratorProvider(),
@@ -129,7 +123,6 @@ public class ModuleScanContainer extends ComponentContainer {
LanguageDetectionFactory.class,
FileIndexer.class,
new IndexedFileBuilderProvider(),
- ComponentIndexer.class,
LanguageVerifier.class,
FileSystemLogger.class,
DefaultModuleFileSystem.class,
@@ -179,12 +172,12 @@ public class ModuleScanContainer extends ComponentContainer {
@Override
protected void doAfterStart() {
DefaultIndex index = getComponentByType(DefaultIndex.class);
- index.setCurrentProject(module, getComponentByType(DefaultSensorStorage.class));
+ index.setCurrentProject(getComponentByType(DefaultSensorStorage.class));
getComponentByType(AbstractPhaseExecutor.class).execute(module);
// Free memory since module settings are no more used
- module.setSettings(null);
+ //module.setSettings(null);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
index c7c34eb64d2..de4bfe28a36 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
@@ -22,17 +22,17 @@ package org.sonar.scanner.scan;
import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.InstantiationStrategy;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.metric.ScannerMetrics;
import org.sonar.core.platform.ComponentContainer;
-import org.sonar.scanner.DefaultProjectTree;
-import org.sonar.scanner.ProjectConfigurator;
+import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.analysis.AnalysisProperties;
import org.sonar.scanner.analysis.AnalysisTempFolderProvider;
import org.sonar.scanner.analysis.DefaultAnalysisMode;
@@ -45,7 +45,6 @@ import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
import org.sonar.scanner.deprecated.test.TestPlanBuilder;
import org.sonar.scanner.deprecated.test.TestableBuilder;
import org.sonar.scanner.events.EventBus;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.issue.DefaultIssueCallback;
import org.sonar.scanner.issue.DefaultProjectIssues;
@@ -86,7 +85,8 @@ import org.sonar.scanner.rule.DefaultActiveRulesLoader;
import org.sonar.scanner.rule.DefaultRulesLoader;
import org.sonar.scanner.rule.RulesLoader;
import org.sonar.scanner.rule.RulesProvider;
-import org.sonar.scanner.scan.filesystem.InputPathCache;
+import org.sonar.scanner.scan.filesystem.BatchIdGenerator;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.scan.measure.DefaultMetricFinder;
import org.sonar.scanner.scan.measure.DeprecatedMetricFinder;
import org.sonar.scanner.scan.measure.MeasureCache;
@@ -133,14 +133,12 @@ public class ProjectScanContainer extends ComponentContainer {
EventBus.class,
PhasesTimeProfiler.class,
ResourceTypes.class,
- DefaultProjectTree.class,
ProjectReactorValidator.class,
CodeColorizers.class,
MetricProvider.class,
- ProjectConfigurator.class,
+ ProjectAnalysisInfo.class,
DefaultIndex.class,
Storages.class,
- BatchComponentCache.class,
DefaultIssueCallback.class,
new RulesProvider(),
new ProjectRepositoriesProvider(),
@@ -149,8 +147,11 @@ public class ProjectScanContainer extends ComponentContainer {
new AnalysisTempFolderProvider(),
// file system
- InputPathCache.class,
+ InputComponentStore.class,
PathResolver.class,
+ DefaultInputModuleHierarchy.class,
+ DefaultComponentTree.class,
+ BatchIdGenerator.class,
// rules
new ActiveRulesProvider(),
@@ -228,22 +229,22 @@ public class ProjectScanContainer extends ComponentContainer {
DefaultAnalysisMode analysisMode = getComponentByType(DefaultAnalysisMode.class);
analysisMode.printMode();
LOG.debug("Start recursive analysis of project modules");
- DefaultProjectTree tree = getComponentByType(DefaultProjectTree.class);
- scanRecursively(tree.getRootProject());
+ InputModuleHierarchy tree = getComponentByType(InputModuleHierarchy.class);
+ scanRecursively(tree, tree.root());
if (analysisMode.isMediumTest()) {
getComponentByType(ScanTaskObservers.class).notifyEndOfScanTask();
}
}
- private void scanRecursively(Project module) {
- for (Project subModules : module.getModules()) {
- scanRecursively(subModules);
+ private void scanRecursively(InputModuleHierarchy tree, DefaultInputModule module) {
+ for (DefaultInputModule child : tree.children(module)) {
+ scanRecursively(tree, child);
}
scan(module);
}
@VisibleForTesting
- void scan(Project module) {
+ void scan(DefaultInputModule module) {
new ModuleScanContainer(this, module).execute();
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/BatchIdGenerator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/BatchIdGenerator.java
new file mode 100644
index 00000000000..48d90078bae
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/BatchIdGenerator.java
@@ -0,0 +1,31 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import java.util.function.Supplier;
+
+public class BatchIdGenerator implements Supplier<Integer> {
+ private int nextBatchId = 1;
+
+ @Override
+ public Integer get() {
+ return nextBatchId++;
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ComponentIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ComponentIndexer.java
deleted file mode 100644
index 4c28ad63ab9..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ComponentIndexer.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.scan.filesystem;
-
-import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.batch.fs.InputDir;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
-import org.sonar.scanner.index.DefaultIndex;
-
-/**
- * Index all files/directories of the module in SQ database and importing source code.
- *
- * @since 4.2
- */
-@ScannerSide
-public class ComponentIndexer {
-
- private final Languages languages;
- private final DefaultIndex sonarIndex;
- private final Project module;
- private final BatchComponentCache componentCache;
-
- public ComponentIndexer(Project module, Languages languages, DefaultIndex sonarIndex, BatchComponentCache componentCache) {
- this.module = module;
- this.languages = languages;
- this.sonarIndex = sonarIndex;
- this.componentCache = componentCache;
- }
-
- public void execute(DefaultModuleFileSystem fs) {
- module.setBaseDir(fs.baseDir());
-
- for (InputFile inputFile : fs.inputFiles()) {
- String languageKey = inputFile.language();
- boolean unitTest = InputFile.Type.TEST == inputFile.type();
- Resource sonarFile = File.create(inputFile.relativePath(), languages.get(languageKey), unitTest);
- sonarIndex.index(sonarFile);
- BatchComponent file = componentCache.get(sonarFile);
- file.setInputComponent(inputFile);
- Resource sonarDir = file.parent().resource();
- InputDir inputDir = fs.inputDir(inputFile.file().getParentFile());
- componentCache.get(sonarDir).setInputComponent(inputDir);
- }
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java
index 03b9fb9285e..3baf5893654 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java
@@ -27,8 +27,8 @@ import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Project;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.analysis.DefaultAnalysisMode;
import org.sonar.scanner.repository.ProjectRepositories;
@@ -44,30 +44,28 @@ public class DefaultModuleFileSystem extends DefaultFileSystem {
private List<File> sourceDirsOrFiles = Lists.newArrayList();
private List<File> testDirsOrFiles = Lists.newArrayList();
- private ComponentIndexer componentIndexer;
private boolean initialized;
private Charset charset = null;
- public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, Project project,
- Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode,
+ public DefaultModuleFileSystem(ModuleInputComponentStore moduleInputFileCache, DefaultInputModule module,
+ Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, DefaultAnalysisMode mode,
ProjectRepositories projectRepositories) {
super(initializer.baseDir(), moduleInputFileCache);
- setFields(project, settings, indexer, initializer, componentIndexer, mode, projectRepositories);
+ setFields(module, settings, indexer, initializer, mode, projectRepositories);
}
@VisibleForTesting
- public DefaultModuleFileSystem(Project project,
- Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode,
+ public DefaultModuleFileSystem(DefaultInputModule module,
+ Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, DefaultAnalysisMode mode,
ProjectRepositories projectRepositories) {
super(initializer.baseDir().toPath());
- setFields(project, settings, indexer, initializer, componentIndexer, mode, projectRepositories);
+ setFields(module, settings, indexer, initializer, mode, projectRepositories);
}
- private void setFields(Project project,
- Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode,
+ private void setFields(DefaultInputModule module,
+ Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, DefaultAnalysisMode mode,
ProjectRepositories projectRepositories) {
- this.componentIndexer = componentIndexer;
- this.moduleKey = project.getKey();
+ this.moduleKey = module.key();
this.settings = settings;
this.indexer = indexer;
setWorkDir(initializer.workingDir());
@@ -127,9 +125,6 @@ public class DefaultModuleFileSystem extends DefaultFileSystem {
}
initialized = true;
indexer.index(this);
- if (componentIndexer != null) {
- componentIndexer.execute(this);
- }
}
@Override
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
index 046a0a448a0..4b1d99e355c 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
@@ -44,13 +44,15 @@ import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
import org.sonar.api.batch.fs.internal.DefaultInputDir;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.batch.fs.InputFileFilter;
import org.sonar.api.utils.MessageException;
+import org.sonar.scanner.scan.DefaultComponentTree;
import org.sonar.scanner.util.ProgressReport;
/**
- * Index input files into {@link InputPathCache}.
+ * Index input files into {@link InputComponentStore}.
*/
@ScannerSide
public class FileIndexer {
@@ -59,13 +61,21 @@ public class FileIndexer {
private final InputFileFilter[] filters;
private final boolean isAggregator;
private final ExclusionFilters exclusionFilters;
+ private final IndexedFileBuilder indexedFileBuilder;
+ private final MetadataGenerator metadataGenerator;
+ private final DefaultComponentTree componentTree;
+ private final DefaultInputModule module;
+ private final BatchIdGenerator batchIdGenerator;
+ private final InputComponentStore componentStore;
private ProgressReport progressReport;
- private IndexedFileBuilder indexedFileBuilder;
- private MetadataGenerator metadataGenerator;
- public FileIndexer(ExclusionFilters exclusionFilters, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def,
- InputFileFilter[] filters) {
+ public FileIndexer(BatchIdGenerator batchIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters,
+ DefaultComponentTree componentTree, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def, InputFileFilter[] filters) {
+ this.batchIdGenerator = batchIdGenerator;
+ this.componentStore = componentStore;
+ this.module = module;
+ this.componentTree = componentTree;
this.indexedFileBuilder = indexedFileBuilder;
this.metadataGenerator = inputFileBuilder;
this.filters = filters;
@@ -73,11 +83,13 @@ public class FileIndexer {
this.isAggregator = !def.getSubProjects().isEmpty();
}
- public FileIndexer(ExclusionFilters exclusionFilters, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def) {
- this(exclusionFilters, indexedFileBuilder, inputFileBuilder, def, new InputFileFilter[0]);
+ public FileIndexer(BatchIdGenerator batchIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters,
+ DefaultComponentTree componentTree, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def) {
+ this(batchIdGenerator, componentStore, module, exclusionFilters, componentTree, indexedFileBuilder, inputFileBuilder, def, new InputFileFilter[0]);
}
void index(DefaultModuleFileSystem fileSystem) {
+ fileSystem.add(module);
if (isAggregator) {
// No indexing for an aggregator module
return;
@@ -102,7 +114,7 @@ public class FileIndexer {
try {
for (File dirOrFile : sources) {
if (dirOrFile.isDirectory()) {
- indexDirectory(fileSystem, progress, dirOrFile, type);
+ indexDirectory(fileSystem, progress, dirOrFile.toPath(), type);
} else {
indexFile(fileSystem, progress, dirOrFile.toPath(), type);
}
@@ -112,8 +124,8 @@ public class FileIndexer {
}
}
- private void indexDirectory(final DefaultModuleFileSystem fileSystem, final Progress status, final File dirToIndex, final InputFile.Type type) throws IOException {
- Files.walkFileTree(dirToIndex.toPath().normalize(), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
+ private void indexDirectory(final DefaultModuleFileSystem fileSystem, final Progress status, final Path dirToIndex, final InputFile.Type type) throws IOException {
+ Files.walkFileTree(dirToIndex.normalize(), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new IndexFileVisitor(fileSystem, status, type));
}
@@ -122,12 +134,10 @@ public class FileIndexer {
Path realFile = sourceFile.toRealPath(LinkOption.NOFOLLOW_LINKS);
DefaultIndexedFile indexedFile = indexedFileBuilder.create(realFile, type, fileSystem.baseDirPath());
if (indexedFile != null) {
- if (exclusionFilters.accept(indexedFile, type)) {
- InputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.readMetadata(f, fileSystem.encoding()));
- if (accept(inputFile)) {
- fileSystem.add(inputFile);
- }
- indexParentDir(fileSystem, indexedFile);
+ InputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.readMetadata(f, fileSystem.encoding()));
+ if (exclusionFilters.accept(indexedFile, type) && accept(inputFile)) {
+ fileSystem.add(inputFile);
+ indexParentDir(fileSystem, inputFile);
progress.markAsIndexed(indexedFile);
LOG.debug("'{}' indexed {} with language '{}'", indexedFile.relativePath(), type == Type.TEST ? "as test " : "", indexedFile.language());
} else {
@@ -136,18 +146,25 @@ public class FileIndexer {
}
}
- private static void indexParentDir(DefaultModuleFileSystem fileSystem, IndexedFile indexedFile) {
- File parentDir = indexedFile.file().getParentFile();
- String relativePath = new PathResolver().relativePath(fileSystem.baseDir(), parentDir);
- if (relativePath != null) {
- DefaultInputDir inputDir = new DefaultInputDir(fileSystem.moduleKey(), relativePath);
+ private void indexParentDir(DefaultModuleFileSystem fileSystem, InputFile inputFile) {
+ Path parentDir = inputFile.path().getParent();
+ String relativePath = new PathResolver().relativePath(fileSystem.baseDirPath(), parentDir);
+ if (relativePath == null) {
+ throw new IllegalStateException("Failed to compute relative path of file: " + inputFile);
+ }
+
+ DefaultInputDir inputDir = (DefaultInputDir) componentStore.getDir(module.key(), relativePath);
+ if (inputDir == null) {
+ inputDir = new DefaultInputDir(fileSystem.moduleKey(), relativePath, batchIdGenerator.get());
inputDir.setModuleBaseDir(fileSystem.baseDirPath());
fileSystem.add(inputDir);
+ componentTree.index(inputDir, module);
}
+ componentTree.index(inputFile, inputDir);
}
private boolean accept(InputFile indexedFile) {
- // InputFileFilter extensions
+ // InputFileFilter extensions. Might trigger generation of metadata
for (InputFileFilter filter : filters) {
if (!filter.accept(indexedFile)) {
LOG.debug("'{}' excluded by {}", indexedFile.relativePath(), filter.getClass().getName());
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java
index 352065dbcb7..1db56df4c15 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java
@@ -37,12 +37,14 @@ public class IndexedFileBuilder {
private final PathResolver pathResolver;
private final LanguageDetection langDetection;
private final Settings settings;
+ private final BatchIdGenerator idGenerator;
- IndexedFileBuilder(String moduleKey, PathResolver pathResolver, Settings settings, LanguageDetection langDetection) {
+ IndexedFileBuilder(String moduleKey, PathResolver pathResolver, Settings settings, LanguageDetection langDetection, BatchIdGenerator idGenerator) {
this.moduleKey = moduleKey;
this.pathResolver = pathResolver;
this.settings = settings;
this.langDetection = langDetection;
+ this.idGenerator = idGenerator;
}
@CheckForNull
@@ -52,7 +54,7 @@ public class IndexedFileBuilder {
LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", file.toAbsolutePath(), moduleBaseDir);
return null;
}
- DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type);
+ DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type, idGenerator.get());
String language = langDetection.language(indexedFile);
if (language == null && !settings.getBoolean(CoreProperties.IMPORT_UNKNOWN_FILES_KEY)) {
LOG.debug("'{}' language is not supported by any analyzer. Skipping it.", relativePath);
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java
index c892bf9ff8f..e0bbf85464e 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java
@@ -26,8 +26,9 @@ import org.sonar.api.scan.filesystem.PathResolver;
public class IndexedFileBuilderProvider extends ProviderAdapter {
- public IndexedFileBuilder provide(ProjectDefinition def, PathResolver pathResolver, Settings settings, LanguageDetectionFactory langDetectionFactory) {
- return new IndexedFileBuilder(def.getKeyWithBranch(), pathResolver, settings, langDetectionFactory.create());
+ public IndexedFileBuilder provide(ProjectDefinition def, PathResolver pathResolver, Settings settings,
+ LanguageDetectionFactory langDetectionFactory, BatchIdGenerator idGenerator) {
+ return new IndexedFileBuilder(def.getKey(), pathResolver, settings, langDetectionFactory.create(), idGenerator);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputPathCache.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java
index 2aff151cdc9..88c41a10d08 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputPathCache.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java
@@ -19,23 +19,39 @@
*/
package org.sonar.scanner.scan.filesystem;
-import com.google.common.collect.Table;
-import com.google.common.collect.TreeBasedTable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.CheckForNull;
+
import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import javax.annotation.CheckForNull;
+import com.google.common.collect.Table;
+import com.google.common.collect.TreeBasedTable;
/**
- * Cache of all files and dirs. This cache is shared amongst all project modules. Inclusion and
+ * Store of all files and dirs. This cache is shared amongst all project modules. Inclusion and
* exclusion patterns are already applied.
*/
@ScannerSide
-public class InputPathCache {
+public class InputComponentStore {
private final Table<String, String, InputFile> inputFileCache = TreeBasedTable.create();
private final Table<String, String, InputDir> inputDirCache = TreeBasedTable.create();
+ private final Map<String, InputModule> inputModuleCache = new HashMap<>();
+ private final Map<String, InputComponent> inputComponents = new HashMap<>();
+ private InputModule root;
+
+ public Collection<InputComponent> all() {
+ return inputComponents.values();
+ }
public Iterable<InputFile> allFiles() {
return inputFileCache.values();
@@ -45,6 +61,19 @@ public class InputPathCache {
return inputDirCache.values();
}
+ public InputComponent getByKey(String key) {
+ return inputComponents.get(key);
+ }
+
+ public void setRoot(InputModule root) {
+ this.root = root;
+ }
+
+ @CheckForNull
+ public InputModule root() {
+ return root;
+ }
+
public Iterable<InputFile> filesByModule(String moduleKey) {
return inputFileCache.row(moduleKey).values();
}
@@ -53,29 +82,35 @@ public class InputPathCache {
return inputDirCache.row(moduleKey).values();
}
- public InputPathCache removeModule(String moduleKey) {
+ public InputComponentStore removeModule(String moduleKey) {
inputFileCache.row(moduleKey).clear();
inputDirCache.row(moduleKey).clear();
return this;
}
- public InputPathCache remove(String moduleKey, InputFile inputFile) {
- inputFileCache.remove(moduleKey, inputFile.relativePath());
+ public InputComponentStore remove(InputFile inputFile) {
+ DefaultInputFile file = (DefaultInputFile) inputFile;
+ inputFileCache.remove(file.moduleKey(), inputFile.relativePath());
return this;
}
- public InputPathCache remove(String moduleKey, InputDir inputDir) {
- inputDirCache.remove(moduleKey, inputDir.relativePath());
+ public InputComponentStore remove(InputDir inputDir) {
+ DefaultInputDir dir = (DefaultInputDir) inputDir;
+ inputDirCache.remove(dir.moduleKey(), inputDir.relativePath());
return this;
}
- public InputPathCache put(String moduleKey, InputFile inputFile) {
- inputFileCache.put(moduleKey, inputFile.relativePath(), inputFile);
+ public InputComponentStore put(InputFile inputFile) {
+ DefaultInputFile file = (DefaultInputFile) inputFile;
+ inputFileCache.put(file.moduleKey(), inputFile.relativePath(), inputFile);
+ inputComponents.put(inputFile.key(), inputFile);
return this;
}
- public InputPathCache put(String moduleKey, InputDir inputDir) {
- inputDirCache.put(moduleKey, inputDir.relativePath(), inputDir);
+ public InputComponentStore put(InputDir inputDir) {
+ DefaultInputDir dir = (DefaultInputDir) inputDir;
+ inputDirCache.put(dir.moduleKey(), inputDir.relativePath(), inputDir);
+ inputComponents.put(inputDir.key(), inputDir);
return this;
}
@@ -89,4 +124,14 @@ public class InputPathCache {
return inputDirCache.get(moduleKey, relativePath);
}
+ @CheckForNull
+ public InputModule getModule(String moduleKey) {
+ return inputModuleCache.get(moduleKey);
+ }
+
+ public void put(InputModule inputModule) {
+ inputComponents.put(inputModule.key(), inputModule);
+ inputModuleCache.put(inputModule.key(), inputModule);
+ }
+
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputFileCache.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java
index 4f421964ca7..9b4e5762fb1 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputFileCache.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java
@@ -20,44 +20,54 @@
package org.sonar.scanner.scan.filesystem;
import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
@ScannerSide
-public class ModuleInputFileCache extends DefaultFileSystem.Cache {
+public class ModuleInputComponentStore extends DefaultFileSystem.Cache {
private final String moduleKey;
- private final InputPathCache inputPathCache;
+ private final InputComponentStore inputComponentStore;
- public ModuleInputFileCache(ProjectDefinition projectDef, InputPathCache projectCache) {
- this.moduleKey = projectDef.getKeyWithBranch();
- this.inputPathCache = projectCache;
+ public ModuleInputComponentStore(InputModule module, InputComponentStore inputComponentStore) {
+ this.moduleKey = module.key();
+ this.inputComponentStore = inputComponentStore;
}
@Override
public Iterable<InputFile> inputFiles() {
- return inputPathCache.filesByModule(moduleKey);
+ return inputComponentStore.filesByModule(moduleKey);
}
@Override
public InputFile inputFile(String relativePath) {
- return inputPathCache.getFile(moduleKey, relativePath);
+ return inputComponentStore.getFile(moduleKey, relativePath);
}
@Override
public InputDir inputDir(String relativePath) {
- return inputPathCache.getDir(moduleKey, relativePath);
+ return inputComponentStore.getDir(moduleKey, relativePath);
}
@Override
protected void doAdd(InputFile inputFile) {
- inputPathCache.put(moduleKey, inputFile);
+ inputComponentStore.put(inputFile);
}
@Override
protected void doAdd(InputDir inputDir) {
- inputPathCache.put(moduleKey, inputDir);
+ inputComponentStore.put(inputDir);
+ }
+
+ @Override
+ protected void doAdd(InputModule inputModule) {
+ inputComponentStore.put(inputModule);
+ }
+
+ @Override
+ public InputModule module() {
+ return inputComponentStore.getModule(moduleKey);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ConsoleReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ConsoleReport.java
index d4ddff8b2e7..94f7054a128 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ConsoleReport.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ConsoleReport.java
@@ -30,7 +30,7 @@ import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.scanner.issue.IssueCache;
import org.sonar.scanner.issue.tracking.TrackedIssue;
-import org.sonar.scanner.scan.filesystem.InputPathCache;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
@Properties({
@Property(key = ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, defaultValue = "false", name = "Enable console report",
@@ -47,10 +47,10 @@ public class ConsoleReport implements Reporter {
private Settings settings;
private IssueCache issueCache;
- private InputPathCache inputPathCache;
+ private InputComponentStore inputPathCache;
@VisibleForTesting
- public ConsoleReport(Settings settings, IssueCache issueCache, InputPathCache inputPathCache) {
+ public ConsoleReport(Settings settings, IssueCache issueCache, InputComponentStore inputPathCache) {
this.settings = settings;
this.issueCache = issueCache;
this.inputPathCache = inputPathCache;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReport.java
index 470c2d0339e..5da5cb78345 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReport.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReport.java
@@ -24,9 +24,10 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
+
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.rules.RulePriority;
-import org.sonar.scanner.index.BatchComponent;
import org.sonar.scanner.issue.tracking.TrackedIssue;
public class IssuesReport {
@@ -36,7 +37,7 @@ public class IssuesReport {
private Date date;
private boolean noFile;
private final ReportSummary summary = new ReportSummary();
- private final Map<BatchComponent, ResourceReport> resourceReportsByResource = Maps.newLinkedHashMap();
+ private final Map<InputComponent, ResourceReport> resourceReportsByResource = Maps.newLinkedHashMap();
public ReportSummary getSummary() {
return summary;
@@ -66,7 +67,7 @@ public class IssuesReport {
this.noFile = noFile;
}
- public Map<BatchComponent, ResourceReport> getResourceReportsByResource() {
+ public Map<InputComponent, ResourceReport> getResourceReportsByResource() {
return resourceReportsByResource;
}
@@ -74,25 +75,25 @@ public class IssuesReport {
return new ArrayList<>(resourceReportsByResource.values());
}
- public List<BatchComponent> getResourcesWithReport() {
+ public List<InputComponent> getResourcesWithReport() {
return new ArrayList<>(resourceReportsByResource.keySet());
}
- public void addIssueOnResource(BatchComponent resource, TrackedIssue issue, Rule rule, RulePriority severity) {
+ public void addIssueOnResource(InputComponent resource, TrackedIssue issue, Rule rule, RulePriority severity) {
addResource(resource);
getSummary().addIssue(issue, rule, severity);
resourceReportsByResource.get(resource).addIssue(issue, rule, severity);
}
- public void addResolvedIssueOnResource(BatchComponent resource, Rule rule, RulePriority severity) {
+ public void addResolvedIssueOnResource(InputComponent resource, Rule rule, RulePriority severity) {
addResource(resource);
getSummary().addResolvedIssue(rule, severity);
resourceReportsByResource.get(resource).addResolvedIssue(rule, severity);
}
- private void addResource(BatchComponent resource) {
- if (!resourceReportsByResource.containsKey(resource)) {
- resourceReportsByResource.put(resource, new ResourceReport(resource));
+ private void addResource(InputComponent componnet) {
+ if (!resourceReportsByResource.containsKey(componnet)) {
+ resourceReportsByResource.put(componnet, new ResourceReport(componnet));
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReportBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReportBuilder.java
index cd39b0750c2..7d5e82a2f8f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReportBuilder.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/IssuesReportBuilder.java
@@ -24,16 +24,16 @@ import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.resources.Project;
import org.sonar.api.rules.RulePriority;
-import org.sonar.scanner.DefaultProjectTree;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
+import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.issue.IssueCache;
import org.sonar.scanner.issue.tracking.TrackedIssue;
-import org.sonar.scanner.scan.filesystem.InputPathCache;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
@ScannerSide
public class IssuesReportBuilder {
@@ -42,24 +42,25 @@ public class IssuesReportBuilder {
private final IssueCache issueCache;
private final Rules rules;
- private final BatchComponentCache resourceCache;
- private final DefaultProjectTree projectTree;
- private final InputPathCache inputPathCache;
+ private final InputComponentStore inputComponentCache;
+ private final InputModuleHierarchy moduleHierarchy;
+ private final ProjectAnalysisInfo projectAnalysisInfo;
- public IssuesReportBuilder(IssueCache issueCache, Rules rules, BatchComponentCache resourceCache, DefaultProjectTree projectTree, InputPathCache inputPathCache) {
+ public IssuesReportBuilder(IssueCache issueCache, Rules rules, ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy,
+ InputComponentStore inputComponentCache) {
this.issueCache = issueCache;
this.rules = rules;
- this.resourceCache = resourceCache;
- this.projectTree = projectTree;
- this.inputPathCache = inputPathCache;
+ this.projectAnalysisInfo = projectAnalysisInfo;
+ this.moduleHierarchy = moduleHierarchy;
+ this.inputComponentCache = inputComponentCache;
}
public IssuesReport buildReport() {
- Project project = projectTree.getRootProject();
+ DefaultInputModule project = moduleHierarchy.root();
IssuesReport issuesReport = new IssuesReport();
- issuesReport.setNoFile(!inputPathCache.allFiles().iterator().hasNext());
- issuesReport.setTitle(project.getName());
- issuesReport.setDate(project.getAnalysisDate());
+ issuesReport.setNoFile(!inputComponentCache.allFiles().iterator().hasNext());
+ issuesReport.setTitle(project.definition().getName());
+ issuesReport.setDate(projectAnalysisInfo.analysisDate());
processIssues(issuesReport, issueCache.all());
@@ -70,7 +71,7 @@ public class IssuesReportBuilder {
for (TrackedIssue issue : issues) {
Rule rule = findRule(issue);
RulePriority severity = RulePriority.valueOf(issue.severity());
- BatchComponent resource = resourceCache.get(issue.componentKey());
+ InputComponent resource = inputComponentCache.getByKey(issue.componentKey());
if (!validate(issue, rule, resource)) {
continue;
}
@@ -82,7 +83,7 @@ public class IssuesReportBuilder {
}
}
- private static boolean validate(TrackedIssue issue, @Nullable Rule rule, @Nullable BatchComponent resource) {
+ private static boolean validate(TrackedIssue issue, @Nullable Rule rule, @Nullable InputComponent resource) {
if (rule == null) {
LOG.warn("Unknow rule for issue {}", issue);
return false;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java
index 05cc7f08717..f1ce2013147 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java
@@ -43,11 +43,12 @@ 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.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.Rules;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.Server;
-import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.scanner.issue.IssueCache;
@@ -55,7 +56,7 @@ import org.sonar.scanner.issue.tracking.TrackedIssue;
import org.sonar.scanner.protocol.input.ScannerInput;
import org.sonar.scanner.protocol.input.ScannerInput.User;
import org.sonar.scanner.repository.user.UserRepositoryLoader;
-import org.sonar.scanner.scan.filesystem.InputPathCache;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
@Properties({
@Property(
@@ -72,12 +73,14 @@ public class JSONReport implements Reporter {
private final Server server;
private final Rules rules;
private final IssueCache issueCache;
- private final InputPathCache fileCache;
- private final Project rootModule;
+ private final InputComponentStore fileCache;
+ private final DefaultInputModule rootModule;
private final UserRepositoryLoader userRepository;
+ private final InputModuleHierarchy moduleHierarchy;
- public JSONReport(Settings settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache,
- Project rootModule, InputPathCache fileCache, UserRepositoryLoader userRepository) {
+ public JSONReport(InputModuleHierarchy moduleHierarchy, Settings settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache,
+ DefaultInputModule rootModule, InputComponentStore fileCache, UserRepositoryLoader userRepository) {
+ this.moduleHierarchy = moduleHierarchy;
this.settings = settings;
this.fileSystem = fileSystem;
this.server = server;
@@ -186,13 +189,13 @@ public class JSONReport implements Reporter {
json.endArray();
}
- private static void writeJsonModuleComponents(JsonWriter json, Project module) {
+ private void writeJsonModuleComponents(JsonWriter json, DefaultInputModule module) {
json
.beginObject()
- .prop("key", module.getEffectiveKey())
- .prop("path", module.getPath())
+ .prop("key", module.key())
+ .prop("path", moduleHierarchy.relativePath(module))
.endObject();
- for (Project subModule : module.getModules()) {
+ for (DefaultInputModule subModule : moduleHierarchy.children(module)) {
writeJsonModuleComponents(json, subModule);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ResourceReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ResourceReport.java
index e0bf1df43ca..fb6782b3d91 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ResourceReport.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/ResourceReport.java
@@ -26,13 +26,19 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
+
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.InputDir;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.rules.RulePriority;
-import org.sonar.scanner.index.BatchComponent;
import org.sonar.scanner.issue.tracking.TrackedIssue;
public final class ResourceReport {
- private final BatchComponent resource;
+ private final InputComponent component;
private final IssueVariation total = new IssueVariation();
private final Map<ReportRuleKey, RuleReport> ruleReportByRuleKey = Maps.newHashMap();
@@ -42,24 +48,41 @@ public final class ResourceReport {
private Map<Rule, AtomicInteger> issuesByRule = Maps.newHashMap();
private Map<RulePriority, AtomicInteger> issuesBySeverity = Maps.newHashMap();
- public ResourceReport(BatchComponent resource) {
- this.resource = resource;
+ public ResourceReport(InputComponent component) {
+ this.component = component;
}
- public BatchComponent getResourceNode() {
- return resource;
+ public InputComponent getResourceNode() {
+ return component;
}
public String getName() {
- return resource.resource().getName();
+ if (component instanceof InputPath) {
+ InputPath inputPath = (InputPath) component;
+ return inputPath.path().getFileName().toString();
+ } else if (component instanceof InputModule) {
+ DefaultInputModule module = (DefaultInputModule) component;
+ return module.definition().getName();
+ }
+ throw new IllegalStateException("Unknown component type: " + component.getClass());
}
public String getKey() {
- return resource.inputComponent().key();
+ return component.key();
}
+ /**
+ * Must match one of the png in the resources, under org/scanner/scan/report/issuesreport_files
+ */
public String getType() {
- return resource.resource().getScope();
+ if (component instanceof InputFile) {
+ return "FIL";
+ } else if (component instanceof InputDir) {
+ return "DIR";
+ } else if (component instanceof InputModule) {
+ return "PRJ";
+ }
+ throw new IllegalStateException("Unknown component type: " + component.getClass());
}
public IssueVariation getTotal() {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/SourceProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/SourceProvider.java
index 6587e24933c..3bd94acd7c2 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/SourceProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/SourceProvider.java
@@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.scanner.index.BatchComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
@ScannerSide
public class SourceProvider {
@@ -42,13 +42,13 @@ public class SourceProvider {
this.fs = fs;
}
- public List<String> getEscapedSource(BatchComponent component) {
+ public List<String> getEscapedSource(DefaultInputComponent component) {
if (!component.isFile()) {
// Folder
return Collections.emptyList();
}
try {
- InputFile inputFile = (InputFile) component.inputComponent();
+ InputFile inputFile = (InputFile) component;
List<String> lines = FileUtils.readLines(inputFile.file(), fs.encoding());
List<String> escapedLines = new ArrayList<>(lines.size());
for (String line : lines) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java
index 4cbb59f995f..cc56fadfd19 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java
@@ -31,12 +31,11 @@ import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.scm.BlameCommand.BlameOutput;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder;
import org.sonar.scanner.util.ProgressReport;
@@ -50,15 +49,13 @@ class DefaultBlameOutput implements BlameOutput {
private static final Pattern ACCENT_CODES = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
private final ScannerReportWriter writer;
- private final BatchComponentCache componentCache;
private final Set<InputFile> allFilesToBlame = new HashSet<>();
private ProgressReport progressReport;
private int count;
private int total;
- DefaultBlameOutput(ScannerReportWriter writer, BatchComponentCache componentCache, List<InputFile> filesToBlame) {
+ DefaultBlameOutput(ScannerReportWriter writer, List<InputFile> filesToBlame) {
this.writer = writer;
- this.componentCache = componentCache;
this.allFilesToBlame.addAll(filesToBlame);
count = 0;
total = filesToBlame.size();
@@ -77,9 +74,9 @@ class DefaultBlameOutput implements BlameOutput {
return;
}
- BatchComponent batchComponent = componentCache.get(file);
Builder scmBuilder = ScannerReport.Changesets.newBuilder();
- scmBuilder.setComponentRef(batchComponent.batchId());
+ DefaultInputFile inputFile = (DefaultInputFile) file;
+ scmBuilder.setComponentRef(inputFile.batchId());
Map<String, Integer> changesetsIdByRevision = new HashMap<>();
int lineId = 1;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmSensor.java
index 0783726ac94..3f00b5b5c58 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmSensor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmSensor.java
@@ -27,13 +27,12 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Status;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.scanner.index.BatchComponent;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder;
import org.sonar.scanner.report.ReportPublisher;
@@ -48,16 +47,14 @@ public final class ScmSensor implements Sensor {
private final ScmConfiguration configuration;
private final FileSystem fs;
private final ProjectRepositories projectRepositories;
- private final BatchComponentCache componentCache;
private final ReportPublisher publishReportJob;
public ScmSensor(ProjectDefinition projectDefinition, ScmConfiguration configuration,
- ProjectRepositories projectRepositories, FileSystem fs, BatchComponentCache componentCache, ReportPublisher publishReportJob) {
+ ProjectRepositories projectRepositories, FileSystem fs, ReportPublisher publishReportJob) {
this.projectDefinition = projectDefinition;
this.configuration = configuration;
this.projectRepositories = projectRepositories;
this.fs = fs;
- this.componentCache = componentCache;
this.publishReportJob = publishReportJob;
}
@@ -81,7 +78,7 @@ public final class ScmSensor implements Sensor {
if (!filesToBlame.isEmpty()) {
String key = configuration.provider().key();
LOG.info("SCM provider for this project is: " + key);
- DefaultBlameOutput output = new DefaultBlameOutput(publishReportJob.getWriter(), componentCache, filesToBlame);
+ DefaultBlameOutput output = new DefaultBlameOutput(publishReportJob.getWriter(), filesToBlame);
try {
configuration.provider().blameCommand().blame(new DefaultBlameInput(fs, filesToBlame), output);
} catch (Exception e) {
@@ -106,17 +103,16 @@ public final class ScmSensor implements Sensor {
if (StringUtils.isEmpty(fileData.revision())) {
addIfNotEmpty(filesToBlame, f);
} else {
- askToCopyDataFromPreviousAnalysis(f);
+ askToCopyDataFromPreviousAnalysis((DefaultInputFile) f);
}
}
}
return filesToBlame;
}
- private void askToCopyDataFromPreviousAnalysis(InputFile f) {
- BatchComponent batchComponent = componentCache.get(f);
+ private void askToCopyDataFromPreviousAnalysis(DefaultInputFile f) {
Builder scmBuilder = ScannerReport.Changesets.newBuilder();
- scmBuilder.setComponentRef(batchComponent.batchId());
+ scmBuilder.setComponentRef(f.batchId());
scmBuilder.setCopyFromPrevious(true);
publishReportJob.getWriter().writeComponentChangesets(scmBuilder.build());
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
index ec7b8cfe5b6..8600ec3fdab 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
@@ -23,6 +23,7 @@ import java.io.Serializable;
import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.SensorContext;
@@ -156,4 +157,9 @@ public class DefaultSensorContext implements SensorContext {
public void addContextProperty(String key, String value) {
sensorStorage.storeProperty(key, value);
}
+
+ @Override
+ public void markForPublishing(InputFile inputFile) {
+
+ }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
index 8beba97adae..051565781cd 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
@@ -33,6 +33,7 @@ import java.util.stream.Stream;
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
@@ -54,7 +55,6 @@ import org.sonar.duplications.block.Block;
import org.sonar.duplications.internal.pmd.PmdBlockChunker;
import org.sonar.scanner.cpd.deprecated.DefaultCpdBlockIndexer;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.issue.ModuleIssues;
import org.sonar.scanner.protocol.output.FileStructure;
import org.sonar.scanner.protocol.output.ScannerReport;
@@ -142,7 +142,6 @@ public class DefaultSensorStorage implements SensorStorage {
private final MetricFinder metricFinder;
private final ModuleIssues moduleIssues;
private final CoverageExclusions coverageExclusions;
- private final BatchComponentCache componentCache;
private final ReportPublisher reportPublisher;
private final MeasureCache measureCache;
private final SonarCpdBlockIndex index;
@@ -156,14 +155,13 @@ public class DefaultSensorStorage implements SensorStorage {
public DefaultSensorStorage(MetricFinder metricFinder, ModuleIssues moduleIssues,
Settings settings,
- CoverageExclusions coverageExclusions, BatchComponentCache componentCache, ReportPublisher reportPublisher,
+ CoverageExclusions coverageExclusions, ReportPublisher reportPublisher,
MeasureCache measureCache, SonarCpdBlockIndex index,
ContextPropertiesCache contextPropertiesCache, ScannerMetrics scannerMetrics) {
this.metricFinder = metricFinder;
this.moduleIssues = moduleIssues;
this.settings = settings;
this.coverageExclusions = coverageExclusions;
- this.componentCache = componentCache;
this.reportPublisher = reportPublisher;
this.measureCache = measureCache;
this.index = index;
@@ -352,8 +350,8 @@ public class DefaultSensorStorage implements SensorStorage {
@Override
public void store(DefaultHighlighting highlighting) {
ScannerReportWriter writer = reportPublisher.getWriter();
- InputFile inputFile = highlighting.inputFile();
- int componentRef = componentCache.get(inputFile).batchId();
+ DefaultInputFile inputFile = (DefaultInputFile) highlighting.inputFile();
+ int componentRef = inputFile.batchId();
if (writer.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, componentRef)) {
throw new UnsupportedOperationException("Trying to save highlighting twice for the same file is not supported: " + inputFile.absolutePath());
}
@@ -376,7 +374,8 @@ public class DefaultSensorStorage implements SensorStorage {
@Override
public void store(DefaultSymbolTable symbolTable) {
ScannerReportWriter writer = reportPublisher.getWriter();
- int componentRef = componentCache.get(symbolTable.inputFile()).batchId();
+ DefaultInputFile inputFile = (DefaultInputFile) symbolTable.inputFile();
+ int componentRef = inputFile.batchId();
if (writer.hasComponentData(FileStructure.Domain.SYMBOLS, componentRef)) {
throw new UnsupportedOperationException("Trying to save symbol table twice for the same file is not supported: " + symbolTable.inputFile().absolutePath());
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/CodeColorizerSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/CodeColorizerSensor.java
index 3b5f2c5ec44..fb030a3d75a 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/CodeColorizerSensor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/CodeColorizerSensor.java
@@ -22,10 +22,10 @@ package org.sonar.scanner.source;
import org.sonar.api.batch.Phase;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.report.ReportPublisher;
@@ -33,12 +33,10 @@ import org.sonar.scanner.report.ReportPublisher;
public final class CodeColorizerSensor implements Sensor {
private final ReportPublisher reportPublisher;
- private final BatchComponentCache resourceCache;
private final CodeColorizers codeColorizers;
- public CodeColorizerSensor(ReportPublisher reportPublisher, BatchComponentCache resourceCache, CodeColorizers codeColorizers) {
+ public CodeColorizerSensor(ReportPublisher reportPublisher, CodeColorizers codeColorizers) {
this.reportPublisher = reportPublisher;
- this.resourceCache = resourceCache;
this.codeColorizers = codeColorizers;
}
@@ -52,9 +50,9 @@ public final class CodeColorizerSensor implements Sensor {
FileSystem fs = context.fileSystem();
for (InputFile f : fs.inputFiles(fs.predicates().all())) {
ScannerReportReader reader = new ScannerReportReader(reportPublisher.getReportDir());
- int batchId = resourceCache.get(f).batchId();
+ DefaultInputFile inputFile = (DefaultInputFile) f;
String language = f.language();
- if (reader.hasSyntaxHighlighting(batchId) || language == null) {
+ if (reader.hasSyntaxHighlighting(inputFile.batchId()) || language == null) {
continue;
}
codeColorizers.toSyntaxHighlighting(f.file(), fs.encoding(), language, context.newHighlighting().onFile(f));