aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/sonar-core-plugin
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2013-10-02 16:00:16 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2013-10-02 16:10:29 +0200
commitd1ed91b890bfec5df267fff19faca781848be242 (patch)
tree12d724f59edc85c9bdc54d2c9fc5f4cde773b57e /plugins/sonar-core-plugin
parentf6af69b24e93bb1262b9c02d8865e88cffa8d9a5 (diff)
downloadsonarqube-d1ed91b890bfec5df267fff19faca781848be242.tar.gz
sonarqube-d1ed91b890bfec5df267fff19faca781848be242.zip
SONAR-2657 Expose changed files API in ModuleFileSystem
Diffstat (limited to 'plugins/sonar-core-plugin')
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java312
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/PartialScanFilter.java126
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java18
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/HashBuilder.java46
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/package-info.java23
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/PartialScanFilterTest.java161
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java14
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/utils/HashBuilderTest.java49
8 files changed, 208 insertions, 541 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
index 4fcf1dc68b3..adea1718036 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
@@ -19,11 +19,12 @@
*/
package org.sonar.plugins.core;
-import org.sonar.plugins.core.batch.PartialScanFilter;
-
-import org.sonar.plugins.core.utils.HashBuilder;
import com.google.common.collect.ImmutableList;
-import org.sonar.api.*;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.Properties;
+import org.sonar.api.Property;
+import org.sonar.api.PropertyType;
+import org.sonar.api.SonarPlugin;
import org.sonar.api.checks.NoSonarFilter;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.Java;
@@ -35,21 +36,91 @@ import org.sonar.plugins.core.charts.DistributionAreaChart;
import org.sonar.plugins.core.charts.DistributionBarChart;
import org.sonar.plugins.core.charts.XradarChart;
import org.sonar.plugins.core.colorizers.JavaColorizerFormat;
-import org.sonar.plugins.core.dashboards.*;
-import org.sonar.plugins.core.issue.*;
+import org.sonar.plugins.core.dashboards.GlobalDefaultDashboard;
+import org.sonar.plugins.core.dashboards.ProjectDefaultDashboard;
+import org.sonar.plugins.core.dashboards.ProjectHotspotDashboard;
+import org.sonar.plugins.core.dashboards.ProjectIssuesDashboard;
+import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard;
+import org.sonar.plugins.core.issue.CountFalsePositivesDecorator;
+import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator;
+import org.sonar.plugins.core.issue.InitialOpenIssuesSensor;
+import org.sonar.plugins.core.issue.InitialOpenIssuesStack;
+import org.sonar.plugins.core.issue.IssueHandlers;
+import org.sonar.plugins.core.issue.IssueTracking;
+import org.sonar.plugins.core.issue.IssueTrackingDecorator;
+import org.sonar.plugins.core.issue.IssuesDensityDecorator;
+import org.sonar.plugins.core.issue.WeightedIssuesDecorator;
import org.sonar.plugins.core.issue.ignore.IgnoreIssuesPlugin;
-import org.sonar.plugins.core.issue.notification.*;
+import org.sonar.plugins.core.issue.notification.ChangesOnMyIssueNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.IssueChangesEmailTemplate;
+import org.sonar.plugins.core.issue.notification.NewFalsePositiveNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.NewIssuesEmailTemplate;
+import org.sonar.plugins.core.issue.notification.NewIssuesNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.SendIssueNotificationsPostJob;
import org.sonar.plugins.core.measurefilters.MyFavouritesFilter;
import org.sonar.plugins.core.measurefilters.ProjectFilter;
import org.sonar.plugins.core.notifications.alerts.NewAlerts;
import org.sonar.plugins.core.security.ApplyProjectRolesDecorator;
-import org.sonar.plugins.core.sensors.*;
+import org.sonar.plugins.core.sensors.BranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.CheckAlertThresholds;
+import org.sonar.plugins.core.sensors.CommentDensityDecorator;
+import org.sonar.plugins.core.sensors.CoverageDecorator;
+import org.sonar.plugins.core.sensors.CoverageMeasurementFilter;
+import org.sonar.plugins.core.sensors.DirectoriesDecorator;
+import org.sonar.plugins.core.sensors.FileHashSensor;
+import org.sonar.plugins.core.sensors.FilesDecorator;
+import org.sonar.plugins.core.sensors.GenerateAlertEvents;
+import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.ItCoverageDecorator;
+import org.sonar.plugins.core.sensors.ItLineCoverageDecorator;
+import org.sonar.plugins.core.sensors.LineCoverageDecorator;
+import org.sonar.plugins.core.sensors.ManualMeasureDecorator;
+import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.OverallCoverageDecorator;
+import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator;
+import org.sonar.plugins.core.sensors.ProfileEventsSensor;
+import org.sonar.plugins.core.sensors.ProfileSensor;
+import org.sonar.plugins.core.sensors.ProjectLinksSensor;
+import org.sonar.plugins.core.sensors.UnitTestDecorator;
+import org.sonar.plugins.core.sensors.VersionEventsSensor;
import org.sonar.plugins.core.technicaldebt.TechnicalDebtDecorator;
-import org.sonar.plugins.core.timemachine.*;
+import org.sonar.plugins.core.timemachine.NewCoverageAggregator;
+import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.NewOverallCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.TendencyDecorator;
+import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister;
+import org.sonar.plugins.core.timemachine.VariationDecorator;
import org.sonar.plugins.core.web.Lcom4Viewer;
import org.sonar.plugins.core.web.TestsViewer;
-import org.sonar.plugins.core.widgets.*;
-import org.sonar.plugins.core.widgets.issues.*;
+import org.sonar.plugins.core.widgets.AlertsWidget;
+import org.sonar.plugins.core.widgets.ComplexityWidget;
+import org.sonar.plugins.core.widgets.CoverageWidget;
+import org.sonar.plugins.core.widgets.CustomMeasuresWidget;
+import org.sonar.plugins.core.widgets.DescriptionWidget;
+import org.sonar.plugins.core.widgets.DocumentationCommentsWidget;
+import org.sonar.plugins.core.widgets.DuplicationsWidget;
+import org.sonar.plugins.core.widgets.EventsWidget;
+import org.sonar.plugins.core.widgets.HotspotMetricWidget;
+import org.sonar.plugins.core.widgets.HotspotMostViolatedResourcesWidget;
+import org.sonar.plugins.core.widgets.HotspotMostViolatedRulesWidget;
+import org.sonar.plugins.core.widgets.ItCoverageWidget;
+import org.sonar.plugins.core.widgets.MeasureFilterListWidget;
+import org.sonar.plugins.core.widgets.MeasureFilterTreemapWidget;
+import org.sonar.plugins.core.widgets.RulesWidget;
+import org.sonar.plugins.core.widgets.SizeWidget;
+import org.sonar.plugins.core.widgets.TechnicalDebtPyramidWidget;
+import org.sonar.plugins.core.widgets.TechnicalDebtWidget;
+import org.sonar.plugins.core.widgets.TimeMachineWidget;
+import org.sonar.plugins.core.widgets.TimelineWidget;
+import org.sonar.plugins.core.widgets.TreemapWidget;
+import org.sonar.plugins.core.widgets.WelcomeWidget;
+import org.sonar.plugins.core.widgets.issues.ActionPlansWidget;
+import org.sonar.plugins.core.widgets.issues.FalsePositiveIssuesWidget;
+import org.sonar.plugins.core.widgets.issues.IssueFilterWidget;
+import org.sonar.plugins.core.widgets.issues.MyUnresolvedIssuesWidget;
+import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesPerAssigneeWidget;
+import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesStatusesWidget;
import java.util.Arrays;
import java.util.List;
@@ -209,127 +280,125 @@ public final class CorePlugin extends SonarPlugin {
ImmutableList.Builder<Object> extensions = ImmutableList.builder();
extensions.add(
- DefaultResourceTypes.class,
- UserManagedMetrics.class,
- Periods.class,
+ DefaultResourceTypes.class,
+ UserManagedMetrics.class,
+ Periods.class,
- // pages
- Lcom4Viewer.class,
- TestsViewer.class,
+ // pages
+ Lcom4Viewer.class,
+ TestsViewer.class,
- // measure filters
- ProjectFilter.class,
- MyFavouritesFilter.class,
+ // measure filters
+ ProjectFilter.class,
+ MyFavouritesFilter.class,
- // widgets
- AlertsWidget.class,
- CoverageWidget.class,
- ItCoverageWidget.class,
- DescriptionWidget.class,
- ComplexityWidget.class,
- RulesWidget.class,
- SizeWidget.class,
- EventsWidget.class,
- CustomMeasuresWidget.class,
- TimelineWidget.class,
- TimeMachineWidget.class,
- HotspotMetricWidget.class,
- TreemapWidget.class,
- MeasureFilterListWidget.class,
- MeasureFilterTreemapWidget.class,
- WelcomeWidget.class,
- DocumentationCommentsWidget.class,
- DuplicationsWidget.class,
- TechnicalDebtWidget.class,
- TechnicalDebtPyramidWidget.class,
+ // widgets
+ AlertsWidget.class,
+ CoverageWidget.class,
+ ItCoverageWidget.class,
+ DescriptionWidget.class,
+ ComplexityWidget.class,
+ RulesWidget.class,
+ SizeWidget.class,
+ EventsWidget.class,
+ CustomMeasuresWidget.class,
+ TimelineWidget.class,
+ TimeMachineWidget.class,
+ HotspotMetricWidget.class,
+ TreemapWidget.class,
+ MeasureFilterListWidget.class,
+ MeasureFilterTreemapWidget.class,
+ WelcomeWidget.class,
+ DocumentationCommentsWidget.class,
+ DuplicationsWidget.class,
+ TechnicalDebtWidget.class,
+ TechnicalDebtPyramidWidget.class,
- // dashboards
- ProjectDefaultDashboard.class,
- ProjectHotspotDashboard.class,
- ProjectIssuesDashboard.class,
- ProjectTimeMachineDashboard.class,
- GlobalDefaultDashboard.class,
+ // dashboards
+ ProjectDefaultDashboard.class,
+ ProjectHotspotDashboard.class,
+ ProjectIssuesDashboard.class,
+ ProjectTimeMachineDashboard.class,
+ GlobalDefaultDashboard.class,
- // chart
- XradarChart.class,
- DistributionBarChart.class,
- DistributionAreaChart.class,
+ // chart
+ XradarChart.class,
+ DistributionBarChart.class,
+ DistributionAreaChart.class,
- // colorizers
- JavaColorizerFormat.class,
+ // colorizers
+ JavaColorizerFormat.class,
- // issues
- IssueTrackingDecorator.class,
- IssueTracking.class,
- IssueHandlers.class,
- CountUnresolvedIssuesDecorator.class,
- CountFalsePositivesDecorator.class,
- WeightedIssuesDecorator.class,
- IssuesDensityDecorator.class,
- InitialOpenIssuesSensor.class,
- InitialOpenIssuesStack.class,
- HotspotMostViolatedResourcesWidget.class,
- HotspotMostViolatedRulesWidget.class,
- MyUnresolvedIssuesWidget.class,
- FalsePositiveIssuesWidget.class,
- ActionPlansWidget.class,
- UnresolvedIssuesPerAssigneeWidget.class,
- UnresolvedIssuesStatusesWidget.class,
- IssueFilterWidget.class,
- org.sonar.api.issue.NoSonarFilter.class,
+ // issues
+ IssueTrackingDecorator.class,
+ IssueTracking.class,
+ IssueHandlers.class,
+ CountUnresolvedIssuesDecorator.class,
+ CountFalsePositivesDecorator.class,
+ WeightedIssuesDecorator.class,
+ IssuesDensityDecorator.class,
+ InitialOpenIssuesSensor.class,
+ InitialOpenIssuesStack.class,
+ HotspotMostViolatedResourcesWidget.class,
+ HotspotMostViolatedRulesWidget.class,
+ MyUnresolvedIssuesWidget.class,
+ FalsePositiveIssuesWidget.class,
+ ActionPlansWidget.class,
+ UnresolvedIssuesPerAssigneeWidget.class,
+ UnresolvedIssuesStatusesWidget.class,
+ IssueFilterWidget.class,
+ org.sonar.api.issue.NoSonarFilter.class,
- // issue notifications
- SendIssueNotificationsPostJob.class,
- NewIssuesEmailTemplate.class,
- IssueChangesEmailTemplate.class,
- ChangesOnMyIssueNotificationDispatcher.class,
- ChangesOnMyIssueNotificationDispatcher.newMetadata(),
- NewIssuesNotificationDispatcher.class,
- NewIssuesNotificationDispatcher.newMetadata(),
- NewFalsePositiveNotificationDispatcher.class,
- NewFalsePositiveNotificationDispatcher.newMetadata(),
+ // issue notifications
+ SendIssueNotificationsPostJob.class,
+ NewIssuesEmailTemplate.class,
+ IssueChangesEmailTemplate.class,
+ ChangesOnMyIssueNotificationDispatcher.class,
+ ChangesOnMyIssueNotificationDispatcher.newMetadata(),
+ NewIssuesNotificationDispatcher.class,
+ NewIssuesNotificationDispatcher.newMetadata(),
+ NewFalsePositiveNotificationDispatcher.class,
+ NewFalsePositiveNotificationDispatcher.newMetadata(),
- // batch
- ProfileSensor.class,
- ProfileEventsSensor.class,
- ProjectLinksSensor.class,
- UnitTestDecorator.class,
- VersionEventsSensor.class,
- CheckAlertThresholds.class,
- GenerateAlertEvents.class,
- LineCoverageDecorator.class,
- CoverageDecorator.class,
- BranchCoverageDecorator.class,
- ItLineCoverageDecorator.class,
- ItCoverageDecorator.class,
- ItBranchCoverageDecorator.class,
- OverallLineCoverageDecorator.class,
- OverallCoverageDecorator.class,
- OverallBranchCoverageDecorator.class,
- CoverageMeasurementFilter.class,
- ApplyProjectRolesDecorator.class,
- CommentDensityDecorator.class,
- NoSonarFilter.class,
- DirectoriesDecorator.class,
- FilesDecorator.class,
- IndexProjectPostJob.class,
- ManualMeasureDecorator.class,
- HashBuilder.class,
- FileHashSensor.class,
- PartialScanFilter.class,
+ // batch
+ ProfileSensor.class,
+ ProfileEventsSensor.class,
+ ProjectLinksSensor.class,
+ UnitTestDecorator.class,
+ VersionEventsSensor.class,
+ CheckAlertThresholds.class,
+ GenerateAlertEvents.class,
+ LineCoverageDecorator.class,
+ CoverageDecorator.class,
+ BranchCoverageDecorator.class,
+ ItLineCoverageDecorator.class,
+ ItCoverageDecorator.class,
+ ItBranchCoverageDecorator.class,
+ OverallLineCoverageDecorator.class,
+ OverallCoverageDecorator.class,
+ OverallBranchCoverageDecorator.class,
+ CoverageMeasurementFilter.class,
+ ApplyProjectRolesDecorator.class,
+ CommentDensityDecorator.class,
+ NoSonarFilter.class,
+ DirectoriesDecorator.class,
+ FilesDecorator.class,
+ IndexProjectPostJob.class,
+ ManualMeasureDecorator.class,
+ FileHashSensor.class,
- // time machine
- TendencyDecorator.class,
- VariationDecorator.class,
- TimeMachineConfigurationPersister.class,
- NewCoverageFileAnalyzer.class,
- NewItCoverageFileAnalyzer.class,
- NewOverallCoverageFileAnalyzer.class,
- NewCoverageAggregator.class,
+ // time machine
+ TendencyDecorator.class,
+ VariationDecorator.class,
+ TimeMachineConfigurationPersister.class,
+ NewCoverageFileAnalyzer.class,
+ NewItCoverageFileAnalyzer.class,
+ NewOverallCoverageFileAnalyzer.class,
+ NewCoverageAggregator.class,
- // Notify alerts on my favourite projects
- NewAlerts.class,
- NewAlerts.newMetadata());
+ // Notify alerts on my favourite projects
+ NewAlerts.class,
+ NewAlerts.newMetadata());
extensions.addAll(ExclusionProperties.definitions());
extensions.addAll(IgnoreIssuesPlugin.getExtensions());
@@ -341,7 +410,6 @@ public final class CorePlugin extends SonarPlugin {
return extensions.build();
}
-
static List<PropertyDefinition> propertyDefinitions() {
return Arrays.asList(
PropertyDefinition.builder(CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY)
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/PartialScanFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/PartialScanFilter.java
deleted file mode 100644
index 903a5ca36e4..00000000000
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/PartialScanFilter.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.plugins.core.batch;
-
-import com.google.common.collect.Maps;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.picocontainer.Startable;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.config.Settings;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.scan.filesystem.FileSystemFilter;
-import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.components.PastSnapshot;
-import org.sonar.batch.components.PastSnapshotFinder;
-import org.sonar.core.source.SnapshotDataType;
-import org.sonar.core.source.jdbc.SnapshotDataDao;
-import org.sonar.core.source.jdbc.SnapshotDataDto;
-import org.sonar.plugins.core.utils.HashBuilder;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * When enabled this filter will only allow modified files to be analyzed.
- * @since 4.0
- */
-public class PartialScanFilter implements FileSystemFilter, Startable {
-
- private PathResolver pathResolver;
- private HashBuilder hashBuilder;
- private Settings settings;
- private SnapshotDataDao snapshotDataDao;
- private PastSnapshotFinder pastSnapshotFinder;
- private Snapshot snapshot;
- private ProjectDefinition module;
-
- private Map<String, String> fileHashMap = Maps.newHashMap();
-
- public PartialScanFilter(Settings settings, ProjectDefinition module, PathResolver pathResolver, HashBuilder hashBuilder,
- Snapshot snapshot,
- SnapshotDataDao snapshotDataDao,
- PastSnapshotFinder pastSnapshotFinder) {
- this.settings = settings;
- this.module = module;
- this.pathResolver = pathResolver;
- this.hashBuilder = hashBuilder;
- this.snapshot = snapshot;
- this.snapshotDataDao = snapshotDataDao;
- this.pastSnapshotFinder = pastSnapshotFinder;
- }
-
- @Override
- public void start() {
- // Extract previous checksum of all files of this module and store
- // them in a map
- if (settings.getBoolean(CoreProperties.PARTIAL_ANALYSIS)) {
- if (!settings.getBoolean(CoreProperties.DRY_RUN)) {
- throw new SonarException("Partial analysis is only supported with dry run mode");
- }
- PastSnapshot pastSnapshot = pastSnapshotFinder.findPreviousAnalysis(snapshot);
- if (pastSnapshot.isRelatedToSnapshot()) {
- Collection<SnapshotDataDto> selectSnapshotData = snapshotDataDao.selectSnapshotData(pastSnapshot.getProjectSnapshot().getId().longValue(),
- Arrays.asList(SnapshotDataType.FILE_HASH.getValue()));
- if (!selectSnapshotData.isEmpty()) {
- SnapshotDataDto snapshotDataDto = selectSnapshotData.iterator().next();
- String data = snapshotDataDto.getData();
- try {
- List<String> lines = IOUtils.readLines(new StringReader(data));
- for (String line : lines) {
- String[] keyValue = StringUtils.split(line, "=");
- if (keyValue.length == 2) {
- fileHashMap.put(keyValue[0], keyValue[1]);
- }
- }
- } catch (IOException e) {
- throw new SonarException("Unable to read previous file hashes", e);
- }
- }
- }
- }
- }
-
- @Override
- public void stop() {
- }
-
- @Override
- public boolean accept(File file, Context context) {
- if (!settings.getBoolean(CoreProperties.PARTIAL_ANALYSIS)) {
- return true;
- }
- String relativePath = pathResolver.relativePath(module.getBaseDir(), file);
- String previousHash = fileHashMap.get(relativePath);
- if (previousHash == null) {
- return true;
- }
- String currentHash = hashBuilder.computeHash(file);
- return !currentHash.equals(previousHash);
- }
-
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java
index 8e3f8d0600e..93c943a3490 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java
@@ -27,30 +27,30 @@ import org.sonar.api.scan.filesystem.FileType;
import org.sonar.api.scan.filesystem.ModuleFileSystem;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.batch.scan.filesystem.FileHashCache;
import org.sonar.core.source.SnapshotDataType;
-import org.sonar.plugins.core.utils.HashBuilder;
import java.io.File;
import java.util.List;
/**
- * This sensor will compute md5 checksum of each file of the current module and store it in DB
+ * This sensor will retrieve hash of each file of the current module and store it in DB
* in order to compare it during next analysis and see if the file was modified.
- * This is used by the partial analysis mode.
- * @see org.sonar.plugins.core.batch.PartialScanFilter
+ * This is used by the incremental preview mode.
+ * @see org.sonar.plugins.core.batch.IncrementalPreviewFilter
* @since 4.0
*/
public final class FileHashSensor implements Sensor {
private ModuleFileSystem moduleFileSystem;
private PathResolver pathResolver;
- private HashBuilder hashBuilder;
private ComponentDataCache componentDataCache;
+ private FileHashCache fileHashCache;
- public FileHashSensor(ModuleFileSystem moduleFileSystem, PathResolver pathResolver, HashBuilder hashBuilder, ComponentDataCache componentDataCache) {
+ public FileHashSensor(FileHashCache fileHashCache, ModuleFileSystem moduleFileSystem, PathResolver pathResolver, ComponentDataCache componentDataCache) {
+ this.fileHashCache = fileHashCache;
this.moduleFileSystem = moduleFileSystem;
this.pathResolver = pathResolver;
- this.hashBuilder = hashBuilder;
this.componentDataCache = componentDataCache;
}
@@ -69,8 +69,8 @@ public final class FileHashSensor implements Sensor {
private void analyse(StringBuilder fileHashMap, Project project, FileType fileType) {
List<File> files = moduleFileSystem.files(FileQuery.on(fileType).onLanguage(project.getLanguageKey()));
for (File file : files) {
- String md5 = hashBuilder.computeHash(file);
- fileHashMap.append(pathResolver.relativePath(moduleFileSystem.baseDir(), file)).append("=").append(md5).append("\n");
+ String hash = fileHashCache.getCurrentHash(file);
+ fileHashMap.append(pathResolver.relativePath(moduleFileSystem.baseDir(), file)).append("=").append(hash).append("\n");
}
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/HashBuilder.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/HashBuilder.java
deleted file mode 100644
index 87b78a11c77..00000000000
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/HashBuilder.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.plugins.core.utils;
-
-import org.apache.commons.io.IOUtils;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.utils.SonarException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * @since 4.0
- */
-public final class HashBuilder implements BatchExtension {
-
- public String computeHash(File file) {
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(file);
- return org.apache.commons.codec.digest.DigestUtils.md5Hex(fis);
- } catch (IOException e) {
- throw new SonarException("Unable to compute file hash", e);
- } finally {
- IOUtils.closeQuietly(fis);
- }
- }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/package-info.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/package-info.java
deleted file mode 100644
index 6d0f75f915b..00000000000
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.core.utils;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/PartialScanFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/PartialScanFilterTest.java
deleted file mode 100644
index 7cd784988d9..00000000000
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/PartialScanFilterTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.plugins.core.batch;
-
-import org.apache.commons.io.FileUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.config.Settings;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.scan.filesystem.FileSystemFilter;
-import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.components.PastSnapshot;
-import org.sonar.batch.components.PastSnapshotFinder;
-import org.sonar.core.source.SnapshotDataType;
-import org.sonar.core.source.jdbc.SnapshotDataDao;
-import org.sonar.core.source.jdbc.SnapshotDataDto;
-import org.sonar.plugins.core.utils.HashBuilder;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Date;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class PartialScanFilterTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- private PartialScanFilter filter;
-
- private Settings settings;
-
- private PastSnapshotFinder pastSnapshotFinder;
-
- private Snapshot snapshot;
-
- private File baseDir;
-
- private SnapshotDataDao snapshotDataDao;
-
- @Before
- public void prepare() throws Exception {
- settings = new Settings();
- pastSnapshotFinder = mock(PastSnapshotFinder.class);
- snapshot = mock(Snapshot.class);
- baseDir = temp.newFolder();
- snapshotDataDao = mock(SnapshotDataDao.class);
- filter = new PartialScanFilter(settings, ProjectDefinition.create().setBaseDir(baseDir), new PathResolver(), new HashBuilder(), snapshot,
- snapshotDataDao, pastSnapshotFinder);
- }
-
- @Test
- public void should_not_run_by_default() throws Exception {
- filter.start();
- assertThat(filter.accept(temp.newFile(), mock(FileSystemFilter.Context.class))).isTrue();
- }
-
- @Test
- public void should_throw_if_partial_mode_and_not_in_dryrun() throws Exception {
- settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true);
-
- thrown.expect(SonarException.class);
- thrown.expectMessage("Partial analysis is only supported with dry run mode");
- filter.start();
- }
-
- @Test
- public void should_include_if_no_previous_snapshot() throws Exception {
- settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true);
- settings.setProperty(CoreProperties.DRY_RUN, true);
-
- when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(new PastSnapshot("foo"));
-
- filter.start();
- assertThat(filter.accept(new File(baseDir, "src/main/java/foo/Bar.java"), mock(FileSystemFilter.Context.class))).isTrue();
- }
-
- @Test
- public void should_include_if_no_previous_snapshot_data() throws Exception {
- settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true);
- settings.setProperty(CoreProperties.DRY_RUN, true);
-
- Snapshot previousSnapshot = mock(Snapshot.class);
- PastSnapshot pastSnapshot = new PastSnapshot("foo", new Date(), previousSnapshot);
- when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(pastSnapshot);
-
- filter.start();
- assertThat(filter.accept(new File(baseDir, "src/main/java/foo/Bar.java"), mock(FileSystemFilter.Context.class))).isTrue();
- }
-
- @Test
- public void should_include_if_different_hash() throws Exception {
- settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true);
- settings.setProperty(CoreProperties.DRY_RUN, true);
-
- Snapshot previousSnapshot = mock(Snapshot.class);
- when(previousSnapshot.getId()).thenReturn(123);
- PastSnapshot pastSnapshot = new PastSnapshot("foo", new Date(), previousSnapshot);
- when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(pastSnapshot);
-
- SnapshotDataDto snapshotDataDto = new SnapshotDataDto();
- snapshotDataDto.setData("src/main/java/foo/Bar.java=abcd1234\n");
- when(snapshotDataDao.selectSnapshotData(123, Arrays.asList(SnapshotDataType.FILE_HASH.getValue())))
- .thenReturn(Arrays.asList(snapshotDataDto));
-
- filter.start();
- File file = new File(baseDir, "src/main/java/foo/Bar.java");
- FileUtils.write(file, "foo");
- assertThat(filter.accept(file, mock(FileSystemFilter.Context.class))).isTrue();
- }
-
- @Test
- public void should_exclude_if_same_hash() throws Exception {
- settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true);
- settings.setProperty(CoreProperties.DRY_RUN, true);
-
- Snapshot previousSnapshot = mock(Snapshot.class);
- when(previousSnapshot.getId()).thenReturn(123);
- PastSnapshot pastSnapshot = new PastSnapshot("foo", new Date(), previousSnapshot);
- when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(pastSnapshot);
-
- SnapshotDataDto snapshotDataDto = new SnapshotDataDto();
- snapshotDataDto.setData("src/main/java/foo/Bar.java=acbd18db4cc2f85cedef654fccc4a4d8\n");
- when(snapshotDataDao.selectSnapshotData(123, Arrays.asList(SnapshotDataType.FILE_HASH.getValue())))
- .thenReturn(Arrays.asList(snapshotDataDto));
-
- filter.start();
- File file = new File(baseDir, "src/main/java/foo/Bar.java");
- FileUtils.write(file, "foo");
- assertThat(filter.accept(file, mock(FileSystemFilter.Context.class))).isFalse();
- }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java
index 0f3d59db57b..a7bbfa49697 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java
@@ -33,7 +33,7 @@ import org.sonar.api.scan.filesystem.FileQuery;
import org.sonar.api.scan.filesystem.ModuleFileSystem;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.batch.index.ComponentDataCache;
-import org.sonar.plugins.core.utils.HashBuilder;
+import org.sonar.batch.scan.filesystem.FileHashCache;
import java.io.File;
import java.util.Arrays;
@@ -61,11 +61,14 @@ public class FileHashSensorTest {
private Project project;
+ private FileHashCache fileHashCache;
+
@Before
public void prepare() {
fileSystem = mock(ModuleFileSystem.class);
componentDataCache = mock(ComponentDataCache.class);
- sensor = new FileHashSensor(fileSystem, new PathResolver(), new HashBuilder(), componentDataCache);
+ fileHashCache = mock(FileHashCache.class);
+ sensor = new FileHashSensor(fileHashCache, fileSystem, new PathResolver(), componentDataCache);
PropertiesConfiguration conf = new PropertiesConfiguration();
conf.setProperty("sonar.language", "java");
project = new Project("java_project").setConfiguration(conf).setLanguage(Java.INSTANCE);
@@ -82,15 +85,16 @@ public class FileHashSensorTest {
File baseDir = temp.newFolder();
File file1 = new File(baseDir, "src/com/foo/Bar.java");
FileUtils.write(file1, "Bar");
+ when(fileHashCache.getCurrentHash(file1)).thenReturn("barhash");
File file2 = new File(baseDir, "src/com/foo/Foo.java");
FileUtils.write(file2, "Foo");
+ when(fileHashCache.getCurrentHash(file2)).thenReturn("foohash");
when(fileSystem.baseDir()).thenReturn(baseDir);
when(fileSystem.files(any(FileQuery.class))).thenReturn(Arrays.asList(file1, file2)).thenReturn(Collections.<File> emptyList());
sensor.analyse(project, mock(SensorContext.class));
verify(componentDataCache).setStringData("java_project", "hash",
- "src/com/foo/Bar.java=ddc35f88fa71b6ef142ae61f35364653\n"
- + "src/com/foo/Foo.java=1356c67d7ad1638d816bfb822dd2c25d\n");
+ "src/com/foo/Bar.java=barhash\n"
+ + "src/com/foo/Foo.java=foohash\n");
}
-
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/utils/HashBuilderTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/utils/HashBuilderTest.java
deleted file mode 100644
index a0819b57450..00000000000
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/utils/HashBuilderTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.plugins.core.utils;
-
-import org.apache.commons.io.FileUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.utils.SonarException;
-
-import java.io.File;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class HashBuilderTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void should_compute_hash() throws Exception {
- File tempFile = temp.newFile();
- FileUtils.write(tempFile, "foobar");
- assertThat(new HashBuilder().computeHash(tempFile)).isEqualTo("3858f62230ac3c915f300c664312c63f");
- }
-
- @Test(expected = SonarException.class)
- public void should_throw_on_not_existing_file() throws Exception {
- File tempFolder = temp.newFolder();
- new HashBuilder().computeHash(new File(tempFolder, "unknowFile.txt"));
- }
-}