]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3677 Rename dryRun -> preview and introduce sonar.analysis.mode
authorJulien HENRY <julien.henry@sonarsource.com>
Mon, 14 Oct 2013 16:20:07 +0000 (18:20 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Mon, 14 Oct 2013 16:20:49 +0000 (18:20 +0200)
80 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/DryRunDatabase.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/IssuePersister.java
sonar-batch/src/main/java/org/sonar/batch/phases/UpdateStatusJob.java
sonar-batch/src/main/java/org/sonar/batch/scan/LastSnapshots.java
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectLock.java
sonar-batch/src/main/java/org/sonar/batch/scan/UnsupportedProperties.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileQueryFilter.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/ComponentSelectorFactory.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/JsonReport.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchDatabaseTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/DryRunDatabaseTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionUtilsTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/IssuePersisterTest.java
sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/LastSnapshotsTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ProjectLockTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/UnsupportedPropertiesTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/FileQueryFilterTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/report/JsonReportTest.java
sonar-core/src/main/java/org/sonar/core/dryrun/DryRunCache.java [deleted file]
sonar-core/src/main/java/org/sonar/core/dryrun/package-info.java [deleted file]
sonar-core/src/main/java/org/sonar/core/persistence/DefaultDatabase.java
sonar-core/src/main/java/org/sonar/core/persistence/DryRunDatabaseFactory.java [deleted file]
sonar-core/src/main/java/org/sonar/core/persistence/PreviewDatabaseFactory.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/preview/PreviewCache.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/preview/package-info.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/dryrun/DryRunCacheTest.java [deleted file]
sonar-core/src/test/java/org/sonar/core/persistence/DryRunDatabaseFactoryTest.java [deleted file]
sonar-core/src/test/java/org/sonar/core/persistence/PreviewDatabaseFactoryTest.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/preview/PreviewCacheTest.java [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/multi-modules-with-issues.xml [deleted file]
sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_copy_permission_templates.xml [deleted file]
sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_create_database.xml [deleted file]
sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_create_database_with_issues.xml [deleted file]
sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/multi-modules-with-issues.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_copy_permission_templates.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database_with_issues.xml [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
sonar-server/src/main/java/org/sonar/server/configuration/Backup.java
sonar-server/src/main/java/org/sonar/server/configuration/ProfilesBackup.java
sonar-server/src/main/java/org/sonar/server/configuration/ProfilesManager.java
sonar-server/src/main/java/org/sonar/server/configuration/PropertiesBackup.java
sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java
sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
sonar-server/src/main/java/org/sonar/server/platform/Platform.java
sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java
sonar-server/src/main/java/org/sonar/server/startup/CleanDryRunCache.java
sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
sonar-server/src/main/webapp/WEB-INF/app/controllers/alerts_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb
sonar-server/src/test/java/org/sonar/server/configuration/BackupTest.java
sonar-server/src/test/java/org/sonar/server/configuration/InheritedProfilesTest.java
sonar-server/src/test/java/org/sonar/server/configuration/ProfilesManagerTest.java
sonar-server/src/test/java/org/sonar/server/configuration/RuleChangeTest.java
sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java
sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java

index 2f89e01c7d25f82a96a8810030a4176f4c7097ad..cc9bed17fccd0b959dbc6714dcb23eef9c48c204 100644 (file)
 package org.sonar.plugins.core;
 
 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;
@@ -32,21 +36,90 @@ 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.SizeWidget;
+import org.sonar.plugins.core.widgets.TechnicalDebtPyramidWidget;
+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.IssuesWidget;
+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;
@@ -116,23 +189,26 @@ import java.util.List;
     global = true,
     category = CoreProperties.CATEGORY_GENERAL),
   @Property(
-    key = CoreProperties.DRY_RUN,
-    defaultValue = "false",
-    name = "Preview",
-    type = PropertyType.BOOLEAN,
+    key = CoreProperties.ANALYSIS_MODE,
+    defaultValue = CoreProperties.ANALYSIS_MODE_ANALYSIS,
+    name = "Analysis mode",
+    type = PropertyType.SINGLE_SELECT_LIST,
+    options = {CoreProperties.ANALYSIS_MODE_ANALYSIS, CoreProperties.ANALYSIS_MODE_PREVIEW, CoreProperties.ANALYSIS_MODE_INCREMENTAL},
     global = false, project = false,
     category = CoreProperties.CATEGORY_GENERAL),
   @Property(
-    key = CoreProperties.DRY_RUN_INCLUDE_PLUGINS,
+    key = CoreProperties.PREVIEW_INCLUDE_PLUGINS,
+    deprecatedKey = CoreProperties.DRY_RUN_INCLUDE_PLUGINS,
     name = "Plugins accepted for Preview",
-    defaultValue = CoreProperties.DRY_RUN_INCLUDE_PLUGINS_DEFAULT_VALUE,
+    defaultValue = CoreProperties.PREVIEW_INCLUDE_PLUGINS_DEFAULT_VALUE,
     global = true, project = false,
     category = CoreProperties.CATEGORY_GENERAL),
   @Property(
-    key = CoreProperties.DRY_RUN_EXCLUDE_PLUGINS,
+    key = CoreProperties.PREVIEW_EXCLUDE_PLUGINS,
+    deprecatedKey = CoreProperties.DRY_RUN_EXCLUDE_PLUGINS,
     name = "Plugins excluded for Preview",
     global = true, project = false,
-    defaultValue = CoreProperties.DRY_RUN_EXCLUDE_PLUGINS_DEFAULT_VALUE,
+    defaultValue = CoreProperties.PREVIEW_EXCLUDE_PLUGINS_DEFAULT_VALUE,
     category = CoreProperties.CATEGORY_GENERAL),
   @Property(
     key = "sonar.report.export.path",
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java
new file mode 100644 (file)
index 0000000..f0872de
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.bootstrap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.CoreProperties;
+
+import java.text.MessageFormat;
+
+/**
+ * @since 4.0
+ */
+public class AnalysisMode implements BatchComponent {
+
+  private static final Logger LOG = LoggerFactory.getLogger(AnalysisMode.class);
+
+  private boolean preview;
+  private boolean incremental;
+
+  public AnalysisMode(BootstrapSettings bootstrapSettings) {
+    init(bootstrapSettings);
+  }
+
+  public boolean isPreview() {
+    return preview || incremental;
+  }
+
+  public boolean isIncremental() {
+    return incremental;
+  }
+
+  private void init(BootstrapSettings bootstrapSettings) {
+    if (bootstrapSettings.properties().containsKey(CoreProperties.DRY_RUN)) {
+      LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead", CoreProperties.DRY_RUN, CoreProperties.ANALYSIS_MODE));
+      preview = "true".equals(bootstrapSettings.property(CoreProperties.DRY_RUN));
+      incremental = false;
+    } else {
+      String mode = bootstrapSettings.property(CoreProperties.ANALYSIS_MODE);
+      preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode);
+      incremental = CoreProperties.ANALYSIS_MODE_INCREMENTAL.equals(mode);
+    }
+    if (incremental) {
+      LOG.info("Incremental mode");
+    } else if (preview) {
+      LOG.info("Preview mode");
+    }
+    // To stay compatible with plugins that use the old property to check mode
+    if (incremental || preview) {
+      bootstrapSettings.properties().put(CoreProperties.DRY_RUN, "true");
+    }
+  }
+}
index 8f58a39a4d9a97e99c9a4254f0d3221a4262204f..0282d43e178ae2c0940aa3bc5f487332e638b4da 100644 (file)
@@ -29,22 +29,28 @@ import java.util.Properties;
  */
 public class BatchDatabase extends DefaultDatabase {
 
+  private final AnalysisMode analysisMode;
+
   public BatchDatabase(Settings settings,
-      // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver
-      // has been downloaded and injected into classloader
-      JdbcDriverHolder jdbcDriverHolder,
+    AnalysisMode analysisMode,
+    // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver
+    // has been downloaded and injected into classloader
+    JdbcDriverHolder jdbcDriverHolder,
 
-      // The dependency on DryRunDatabase is required to be sure that the dryRun mode
-      // changed settings
-      DryRunDatabase dryRun) {
+    // The dependency on DryRunDatabase is required to be sure that the dryRun mode
+    // changed settings
+    PreviewDatabase dryRun) {
     super(settings);
+    this.analysisMode = analysisMode;
   }
 
   public BatchDatabase(Settings settings,
-      // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver
-      // has been downloaded and injected into classloader
-      JdbcDriverHolder jdbcDriverHolder) {
+    AnalysisMode analysisMode,
+    // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver
+    // has been downloaded and injected into classloader
+    JdbcDriverHolder jdbcDriverHolder) {
     super(settings);
+    this.analysisMode = analysisMode;
   }
 
   @Override
@@ -57,4 +63,11 @@ public class BatchDatabase extends DefaultDatabase {
     // SONAR-2965
     properties.setProperty("sonar.jdbc.defaultAutoCommit", "false");
   }
+
+  @Override
+  protected void checkH2Database() {
+    if (!analysisMode.isPreview()) {
+      super.checkH2Database();
+    }
+  }
 }
index 755d2a46b97545d2ff74e17e3a0bc7c36492f5e2..49603d683d7b5c6b91d792e455dbd92d16ddda93 100644 (file)
@@ -35,6 +35,7 @@ import org.sonar.core.plugins.PluginInstaller;
 import org.sonar.core.plugins.RemotePlugin;
 
 import java.io.File;
+import java.text.MessageFormat;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -53,11 +54,13 @@ public class BatchPluginRepository implements PluginRepository {
   private Settings settings;
   private PluginClassloaders classLoaders;
   private TempDirectories workingDirectories;
+  private final AnalysisMode analysisMode;
 
-  public BatchPluginRepository(PluginDownloader pluginDownloader, TempDirectories workingDirectories, Settings settings) {
+  public BatchPluginRepository(PluginDownloader pluginDownloader, TempDirectories workingDirectories, Settings settings, AnalysisMode analysisMode) {
     this.pluginDownloader = pluginDownloader;
     this.workingDirectories = workingDirectories;
     this.settings = settings;
+    this.analysisMode = analysisMode;
   }
 
   public void start() {
@@ -66,7 +69,7 @@ public class BatchPluginRepository implements PluginRepository {
   }
 
   void doStart(List<RemotePlugin> remotePlugins) {
-    PluginFilter filter = new PluginFilter(settings);
+    PluginFilter filter = new PluginFilter(settings, analysisMode);
     PluginInstaller extractor = new PluginInstaller();
     metadataByKey = Maps.newHashMap();
     for (RemotePlugin remote : remotePlugins) {
@@ -119,20 +122,32 @@ public class BatchPluginRepository implements PluginRepository {
   static class PluginFilter {
     Set<String> whites = Sets.newHashSet(), blacks = Sets.newHashSet();
 
-    PluginFilter(Settings settings) {
+    PluginFilter(Settings settings, AnalysisMode mode) {
       if (settings.hasKey(CoreProperties.BATCH_INCLUDE_PLUGINS)) {
         whites.addAll(Arrays.asList(settings.getStringArray(CoreProperties.BATCH_INCLUDE_PLUGINS)));
       }
       if (settings.hasKey(CoreProperties.BATCH_EXCLUDE_PLUGINS)) {
         blacks.addAll(Arrays.asList(settings.getStringArray(CoreProperties.BATCH_EXCLUDE_PLUGINS)));
       }
-      if (settings.getBoolean(CoreProperties.DRY_RUN)) {
+      if (mode.isPreview()) {
         // These default values are not supported by Settings because the class CorePlugin
         // is not loaded yet.
-        whites.addAll(propertyValues(settings,
-            CoreProperties.DRY_RUN_INCLUDE_PLUGINS, CoreProperties.DRY_RUN_INCLUDE_PLUGINS_DEFAULT_VALUE));
-        blacks.addAll(propertyValues(settings,
-            CoreProperties.DRY_RUN_EXCLUDE_PLUGINS, CoreProperties.DRY_RUN_EXCLUDE_PLUGINS_DEFAULT_VALUE));
+        if (settings.hasKey(CoreProperties.DRY_RUN_INCLUDE_PLUGINS)) {
+          LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead", CoreProperties.DRY_RUN_INCLUDE_PLUGINS, CoreProperties.PREVIEW_INCLUDE_PLUGINS));
+          whites.addAll(propertyValues(settings,
+            CoreProperties.DRY_RUN_INCLUDE_PLUGINS, CoreProperties.PREVIEW_INCLUDE_PLUGINS_DEFAULT_VALUE));
+        } else {
+          whites.addAll(propertyValues(settings,
+            CoreProperties.PREVIEW_INCLUDE_PLUGINS, CoreProperties.PREVIEW_INCLUDE_PLUGINS_DEFAULT_VALUE));
+        }
+        if (settings.hasKey(CoreProperties.DRY_RUN_EXCLUDE_PLUGINS)) {
+          LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead", CoreProperties.DRY_RUN_EXCLUDE_PLUGINS, CoreProperties.PREVIEW_EXCLUDE_PLUGINS));
+          blacks.addAll(propertyValues(settings,
+            CoreProperties.DRY_RUN_EXCLUDE_PLUGINS, CoreProperties.PREVIEW_EXCLUDE_PLUGINS_DEFAULT_VALUE));
+        } else {
+          blacks.addAll(propertyValues(settings,
+            CoreProperties.PREVIEW_EXCLUDE_PLUGINS, CoreProperties.PREVIEW_EXCLUDE_PLUGINS_DEFAULT_VALUE));
+        }
       }
       if (!whites.isEmpty()) {
         LOG.info("Include plugins: " + Joiner.on(", ").join(whites));
index 163f9dc232c1efc488ee67179aa0421c879c7a78..e06c8c9c4336f0e428c3597bdaca232164d69f82 100644 (file)
@@ -37,15 +37,17 @@ import java.util.Map;
 public class BatchSettings extends Settings {
   public static final String BATCH_BOOTSTRAP_PROPERTIES_URL = "/batch_bootstrap/properties";
   private Configuration deprecatedConfiguration;
-  private boolean dryRun;
+  private boolean preview;
 
   private final BootstrapSettings bootstrapSettings;
   private final ServerClient client;
+  private final AnalysisMode mode;
   private Map<String, String> savedProperties;
 
   public BatchSettings(BootstrapSettings bootstrapSettings, PropertyDefinitions propertyDefinitions,
-    ServerClient client, Configuration deprecatedConfiguration) {
+    ServerClient client, Configuration deprecatedConfiguration, AnalysisMode mode) {
     super(propertyDefinitions);
+    this.mode = mode;
     getEncryption().setPathToSecretKey(bootstrapSettings.property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
     this.bootstrapSettings = bootstrapSettings;
     this.client = client;
@@ -56,8 +58,7 @@ public class BatchSettings extends Settings {
   public void init(@Nullable ProjectReactor reactor) {
     savedProperties = this.getProperties();
 
-    // Do not use getBoolean to avoid recursion
-    this.dryRun = "true".equals(bootstrapSettings.property(CoreProperties.DRY_RUN));
+    this.preview = mode.isPreview();
     if (reactor != null) {
       LoggerFactory.getLogger(BatchSettings.class).info("Load project settings");
       String branch = bootstrapSettings.property(CoreProperties.PROJECT_BRANCH_PROPERTY);
@@ -89,9 +90,9 @@ public class BatchSettings extends Settings {
   private void downloadSettings(@Nullable String projectKey) {
     String url;
     if (StringUtils.isNotBlank(projectKey)) {
-      url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?project=" + projectKey + "&dryRun=" + dryRun;
+      url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?project=" + projectKey + "&dryRun=" + preview;
     } else {
-      url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?dryRun=" + dryRun;
+      url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?dryRun=" + preview;
     }
     String jsonText = client.request(url);
     List<Map<String, String>> json = (List<Map<String, String>>) JSONValue.parse(jsonText);
@@ -119,9 +120,9 @@ public class BatchSettings extends Settings {
 
   @Override
   protected void doOnGetProperties(String key) {
-    if (dryRun && key.endsWith(".secured") && !key.contains(".license")) {
+    if (preview && key.endsWith(".secured") && !key.contains(".license")) {
       throw new SonarException("Access to the secured property '" + key
-        + "' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin which requires this property must be deactivated in dry run mode.");
+        + "' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode.");
     }
   }
 }
index 2913aad74d810154b978182710fff56562cd1db1..6aa2b6b31b52f4a333c4879135b28f9a9f947d85 100644 (file)
@@ -19,8 +19,6 @@
  */
 package org.sonar.batch.bootstrap;
 
-import org.sonar.core.purge.PurgeProfiler;
-
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.sonar.api.Plugin;
 import org.sonar.api.config.EmailSettings;
@@ -44,6 +42,7 @@ import org.sonar.core.persistence.DatabaseVersion;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.persistence.SemaphoreUpdater;
 import org.sonar.core.persistence.SemaphoresImpl;
+import org.sonar.core.purge.PurgeProfiler;
 import org.sonar.core.qualitymodel.DefaultModelFinder;
 import org.sonar.core.rule.CacheRuleFinder;
 import org.sonar.core.user.HibernateUserFinder;
@@ -79,6 +78,7 @@ public class BootstrapContainer extends ComponentContainer {
     add(
       new PropertiesConfiguration(),
       BootstrapSettings.class,
+      AnalysisMode.class,
       PluginDownloader.class,
       BatchPluginRepository.class,
       BatchSettings.class,
@@ -90,25 +90,23 @@ public class BootstrapContainer extends ComponentContainer {
       TempDirectories.class,
       HttpDownloader.class,
       UriReader.class,
-      new FileCacheProvider()
-    );
+      new FileCacheProvider());
   }
 
   private void addDatabaseComponents() {
     add(
-      DryRunDatabase.class,
+      PreviewDatabase.class,
       JdbcDriverHolder.class,
       BatchDatabase.class,
       MyBatis.class,
       DatabaseVersion.class,
-      //TODO check that it still works (see @Freddy)
+      // TODO check that it still works (see @Freddy)
       DatabaseCompatibility.class,
       DefaultDatabaseConnector.class,
       JpaDatabaseSession.class,
       BatchDatabaseSessionFactory.class,
       DaoUtils.getDaoClasses(),
-      PurgeProfiler.class
-    );
+      PurgeProfiler.class);
   }
 
   /**
@@ -134,8 +132,7 @@ public class BootstrapContainer extends ComponentContainer {
       PastSnapshotFinderByPreviousVersion.class,
       PastMeasuresLoader.class,
       PastSnapshotFinder.class,
-      DefaultModelFinder.class
-    );
+      DefaultModelFinder.class);
   }
 
   @Override
index 6fe7394e040f5377b0c69d774b9c48170a1da339..965ce42ae7f82e70a340e4e22b30c77ae1354061 100644 (file)
@@ -34,15 +34,17 @@ public class DatabaseCompatibility implements BatchComponent {
   private DatabaseVersion version;
   private Settings settings;
   private ServerMetadata server;
+  private AnalysisMode analysisMode;
 
-  public DatabaseCompatibility(DatabaseVersion version, ServerMetadata server, Settings settings) {
+  public DatabaseCompatibility(DatabaseVersion version, ServerMetadata server, Settings settings, AnalysisMode mode) {
     this.version = version;
     this.server = server;
     this.settings = settings;
+    this.analysisMode = mode;
   }
 
   public void start() {
-    if (!settings.getBoolean(CoreProperties.DRY_RUN)) {
+    if (!analysisMode.isPreview()) {
       checkCorrectServerId();
       checkDatabaseStatus();
     }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DryRunDatabase.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DryRunDatabase.java
deleted file mode 100644 (file)
index f484787..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.bootstrap;
-
-import com.google.common.base.Throwables;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.database.DatabaseProperties;
-import org.sonar.api.utils.HttpDownloader.HttpException;
-import org.sonar.api.utils.SonarException;
-
-import java.io.File;
-import java.net.SocketTimeoutException;
-
-/**
- * @since 3.4
- */
-public class DryRunDatabase implements BatchComponent {
-  private static final Logger LOG = LoggerFactory.getLogger(DryRunDatabase.class);
-
-  private static final String DIALECT = "h2";
-  private static final String DRIVER = "org.h2.Driver";
-  private static final String URL = "jdbc:h2:";
-  private static final String USER = "sonar";
-  private static final String PASSWORD = USER;
-
-  private static final int DEFAULT_DRY_RUN_READ_TIMEOUT_SEC = 60;
-
-  private final Settings settings;
-  private final ServerClient server;
-  private final TempDirectories tempDirectories;
-
-  public DryRunDatabase(Settings settings, ServerClient server, TempDirectories tempDirectories) {
-    this.settings = settings;
-    this.server = server;
-    this.tempDirectories = tempDirectories;
-  }
-
-  public void start() {
-    if (settings.getBoolean(CoreProperties.DRY_RUN)) {
-      LOG.info("Preview");
-      File databaseFile = tempDirectories.getFile("", "dryrun.h2.db");
-
-      // SONAR-4488 Allow to increase dryRun timeout
-      int readTimeoutSec = settings.getInt(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC);
-      readTimeoutSec = (readTimeoutSec == 0) ? DEFAULT_DRY_RUN_READ_TIMEOUT_SEC : readTimeoutSec;
-
-      downloadDatabase(databaseFile, readTimeoutSec * 1000);
-
-      String databasePath = StringUtils.removeEnd(databaseFile.getAbsolutePath(), ".h2.db");
-      replaceSettings(databasePath);
-    }
-  }
-
-  private void downloadDatabase(File toFile, int readTimeout) {
-    String projectKey = null;
-    try {
-      projectKey = settings.getString(CoreProperties.PROJECT_KEY_PROPERTY);
-      String branch = settings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY);
-      if (StringUtils.isNotBlank(branch)) {
-        projectKey = String.format("%s:%s", projectKey, branch);
-      }
-      if (StringUtils.isBlank(projectKey)) {
-        server.download("/batch_bootstrap/db", toFile, readTimeout);
-      } else {
-        server.download("/batch_bootstrap/db?project=" + projectKey, toFile, readTimeout);
-      }
-      LOG.debug("Dry Run database size: {}", FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(toFile)));
-    } catch (SonarException e) {
-      handleException(readTimeout, projectKey, e);
-      throw e;
-    }
-  }
-
-  private void handleException(int readTimeout, String projectKey, SonarException e) {
-    Throwable rootCause = Throwables.getRootCause(e);
-    if (rootCause instanceof SocketTimeoutException) {
-      // Pico will unwrap the first runtime exception
-      throw new SonarException(new SonarException(String.format("DryRun database read timed out after %s ms. You can try to increase read timeout with property -D"
-        + CoreProperties.DRY_RUN_READ_TIMEOUT_SEC + " (in seconds)",
-          readTimeout), e));
-    }
-    if (projectKey != null && (rootCause instanceof HttpException) && (((HttpException) rootCause).getResponseCode() == 401)) {
-      // Pico will unwrap the first runtime exception
-      throw new SonarException(new SonarException(String.format("You don't have access rights to project [%s]", projectKey), e));
-    }
-  }
-
-  private void replaceSettings(String databasePath) {
-    settings
-        .removeProperty("sonar.jdbc.schema")
-        .setProperty(DatabaseProperties.PROP_DIALECT, DIALECT)
-        .setProperty(DatabaseProperties.PROP_DRIVER, DRIVER)
-        .setProperty(DatabaseProperties.PROP_USER, USER)
-        .setProperty(DatabaseProperties.PROP_PASSWORD, PASSWORD)
-        .setProperty(DatabaseProperties.PROP_URL, URL + databasePath);
-  }
-}
index 8c396056f76e51ce50c5a2446a911abc4b345bdd..d51421d084c022c8d9a495a9b787babbb796514c 100644 (file)
  */
 package org.sonar.batch.bootstrap;
 
-import org.sonar.api.CoreProperties;
 import org.sonar.api.ExtensionProvider;
 import org.sonar.api.Plugin;
-import org.sonar.api.config.Settings;
 import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.platform.PluginMetadata;
 import org.sonar.batch.bootstrapper.EnvironmentInformation;
@@ -36,21 +34,21 @@ public class ExtensionInstaller {
 
   private final BatchPluginRepository pluginRepository;
   private final EnvironmentInformation env;
-  private final Settings settings;
+  private final AnalysisMode analysisMode;
 
-  public ExtensionInstaller(BatchPluginRepository pluginRepository, EnvironmentInformation env, Settings settings) {
+  public ExtensionInstaller(BatchPluginRepository pluginRepository, EnvironmentInformation env, AnalysisMode analysisMode) {
     this.pluginRepository = pluginRepository;
     this.env = env;
-    this.settings = settings;
+    this.analysisMode = analysisMode;
   }
 
   public ExtensionInstaller install(ComponentContainer container, ExtensionMatcher matcher) {
-    boolean dryRun = isDryRun();
+    boolean preview = analysisMode.isPreview();
     for (Map.Entry<PluginMetadata, Plugin> entry : pluginRepository.getPluginsByMetadata().entrySet()) {
       PluginMetadata metadata = entry.getKey();
       Plugin plugin = entry.getValue();
       for (Object extension : plugin.getExtensions()) {
-        doInstall(container, matcher, metadata, dryRun, extension);
+        doInstall(container, matcher, metadata, preview, extension);
       }
     }
     List<ExtensionProvider> providers = container.getComponentsByType(ExtensionProvider.class);
@@ -58,10 +56,10 @@ public class ExtensionInstaller {
       Object object = provider.provide();
       if (object instanceof Iterable) {
         for (Object extension : (Iterable) object) {
-          doInstall(container, matcher, null, dryRun, extension);
+          doInstall(container, matcher, null, preview, extension);
         }
       } else {
-        doInstall(container, matcher, null, dryRun, object);
+        doInstall(container, matcher, null, preview, object);
       }
     }
     return this;
@@ -69,7 +67,7 @@ public class ExtensionInstaller {
 
   private void doInstall(ComponentContainer container, ExtensionMatcher matcher, @Nullable PluginMetadata metadata, boolean dryRun, Object extension) {
     if (ExtensionUtils.supportsEnvironment(extension, env)
-      && (!dryRun || ExtensionUtils.supportsDryRun(extension))
+      && (!dryRun || ExtensionUtils.supportsPreview(extension))
       && matcher.accept(extension)) {
       container.addExtension(metadata, extension);
     } else {
@@ -77,7 +75,4 @@ public class ExtensionInstaller {
     }
   }
 
-  private boolean isDryRun() {
-    return settings.getBoolean(CoreProperties.DRY_RUN);
-  }
 }
index 1111e7fbfd279b4225ba1537b2b655241fb9d357..89cdaa59845aa7a27a353837d9eb5756a26753ce 100644 (file)
@@ -58,7 +58,7 @@ public class ExtensionUtils {
     return false;
   }
 
-  public static boolean supportsDryRun(Object extension) {
+  public static boolean supportsPreview(Object extension) {
     return AnnotationUtils.getAnnotation(extension, DryRunIncompatible.class) == null;
   }
 
index 0ebd74fee9f778dfd9ce9b51735ef4756de379bb..85777901b5ca79e5782c5475b546fc134313d20e 100644 (file)
@@ -22,8 +22,6 @@ package org.sonar.batch.bootstrap;
 import com.google.common.annotations.VisibleForTesting;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
 import org.sonar.api.utils.SonarException;
 import org.sonar.home.cache.FileCache;
 
@@ -43,20 +41,20 @@ public class JdbcDriverHolder {
   private static final Logger LOG = LoggerFactory.getLogger(JdbcDriverHolder.class);
 
   private ServerClient serverClient;
-  private Settings settings;
+  private AnalysisMode analysisMode;
   private FileCache fileCache;
 
   // initialized in start()
   private JdbcDriverClassLoader classLoader = null;
 
-  public JdbcDriverHolder(FileCache fileCache, Settings settings, ServerClient serverClient) {
+  public JdbcDriverHolder(FileCache fileCache, AnalysisMode analysisMode, ServerClient serverClient) {
     this.serverClient = serverClient;
-    this.settings = settings;
+    this.analysisMode = analysisMode;
     this.fileCache = fileCache;
   }
 
   public void start() {
-    if (!settings.getBoolean(CoreProperties.DRY_RUN)) {
+    if (!analysisMode.isPreview()) {
       try {
         LOG.info("Install JDBC driver");
         String[] nameAndHash = downloadJdbcDriverIndex();
@@ -150,7 +148,7 @@ public class JdbcDriverHolder {
   static class JdbcDriverClassLoader extends URLClassLoader {
 
     public JdbcDriverClassLoader(URL jdbcDriver, ClassLoader parent) {
-      super(new URL[]{jdbcDriver}, parent);
+      super(new URL[] {jdbcDriver}, parent);
     }
 
     public void clearReferencesJdbc() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java
new file mode 100644 (file)
index 0000000..222a40f
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.bootstrap;
+
+import com.google.common.base.Throwables;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
+import org.sonar.api.database.DatabaseProperties;
+import org.sonar.api.utils.HttpDownloader.HttpException;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.net.SocketTimeoutException;
+
+/**
+ * @since 3.4
+ */
+public class PreviewDatabase implements BatchComponent {
+  private static final Logger LOG = LoggerFactory.getLogger(PreviewDatabase.class);
+
+  private static final String DIALECT = "h2";
+  private static final String DRIVER = "org.h2.Driver";
+  private static final String URL = "jdbc:h2:";
+  private static final String USER = "sonar";
+  private static final String PASSWORD = USER;
+
+  private static final int DEFAULT_PREVIEW_READ_TIMEOUT_SEC = 60;
+
+  private final Settings settings;
+  private final ServerClient server;
+  private final TempDirectories tempDirectories;
+  private final AnalysisMode mode;
+
+  public PreviewDatabase(Settings settings, ServerClient server, TempDirectories tempDirectories, AnalysisMode mode) {
+    this.settings = settings;
+    this.server = server;
+    this.tempDirectories = tempDirectories;
+    this.mode = mode;
+  }
+
+  public void start() {
+    if (mode.isPreview()) {
+      File databaseFile = tempDirectories.getFile("", "preview.h2.db");
+
+      int readTimeoutSec = getReadTimeout();
+      downloadDatabase(databaseFile, readTimeoutSec * 1000);
+
+      String databasePath = StringUtils.removeEnd(databaseFile.getAbsolutePath(), ".h2.db");
+      replaceSettings(databasePath);
+    }
+  }
+
+  // SONAR-4488 Allow to increase dryRun timeout
+  private int getReadTimeout() {
+    int readTimeoutSec;
+    if (settings.hasKey(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC)) {
+      LOG.warn(String.format("Property {0} is deprecated. Please use {1} instead.", CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, CoreProperties.PREVIEW_READ_TIMEOUT_SEC));
+      readTimeoutSec = settings.getInt(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC);
+    } else if (settings.hasKey(CoreProperties.PREVIEW_READ_TIMEOUT_SEC)) {
+      readTimeoutSec = settings.getInt(CoreProperties.PREVIEW_READ_TIMEOUT_SEC);
+    } else {
+      readTimeoutSec = DEFAULT_PREVIEW_READ_TIMEOUT_SEC;
+    }
+    return readTimeoutSec;
+  }
+
+  private void downloadDatabase(File toFile, int readTimeout) {
+    String projectKey = null;
+    try {
+      projectKey = settings.getString(CoreProperties.PROJECT_KEY_PROPERTY);
+      String branch = settings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY);
+      if (StringUtils.isNotBlank(branch)) {
+        projectKey = String.format("%s:%s", projectKey, branch);
+      }
+      if (StringUtils.isBlank(projectKey)) {
+        server.download("/batch_bootstrap/db", toFile, readTimeout);
+      } else {
+        server.download("/batch_bootstrap/db?project=" + projectKey, toFile, readTimeout);
+      }
+      LOG.debug("Dry Run database size: {}", FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(toFile)));
+    } catch (SonarException e) {
+      handleException(readTimeout, projectKey, e);
+      throw e;
+    }
+  }
+
+  private void handleException(int readTimeout, String projectKey, SonarException e) {
+    Throwable rootCause = Throwables.getRootCause(e);
+    if (rootCause instanceof SocketTimeoutException) {
+      // Pico will unwrap the first runtime exception
+      throw new SonarException(new SonarException(String.format("Preview database read timed out after %s ms. You can try to increase read timeout with property -D"
+        + CoreProperties.PREVIEW_READ_TIMEOUT_SEC + " (in seconds)",
+        readTimeout), e));
+    }
+    if (projectKey != null && (rootCause instanceof HttpException) && (((HttpException) rootCause).getResponseCode() == 401)) {
+      // Pico will unwrap the first runtime exception
+      throw new SonarException(new SonarException(String.format("You don't have access rights to project [%s]", projectKey), e));
+    }
+  }
+
+  private void replaceSettings(String databasePath) {
+    settings
+      .removeProperty("sonar.jdbc.schema")
+      .setProperty(DatabaseProperties.PROP_DIALECT, DIALECT)
+      .setProperty(DatabaseProperties.PROP_DRIVER, DRIVER)
+      .setProperty(DatabaseProperties.PROP_USER, USER)
+      .setProperty(DatabaseProperties.PROP_PASSWORD, PASSWORD)
+      .setProperty(DatabaseProperties.PROP_URL, URL + databasePath);
+  }
+}
index 6668001f9b724ddc1d846558dade92b435f40b8e..183bbae1e0ce517b7240c854fa85c18c88154442 100644 (file)
@@ -21,9 +21,8 @@ package org.sonar.batch.issue;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
 import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.index.ScanPersister;
 
 /**
@@ -35,18 +34,18 @@ public class IssuePersister implements ScanPersister {
 
   private final IssueCache issueCache;
   private final ScanIssueStorage storage;
-  private Settings settings;
+  private AnalysisMode analysisMode;
 
-  public IssuePersister(IssueCache issueCache, ScanIssueStorage storage, Settings settings) {
+  public IssuePersister(IssueCache issueCache, ScanIssueStorage storage, AnalysisMode analysisMode) {
     this.issueCache = issueCache;
     this.storage = storage;
-    this.settings = settings;
+    this.analysisMode = analysisMode;
   }
 
   @Override
   public void persist() {
-    if (settings.getBoolean(CoreProperties.DRY_RUN)) {
-      LOG.debug("IssuePersister skipped in dryRun");
+    if (analysisMode.isPreview()) {
+      LOG.debug("IssuePersister skipped in preview mode");
       return;
     }
     Iterable<DefaultIssue> issues = issueCache.all();
index dc338ddd36001e56890dadc3883b320b6bcc5ff1..bbc7830289324f4ca76e660162044030af7bbc12 100644 (file)
@@ -30,6 +30,7 @@ import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.bootstrap.ServerClient;
 import org.sonar.batch.index.ResourcePersister;
 
@@ -48,35 +49,37 @@ public class UpdateStatusJob implements BatchComponent {
   private ResourcePersister resourcePersister;
   private Settings settings;
   private Project project;
+  private AnalysisMode analysisMode;
 
   public UpdateStatusJob(Settings settings, ServerClient server, DatabaseSession session,
-    ResourcePersister resourcePersister, Project project, Snapshot snapshot) {
+    ResourcePersister resourcePersister, Project project, Snapshot snapshot, AnalysisMode analysisMode) {
     this.session = session;
     this.server = server;
     this.resourcePersister = resourcePersister;
     this.project = project;
     this.snapshot = snapshot;
     this.settings = settings;
+    this.analysisMode = analysisMode;
   }
 
   public void execute() {
     disablePreviousSnapshot();
     enableCurrentSnapshot();
-    evictDryRunDB();
+    evictPreviewDB();
   }
 
   @VisibleForTesting
-  void evictDryRunDB() {
-    if (settings.getBoolean(CoreProperties.DRY_RUN)) {
-      // If this is a dryRun analysis then we should not evict dryRun database
+  void evictPreviewDB() {
+    if (analysisMode.isPreview()) {
+      // If this is a preview analysis then we should not evict remote preview database
       return;
     }
     String url = "/batch_bootstrap/evict?project=" + project.getId();
     try {
-      LOG.debug("Evict dryRun database");
+      LOG.debug("Evict preview database");
       server.request(url);
     } catch (Exception e) {
-      throw new SonarException("Unable to evict dryRun database: " + url, e);
+      throw new SonarException("Unable to evict preview database: " + url, e);
     }
   }
 
@@ -103,7 +106,7 @@ public class UpdateStatusJob implements BatchComponent {
 
   @VisibleForTesting
   void logSuccess(Logger logger) {
-    if (settings.getBoolean(CoreProperties.DRY_RUN)) {
+    if (analysisMode.isPreview()) {
       logger.info("ANALYSIS SUCCESSFUL");
 
     } else {
index eeb39aa6cdb023d22be82dc2fd80d21eeff1d60c..226a3d6751a11db4719f41af272506d56e56e272 100644 (file)
@@ -20,8 +20,6 @@
 package org.sonar.batch.scan;
 
 import org.sonar.api.BatchComponent;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
 import org.sonar.api.database.DatabaseSession;
 import org.sonar.api.database.model.ResourceModel;
 import org.sonar.api.database.model.Snapshot;
@@ -29,18 +27,19 @@ import org.sonar.api.database.model.SnapshotSource;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.ResourceUtils;
 import org.sonar.api.utils.HttpDownloader;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.bootstrap.ServerClient;
 
 import javax.persistence.Query;
 
 public class LastSnapshots implements BatchComponent {
 
-  private final Settings settings;
+  private final AnalysisMode analysisMode;
   private final DatabaseSession session;
   private final ServerClient server;
 
-  public LastSnapshots(Settings settings, DatabaseSession session, ServerClient server) {
-    this.settings = settings;
+  public LastSnapshots(AnalysisMode analysisMode, DatabaseSession session, ServerClient server) {
+    this.analysisMode = analysisMode;
     this.session = session;
     this.server = server;
   }
@@ -48,7 +47,7 @@ public class LastSnapshots implements BatchComponent {
   public String getSource(Resource resource) {
     String source = "";
     if (ResourceUtils.isFile(resource)) {
-      if (settings.getBoolean(CoreProperties.DRY_RUN)) {
+      if (analysisMode.isPreview()) {
         source = loadSourceFromWs(resource);
       } else {
         source = loadSourceFromDb(resource);
index 956711a1d701668a08e8304606af0f8610f53c38..996fb1e60a79cbeeb4edd6b9c8da352b861faeaf 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.bootstrap.BatchSettings;
 import org.sonar.batch.bootstrap.ServerClient;
 
@@ -44,14 +45,14 @@ import static org.sonar.batch.bootstrap.BatchSettings.BATCH_BOOTSTRAP_PROPERTIES
 public class ModuleSettings extends Settings {
 
   private final Configuration deprecatedCommonsConf;
-  private boolean dryRun;
   private final ServerClient client;
+  private AnalysisMode analysisMode;
 
-  public ModuleSettings(BatchSettings batchSettings, ProjectDefinition project, Configuration deprecatedCommonsConf, ServerClient client) {
+  public ModuleSettings(BatchSettings batchSettings, ProjectDefinition project, Configuration deprecatedCommonsConf, ServerClient client, AnalysisMode analysisMode) {
     super(batchSettings.getDefinitions());
     this.client = client;
+    this.analysisMode = analysisMode;
     getEncryption().setPathToSecretKey(batchSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
-    this.dryRun = "true".equals(batchSettings.getString(CoreProperties.DRY_RUN));
 
     LoggerFactory.getLogger(ModuleSettings.class).info("Load module settings");
     this.deprecatedCommonsConf = deprecatedCommonsConf;
@@ -77,7 +78,7 @@ public class ModuleSettings extends Settings {
   }
 
   private void downloadSettings(String moduleKey) {
-    String url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?project=" + moduleKey + "&dryRun=" + dryRun;
+    String url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?project=" + moduleKey + "&dryRun=" + analysisMode.isPreview();
     String jsonText = client.request(url);
     List<Map<String, String>> json = (List<Map<String, String>>) JSONValue.parse(jsonText);
     for (Map<String, String> jsonProperty : json) {
@@ -124,9 +125,9 @@ public class ModuleSettings extends Settings {
 
   @Override
   protected void doOnGetProperties(String key) {
-    if (this.dryRun && key.endsWith(".secured") && !key.contains(".license")) {
+    if (analysisMode.isPreview() && key.endsWith(".secured") && !key.contains(".license")) {
       throw new SonarException("Access to the secured property '" + key
-        + "' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin which requires this property must be deactivated in dry run mode.");
+        + "' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode.");
     }
   }
 }
index 2f51d5251531fdcfab262dde1f1a1fd50d9c0584..a21b1bbd93bcd6f56e72a2269404a2075390d645 100644 (file)
@@ -22,12 +22,11 @@ package org.sonar.batch.scan;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.Semaphores;
 import org.sonar.api.utils.SonarException;
 import org.sonar.batch.ProjectTree;
+import org.sonar.batch.bootstrap.AnalysisMode;
 
 public class ProjectLock {
 
@@ -35,16 +34,16 @@ public class ProjectLock {
 
   private final Semaphores semaphores;
   private final ProjectTree projectTree;
-  private final Settings settings;
+  private final AnalysisMode analysisMode;
 
-  public ProjectLock(Semaphores semaphores, ProjectTree projectTree, Settings settings) {
+  public ProjectLock(Semaphores semaphores, ProjectTree projectTree, AnalysisMode analysisMode) {
     this.semaphores = semaphores;
     this.projectTree = projectTree;
-    this.settings = settings;
+    this.analysisMode = analysisMode;
   }
 
   public void start() {
-    if (!isInDryRunMode() && StringUtils.isNotBlank(getProject().getKey())) {
+    if (!analysisMode.isPreview() && StringUtils.isNotBlank(getProject().getKey())) {
       Semaphores.Semaphore semaphore = acquire();
       if (!semaphore.isLocked()) {
         LOG.error(getErrorMessage(semaphore));
@@ -62,7 +61,7 @@ public class ProjectLock {
   }
 
   public void stop() {
-    if (!isInDryRunMode()) {
+    if (!analysisMode.isPreview()) {
       release();
     }
   }
@@ -84,8 +83,4 @@ public class ProjectLock {
   private Project getProject() {
     return projectTree.getRootProject();
   }
-
-  private boolean isInDryRunMode() {
-    return settings.getBoolean(CoreProperties.DRY_RUN);
-  }
 }
index cce1d037c06ff23f84d5d97b0919e238eb4a0f8d..c521f261d9cb6a26afb04f15dc78a67102c32049 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.batch.scan;
 
 import org.sonar.api.BatchComponent;
-import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.MessageException;
 
@@ -33,7 +32,6 @@ public class UnsupportedProperties implements BatchComponent {
 
   public void start() {
     verify("sonar.light", "The property 'sonar.light' is no longer supported. Please use 'sonar.dynamicAnalysis'");
-    verifyIncrementalPreviewMode();
   }
 
   private void verify(String key, String message) {
@@ -41,10 +39,4 @@ public class UnsupportedProperties implements BatchComponent {
       throw MessageException.of(message);
     }
   }
-
-  private void verifyIncrementalPreviewMode() {
-    if (settings.getBoolean(CoreProperties.INCREMENTAL_PREVIEW) && !settings.getBoolean(CoreProperties.DRY_RUN)) {
-      throw MessageException.of("Incremental mode is only supported with preview mode");
-    }
-  }
 }
index 571088ac7cb96115359398252cd3ba46a389b6ec..f37c3021b6619d948e096f267345427faba07ea3 100644 (file)
@@ -32,8 +32,10 @@ import org.sonar.api.scan.filesystem.FileQuery;
 import org.sonar.api.scan.filesystem.InputFile;
 import org.sonar.api.scan.filesystem.InputFiles;
 import org.sonar.api.scan.filesystem.ModuleFileSystem;
+import org.sonar.batch.bootstrap.AnalysisMode;
 
 import javax.annotation.CheckForNull;
+
 import java.io.File;
 import java.nio.charset.Charset;
 import java.util.List;
@@ -55,16 +57,18 @@ public class DefaultModuleFileSystem implements ModuleFileSystem, Startable {
   private List<File> binaryDirs = Lists.newArrayList();
   private List<File> sourceFiles = Lists.newArrayList();
   private List<File> testFiles = Lists.newArrayList();
+  private AnalysisMode analysisMode;
 
-  public DefaultModuleFileSystem(ProjectDefinition module, Settings settings, FileIndex index, ModuleFileSystemInitializer initializer) {
-    this(module.getKey(), settings, index, initializer);
+  public DefaultModuleFileSystem(ProjectDefinition module, Settings settings, FileIndex index, ModuleFileSystemInitializer initializer, AnalysisMode analysisMode) {
+    this(module.getKey(), settings, index, initializer, analysisMode);
   }
 
   @VisibleForTesting
-  DefaultModuleFileSystem(String moduleKey, Settings settings, FileIndex index, ModuleFileSystemInitializer initializer) {
+  DefaultModuleFileSystem(String moduleKey, Settings settings, FileIndex index, ModuleFileSystemInitializer initializer, AnalysisMode analysisMode) {
     this.moduleKey = moduleKey;
     this.settings = settings;
     this.index = index;
+    this.analysisMode = analysisMode;
     this.baseDir = initializer.baseDir();
     this.workingDir = initializer.workingDir();
     this.buildDir = initializer.buildDir();
@@ -141,7 +145,7 @@ public class DefaultModuleFileSystem implements ModuleFileSystem, Startable {
   @Override
   public Iterable<InputFile> inputFiles(FileQuery query) {
     List<InputFile> result = Lists.newArrayList();
-    FileQueryFilter filter = new FileQueryFilter(settings, query);
+    FileQueryFilter filter = new FileQueryFilter(analysisMode, query);
     for (InputFile input : index.inputFiles(moduleKey)) {
       if (filter.accept(input)) {
         result.add(input);
@@ -189,7 +193,6 @@ public class DefaultModuleFileSystem implements ModuleFileSystem, Startable {
     return builder.build();
   }
 
-
   @Override
   public boolean equals(Object o) {
     if (this == o) {
index a273903d3cbd2edcdb3cb0171c4d42b72b1babdf..82f831eac1fe6c55c60987737f2b02e1130303fd 100644 (file)
@@ -21,11 +21,10 @@ package org.sonar.batch.scan.filesystem;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
 import org.sonar.api.scan.filesystem.FileQuery;
 import org.sonar.api.scan.filesystem.InputFile;
 import org.sonar.api.scan.filesystem.InputFileFilter;
+import org.sonar.batch.bootstrap.AnalysisMode;
 
 import java.util.Collection;
 import java.util.List;
@@ -35,7 +34,7 @@ class FileQueryFilter {
 
   private final List<InputFileFilter> filters;
 
-  FileQueryFilter(Settings settings, FileQuery query) {
+  FileQueryFilter(AnalysisMode analysisMode, FileQuery query) {
     filters = Lists.newArrayList();
     for (String pattern : query.inclusions()) {
       filters.add(new InclusionFilter(pattern));
@@ -48,7 +47,7 @@ class FileQueryFilter {
     }
 
     // TODO speed-up the following algorithm. Cache ?
-    if (settings.getBoolean(CoreProperties.INCREMENTAL_PREVIEW)) {
+    if (analysisMode.isIncremental()) {
       Collection<String> status = query.attributes().get(InputFile.ATTRIBUTE_STATUS);
       if (status == null || status.isEmpty()) {
         // TODO should be not(SAME) instead of is(ADDED, CHANGED)
index 81c9f8d4a1e593aca9d257e95739973c181a5b8b..b384130468cd89e81a5c8ebda7996e1cb3a86071 100644 (file)
 package org.sonar.batch.scan.report;
 
 import org.sonar.api.BatchComponent;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.scan.filesystem.InputFileCache;
 
 public class ComponentSelectorFactory implements BatchComponent {
 
   private final InputFileCache fileCache;
-  private final Settings settings;
+  private final AnalysisMode mode;
 
-  public ComponentSelectorFactory(InputFileCache fileCache, Settings settings) {
+  public ComponentSelectorFactory(InputFileCache fileCache, AnalysisMode mode) {
     this.fileCache = fileCache;
-    this.settings = settings;
+    this.mode = mode;
   }
 
   public ComponentSelector create() {
-    if (settings.getBoolean(CoreProperties.INCREMENTAL_PREVIEW)) {
+    if (mode.isIncremental()) {
       return new IncrementalComponentSelector(fileCache);
     }
     return new DefaultComponentSelector();
index 049cff49360233063ac4b067143b8fa02879288e..e43dd40be5015dd8b51a1e5f90f29a9a5f852704 100644 (file)
@@ -25,7 +25,6 @@ import com.google.gson.stream.JsonWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchComponent;
-import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.platform.Server;
@@ -33,12 +32,17 @@ import org.sonar.api.rule.RuleKey;
 import org.sonar.api.scan.filesystem.ModuleFileSystem;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.events.BatchStepEvent;
 import org.sonar.batch.events.EventBus;
 import org.sonar.batch.issue.IssueCache;
 import org.sonar.core.i18n.RuleI18nManager;
 
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
 import java.util.Locale;
 import java.util.Set;
 
@@ -58,15 +62,16 @@ public class JsonReport implements BatchComponent {
   private final IssueCache issueCache;
   private final EventBus eventBus;
   private final ComponentSelector componentSelector;
+  private AnalysisMode analysisMode;
 
   public JsonReport(Settings settings, ModuleFileSystem fileSystem, Server server, RuleI18nManager ruleI18nManager, IssueCache issueCache,
-                    EventBus eventBus, ComponentSelectorFactory componentSelectorFactory) {
-    this(settings, fileSystem, server, ruleI18nManager, issueCache, eventBus, componentSelectorFactory.create());
+    EventBus eventBus, ComponentSelectorFactory componentSelectorFactory, AnalysisMode mode) {
+    this(settings, fileSystem, server, ruleI18nManager, issueCache, eventBus, componentSelectorFactory.create(), mode);
   }
 
   @VisibleForTesting
   JsonReport(Settings settings, ModuleFileSystem fileSystem, Server server, RuleI18nManager ruleI18nManager, IssueCache issueCache,
-                    EventBus eventBus, ComponentSelector componentSelector) {
+    EventBus eventBus, ComponentSelector componentSelector, AnalysisMode analysisMode) {
     this.settings = settings;
     this.fileSystem = fileSystem;
     this.server = server;
@@ -74,10 +79,11 @@ public class JsonReport implements BatchComponent {
     this.issueCache = issueCache;
     this.eventBus = eventBus;
     this.componentSelector = componentSelector;
+    this.analysisMode = analysisMode;
   }
 
   public void execute() {
-    if (settings.getBoolean(CoreProperties.DRY_RUN)) {
+    if (analysisMode.isPreview()) {
       eventBus.fireEvent(new BatchStepEvent("JSON report", true));
       exportResults();
       eventBus.fireEvent(new BatchStepEvent("JSON report", false));
@@ -128,19 +134,19 @@ public class JsonReport implements BatchComponent {
     for (DefaultIssue issue : getIssues()) {
       if (issue.resolution() == null && componentSelector.register(issue)) {
         json
-            .beginObject()
-            .name("key").value(issue.key())
-            .name("component").value(issue.componentKey())
-            .name("line").value(issue.line())
-            .name("message").value(issue.message())
-            .name("severity").value(issue.severity())
-            .name("rule").value(issue.ruleKey().toString())
-            .name("status").value(issue.status())
-            .name("resolution").value(issue.resolution())
-            .name("isNew").value(issue.isNew())
-            .name("reporter").value(issue.reporter())
-            .name("assignee").value(issue.assignee())
-            .name("effortToFix").value(issue.effortToFix());
+          .beginObject()
+          .name("key").value(issue.key())
+          .name("component").value(issue.componentKey())
+          .name("line").value(issue.line())
+          .name("message").value(issue.message())
+          .name("severity").value(issue.severity())
+          .name("rule").value(issue.ruleKey().toString())
+          .name("status").value(issue.status())
+          .name("resolution").value(issue.resolution())
+          .name("isNew").value(issue.isNew())
+          .name("reporter").value(issue.reporter())
+          .name("assignee").value(issue.assignee())
+          .name("effortToFix").value(issue.effortToFix());
         if (issue.creationDate() != null) {
           json.name("creationDate").value(DateUtils.formatDateTime(issue.creationDate()));
         }
@@ -161,9 +167,9 @@ public class JsonReport implements BatchComponent {
     json.name("components").beginArray();
     for (String componentKey : componentSelector.componentKeys()) {
       json
-          .beginObject()
-          .name("key").value(componentKey)
-          .endObject();
+        .beginObject()
+        .name("key").value(componentKey)
+        .endObject();
     }
     json.endArray();
   }
@@ -172,12 +178,12 @@ public class JsonReport implements BatchComponent {
     json.name("rules").beginArray();
     for (RuleKey ruleKey : ruleKeys) {
       json
-          .beginObject()
-          .name("key").value(ruleKey.toString())
-          .name("rule").value(ruleKey.rule())
-          .name("repository").value(ruleKey.repository())
-          .name("name").value(getRuleName(ruleKey))
-          .endObject();
+        .beginObject()
+        .name("key").value(ruleKey.toString())
+        .name("rule").value(ruleKey.rule())
+        .name("repository").value(ruleKey.repository())
+        .name("name").value(getRuleName(ruleKey))
+        .endObject();
     }
     json.endArray();
   }
index 042c2d98bd66b1873b6656192bceaa9887fc7b3c..06e1b72b5e0ae4d1e27e3af564de91a9d4be1aa5 100644 (file)
@@ -30,7 +30,7 @@ import static org.mockito.Mockito.mock;
 public class BatchDatabaseTest {
   @Test
   public void should_init_at_least_two_connections() {
-    BatchDatabase db = new BatchDatabase(new Settings(), mock(JdbcDriverHolder.class), mock(DryRunDatabase.class));
+    BatchDatabase db = new BatchDatabase(new Settings(), mock(AnalysisMode.class), mock(JdbcDriverHolder.class), mock(PreviewDatabase.class));
     Properties props = new Properties();
 
     db.doCompleteProperties(props);
index 04ac097df7ae78ed29e308423707dec13bde6ea2..56cdc053f3cfc58870e341662b0ab4ebe89bec81 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.batch.bootstrap;
 import com.google.common.collect.Lists;
 import org.codehaus.plexus.util.FileUtils;
 import org.junit.After;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -46,6 +47,12 @@ public class BatchPluginRepositoryTest {
   public TemporaryFolder temp = new TemporaryFolder();
 
   private BatchPluginRepository repository;
+  private AnalysisMode mode;
+
+  @Before
+  public void before() {
+    mode = mock(AnalysisMode.class);
+  }
 
   @After
   public void tearDown() {
@@ -64,7 +71,7 @@ public class BatchPluginRepositoryTest {
     PluginDownloader downloader = mock(PluginDownloader.class);
     when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFiles("sonar-checkstyle-plugin-2.8.jar"));
 
-    repository = new BatchPluginRepository(downloader, tempDirs, new Settings());
+    repository = new BatchPluginRepository(downloader, tempDirs, new Settings(), mode);
 
     repository.doStart(Arrays.asList(checkstyle));
 
@@ -88,7 +95,7 @@ public class BatchPluginRepositoryTest {
     when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFiles("sonar-checkstyle-plugin-2.8.jar"));
     when(downloader.downloadPlugin(checkstyleExt)).thenReturn(copyFiles("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar"));
 
-    repository = new BatchPluginRepository(downloader, tempDirs, new Settings());
+    repository = new BatchPluginRepository(downloader, tempDirs, new Settings(), mode);
 
     repository.doStart(Arrays.asList(checkstyle, checkstyleExt));
 
@@ -110,7 +117,7 @@ public class BatchPluginRepositoryTest {
     PluginDownloader downloader = mock(PluginDownloader.class);
     when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFiles("sonar-checkstyle-plugin-2.8.jar", "checkstyle-ext.xml"));
 
-    repository = new BatchPluginRepository(downloader, tempDirs, new Settings());
+    repository = new BatchPluginRepository(downloader, tempDirs, new Settings(), mode);
 
     repository.doStart(Arrays.asList(checkstyle));
 
@@ -137,7 +144,7 @@ public class BatchPluginRepositoryTest {
 
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "checkstyle");
-    repository = new BatchPluginRepository(downloader, tempDirs, settings);
+    repository = new BatchPluginRepository(downloader, tempDirs, settings, mode);
 
     repository.doStart(Arrays.asList(checkstyle, checkstyleExt));
 
@@ -158,32 +165,32 @@ public class BatchPluginRepositoryTest {
 
   @Test
   public void shouldAlwaysAcceptIfNoWhiteListAndBlackList() {
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(new Settings());
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(new Settings(), mode);
     assertThat(filter.accepts("pmd")).isTrue();
   }
 
   @Test
   public void whiteListShouldTakePrecedenceOverBlackList() {
     Settings settings = new Settings()
-        .setProperty(CoreProperties.BATCH_INCLUDE_PLUGINS, "checkstyle,pmd,findbugs")
-        .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "cobertura,pmd");
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings);
+      .setProperty(CoreProperties.BATCH_INCLUDE_PLUGINS, "checkstyle,pmd,findbugs")
+      .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "cobertura,pmd");
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
     assertThat(filter.accepts("pmd")).isTrue();
   }
 
   @Test
   public void corePluginShouldAlwaysBeInWhiteList() {
     Settings settings = new Settings()
-        .setProperty(CoreProperties.BATCH_INCLUDE_PLUGINS, "checkstyle,pmd,findbugs");
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings);
+      .setProperty(CoreProperties.BATCH_INCLUDE_PLUGINS, "checkstyle,pmd,findbugs");
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
     assertThat(filter.accepts("core")).isTrue();
   }
 
   @Test
   public void corePluginShouldNeverBeInBlackList() {
     Settings settings = new Settings()
-        .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "core,findbugs");
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings);
+      .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "core,findbugs");
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
     assertThat(filter.accepts("core")).isTrue();
   }
 
@@ -191,16 +198,16 @@ public class BatchPluginRepositoryTest {
   @Test
   public void englishPackPluginShouldNeverBeInBlackList() {
     Settings settings = new Settings()
-        .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "l10nen,findbugs");
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings);
+      .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "l10nen,findbugs");
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
     assertThat(filter.accepts("l10nen")).isTrue();
   }
 
   @Test
   public void shouldCheckWhitelist() {
     Settings settings = new Settings()
-        .setProperty(CoreProperties.BATCH_INCLUDE_PLUGINS, "checkstyle,pmd,findbugs");
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings);
+      .setProperty(CoreProperties.BATCH_INCLUDE_PLUGINS, "checkstyle,pmd,findbugs");
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
     assertThat(filter.accepts("checkstyle")).isTrue();
     assertThat(filter.accepts("pmd")).isTrue();
     assertThat(filter.accepts("cobertura")).isFalse();
@@ -209,21 +216,33 @@ public class BatchPluginRepositoryTest {
   @Test
   public void shouldCheckBlackListIfNoWhiteList() {
     Settings settings = new Settings()
-        .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "checkstyle,pmd,findbugs");
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings);
+      .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "checkstyle,pmd,findbugs");
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
     assertThat(filter.accepts("checkstyle")).isFalse();
     assertThat(filter.accepts("pmd")).isFalse();
     assertThat(filter.accepts("cobertura")).isTrue();
   }
 
   @Test
-  public void should_concatenate_dry_run_filters() {
+  public void should_concatenate_preview_filters() {
+    Settings settings = new Settings()
+      .setProperty(CoreProperties.PREVIEW_INCLUDE_PLUGINS, "cockpit")
+      .setProperty(CoreProperties.PREVIEW_EXCLUDE_PLUGINS, "views")
+      .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "checkstyle,pmd");
+    when(mode.isPreview()).thenReturn(true);
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
+    assertThat(filter.whites).containsOnly("cockpit");
+    assertThat(filter.blacks).containsOnly("views", "checkstyle", "pmd");
+  }
+
+  @Test
+  public void should_concatenate_deprecated_dry_run_filters() {
     Settings settings = new Settings()
-        .setProperty(CoreProperties.DRY_RUN, true)
-        .setProperty(CoreProperties.DRY_RUN_INCLUDE_PLUGINS, "cockpit")
-        .setProperty(CoreProperties.DRY_RUN_EXCLUDE_PLUGINS, "views")
-        .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "checkstyle,pmd");
-    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings);
+      .setProperty(CoreProperties.DRY_RUN_INCLUDE_PLUGINS, "cockpit")
+      .setProperty(CoreProperties.DRY_RUN_EXCLUDE_PLUGINS, "views")
+      .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "checkstyle,pmd");
+    when(mode.isPreview()).thenReturn(true);
+    BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode);
     assertThat(filter.whites).containsOnly("cockpit");
     assertThat(filter.blacks).containsOnly("views", "checkstyle", "pmd");
   }
index 396b2d4be3a3930ef3c179bbed32ebecda3f7cc8..0c67862db73ac33989c0f6744c27816d05290fed 100644 (file)
@@ -56,9 +56,12 @@ public class BatchSettingsTest {
   Configuration deprecatedConf = new BaseConfiguration();
   BootstrapSettings bootstrapSettings;
 
+  private AnalysisMode mode;
+
   @Before
   public void prepare() {
-    bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.<String, String> emptyMap()));
+    bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.<String, String>emptyMap()));
+    mode = mock(AnalysisMode.class);
   }
 
   @Test
@@ -66,9 +69,9 @@ public class BatchSettingsTest {
     when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE);
     System.setProperty("BatchSettingsTest.testSystemProp", "system");
     // Reconstruct bootstrap settings to get system property
-    bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.<String, String> emptyMap()));
+    bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.<String, String>emptyMap()));
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
 
     assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system");
   }
@@ -79,7 +82,7 @@ public class BatchSettingsTest {
     when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE);
     project.setProperty("project.prop", "project");
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
     batchSettings.init(new ProjectReactor(project));
 
     assertThat(batchSettings.getString("project.prop")).isEqualTo("project");
@@ -89,7 +92,7 @@ public class BatchSettingsTest {
   public void should_load_global_settings() {
     when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE);
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
 
     assertThat(batchSettings.getBoolean("sonar.cpd.cross")).isTrue();
   }
@@ -99,7 +102,7 @@ public class BatchSettingsTest {
     when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE);
     when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE);
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
     batchSettings.init(new ProjectReactor(project));
 
     assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");
@@ -112,7 +115,7 @@ public class BatchSettingsTest {
 
     bootstrapSettings.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch");
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
     batchSettings.init(new ProjectReactor(project));
 
     assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");
@@ -123,7 +126,7 @@ public class BatchSettingsTest {
     when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE_WITH_SECURED);
     when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE);
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
     batchSettings.init(new ProjectReactor(project));
 
     assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
@@ -135,15 +138,15 @@ public class BatchSettingsTest {
     when(client.request("/batch_bootstrap/properties?dryRun=true")).thenReturn(JSON_RESPONSE_WITH_SECURED);
     when(client.request("/batch_bootstrap/properties?project=struts&dryRun=true")).thenReturn(REACTOR_JSON_RESPONSE);
 
-    bootstrapSettings.properties().put(CoreProperties.DRY_RUN, "true");
+    when(mode.isPreview()).thenReturn(true);
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
     batchSettings.init(new ProjectReactor(project));
 
     assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
     thrown.expect(SonarException.class);
     thrown
-      .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin which requires this property must be deactivated in dry run mode.");
+      .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode.");
     batchSettings.getString("sonar.foo.secured");
   }
 
@@ -153,7 +156,7 @@ public class BatchSettingsTest {
     System.setProperty("BatchSettingsTest.testSystemProp", "system");
     project.setProperty("BatchSettingsTest.testSystemProp", "build");
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
 
     assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system");
   }
@@ -163,7 +166,7 @@ public class BatchSettingsTest {
     when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE);
     when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE);
 
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
     batchSettings.init(new ProjectReactor(project));
 
     assertThat(deprecatedConf.getString("sonar.cpd.cross")).isEqualTo("true");
@@ -181,7 +184,7 @@ public class BatchSettingsTest {
   @Test
   public void project_should_be_optional() {
     when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE);
-    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf);
+    BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode);
     assertThat(batchSettings.getProperties()).isNotEmpty();
   }
 }
index 673d422affe856472531737abfcf7b18ff52b658..aa166f781951ae01c1945c793bd4b4adeeb49497 100644 (file)
@@ -41,6 +41,8 @@ public class DatabaseCompatibilityTest {
   ServerMetadata server;
   Settings settings;
 
+  private AnalysisMode mode;
+
   @Before
   public void init() {
     server = mock(ServerMetadata.class);
@@ -51,7 +53,8 @@ public class DatabaseCompatibilityTest {
     settings.setProperty(DatabaseProperties.PROP_URL, "jdbc:postgresql://localhost/foo");
     settings.setProperty(DatabaseProperties.PROP_USER, "bar");
     settings.setProperty(CoreProperties.SERVER_ID, "123456");
-    settings.setProperty(CoreProperties.DRY_RUN, false);
+
+    mode = mock(AnalysisMode.class);
 
     databaseVersion = mock(DatabaseVersion.class);
   }
@@ -63,7 +66,7 @@ public class DatabaseCompatibilityTest {
     thrown.expect(MessageException.class);
     thrown.expectMessage("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)");
 
-    new DatabaseCompatibility(databaseVersion, server, settings).start();
+    new DatabaseCompatibility(databaseVersion, server, settings, mode).start();
   }
 
   @Test
@@ -73,7 +76,7 @@ public class DatabaseCompatibilityTest {
     thrown.expect(MessageException.class);
     thrown.expectMessage("Database must be upgraded.");
 
-    new DatabaseCompatibility(databaseVersion, server, settings).start();
+    new DatabaseCompatibility(databaseVersion, server, settings, mode).start();
   }
 
   @Test
@@ -85,7 +88,7 @@ public class DatabaseCompatibilityTest {
     thrown.expectMessage("- Batch side: jdbc:postgresql://localhost/foo (bar / *****)");
     thrown.expectMessage("- Server side: check the configuration at http://localhost:9000/system");
 
-    new DatabaseCompatibility(databaseVersion, server, settings).start();
+    new DatabaseCompatibility(databaseVersion, server, settings, mode).start();
   }
 
   @Test
@@ -97,7 +100,7 @@ public class DatabaseCompatibilityTest {
     thrown.expect(MessageException.class);
     thrown.expectMessage("- Batch side: jdbc:postgresql://localhost/foo (sonar / *****)");
 
-    new DatabaseCompatibility(databaseVersion, server, settings).start();
+    new DatabaseCompatibility(databaseVersion, server, settings, mode).start();
   }
 
   @Test
@@ -106,22 +109,22 @@ public class DatabaseCompatibilityTest {
 
     thrown.expect(IllegalStateException.class);
 
-    new DatabaseCompatibility(mock(DatabaseVersion.class), server, settings).start();
+    new DatabaseCompatibility(mock(DatabaseVersion.class), server, settings, mode).start();
   }
 
   @Test
   public void shouldDoNothingIfUpToDate() {
     when(databaseVersion.getStatus()).thenReturn(DatabaseVersion.Status.UP_TO_DATE);
-    new DatabaseCompatibility(databaseVersion, server, settings).start();
+    new DatabaseCompatibility(databaseVersion, server, settings, mode).start();
     // no error
   }
 
   @Test
-  public void should_not_verify_compatibility_if_dry_run() {
+  public void should_not_verify_compatibility_if_preview() {
     settings.setProperty(CoreProperties.SERVER_ID, "11111111");
-    settings.setProperty(CoreProperties.DRY_RUN, true);
+    when(mode.isPreview()).thenReturn(true);
 
-    new DatabaseCompatibility(databaseVersion, server, settings).start();
+    new DatabaseCompatibility(databaseVersion, server, settings, mode).start();
 
     // no failure
   }
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DryRunDatabaseTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DryRunDatabaseTest.java
deleted file mode 100644 (file)
index 94935e8..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.batch.bootstrap;
-
-import org.apache.commons.lang.StringUtils;
-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.config.Settings;
-import org.sonar.api.database.DatabaseProperties;
-import org.sonar.api.utils.HttpDownloader;
-import org.sonar.api.utils.SonarException;
-
-import java.io.File;
-import java.net.SocketTimeoutException;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class DryRunDatabaseTest {
-  Settings settings;
-  ServerClient server = mock(ServerClient.class);
-  TempDirectories tempDirectories = mock(TempDirectories.class);
-  File databaseFile;
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @Before
-  public void setUp() throws Exception {
-    databaseFile = temp.newFile("dryrun.h2.db");
-    when(tempDirectories.getFile("", "dryrun.h2.db")).thenReturn(databaseFile);
-    settings = new Settings();
-    settings.setProperty(CoreProperties.DRY_RUN, true);
-    settings.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "group:project");
-  }
-
-  @Test
-  public void should_be_disabled_if_not_dry_run() {
-    settings.setProperty(CoreProperties.DRY_RUN, false);
-    new DryRunDatabase(settings, server, tempDirectories).start();
-
-    verifyZeroInteractions(tempDirectories, server);
-  }
-
-  @Test
-  public void should_download_database() {
-    new DryRunDatabase(settings, server, tempDirectories).start();
-
-    verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
-  }
-
-  @Test
-  public void should_download_database_with_overriden_timeout() {
-    settings.setProperty(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, 80);
-    new DryRunDatabase(settings, server, tempDirectories).start();
-
-    verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 80000);
-  }
-
-  @Test
-  public void should_download_database_on_branch() {
-    settings.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch");
-    new DryRunDatabase(settings, server, tempDirectories).start();
-
-    verify(server).download("/batch_bootstrap/db?project=group:project:mybranch", databaseFile, 60000);
-  }
-
-  @Test
-  public void should_replace_database_settings() {
-    new DryRunDatabase(settings, server, tempDirectories).start();
-
-    assertThat(settings.getString(DatabaseProperties.PROP_DIALECT)).isEqualTo("h2");
-    assertThat(settings.getString(DatabaseProperties.PROP_DRIVER)).isEqualTo("org.h2.Driver");
-    assertThat(settings.getString(DatabaseProperties.PROP_USER)).isEqualTo("sonar");
-    assertThat(settings.getString(DatabaseProperties.PROP_PASSWORD)).isEqualTo("sonar");
-    assertThat(settings.getString(DatabaseProperties.PROP_URL)).isEqualTo("jdbc:h2:" + StringUtils.removeEnd(databaseFile.getAbsolutePath(), ".h2.db"));
-  }
-
-  @Test
-  public void should_fail_on_invalid_role() {
-    doThrow(new SonarException(new HttpDownloader.HttpException(null, 401))).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
-
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("You don't have access rights to project [group:project]");
-
-    new DryRunDatabase(settings, server, tempDirectories).start();
-  }
-
-  @Test
-  public void should_fail_on_read_timeout() {
-    doThrow(new SonarException(new SocketTimeoutException())).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
-
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("DryRun database read timed out after 60000 ms. You can try to increase read timeout with property -Dsonar.dryRun.readTimeout (in seconds)");
-
-    new DryRunDatabase(settings, server, tempDirectories).start();
-  }
-
-  @Test
-  public void should_fail() {
-    doThrow(new SonarException("BUG")).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
-
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("BUG");
-
-    new DryRunDatabase(settings, server, tempDirectories).start();
-  }
-
-  @Test
-  public void project_should_be_optional() {
-    // on non-scan tasks
-    settings.removeProperty(CoreProperties.PROJECT_KEY_PROPERTY);
-    new DryRunDatabase(settings, server, tempDirectories).start();
-    verify(server).download("/batch_bootstrap/db", databaseFile, 60000);
-  }
-}
index cb02a9657dd8ee90629c36327320865af819264d..d3c5b7c095d146d305869b6befafebccfa9790a8 100644 (file)
@@ -21,13 +21,13 @@ package org.sonar.batch.bootstrap;
 
 import com.google.common.collect.Maps;
 import org.apache.commons.lang.ClassUtils;
+import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.BatchExtension;
 import org.sonar.api.ExtensionProvider;
 import org.sonar.api.Plugin;
 import org.sonar.api.SonarPlugin;
 import org.sonar.api.batch.SupportedEnvironment;
-import org.sonar.api.config.Settings;
 import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.platform.PluginMetadata;
 import org.sonar.batch.bootstrapper.EnvironmentInformation;
@@ -42,26 +42,32 @@ import static org.mockito.Mockito.when;
 
 public class ExtensionInstallerTest {
 
+  private AnalysisMode mode;
   PluginMetadata metadata = mock(PluginMetadata.class);
 
   Map<PluginMetadata, Plugin> newPlugin(final Object... extensions) {
     Map<PluginMetadata, Plugin> result = Maps.newHashMap();
     result.put(metadata,
-        new SonarPlugin() {
-          public List<?> getExtensions() {
-            return Arrays.asList(extensions);
-          }
+      new SonarPlugin() {
+        public List<?> getExtensions() {
+          return Arrays.asList(extensions);
         }
-        );
+      }
+      );
     return result;
   }
 
+  @Before
+  public void setUp() throws Exception {
+    mode = mock(AnalysisMode.class);
+  }
+
   @Test
   public void should_filter_extensions_to_install() {
     BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class);
     when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(Foo.class, Bar.class));
     ComponentContainer container = new ComponentContainer();
-    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
+    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), mode);
     installer.install(container, new FooMatcher());
 
     assertThat(container.getComponentByType(Foo.class)).isNotNull();
@@ -73,7 +79,7 @@ public class ExtensionInstallerTest {
     BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class);
     when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(new FooProvider(), new BarProvider()));
     ComponentContainer container = new ComponentContainer();
-    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
+    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), mode);
 
     installer.install(container, new FooMatcher());
 
@@ -86,7 +92,7 @@ public class ExtensionInstallerTest {
     BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class);
     when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(new FooBarProvider()));
     ComponentContainer container = new ComponentContainer();
-    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
+    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), mode);
 
     installer.install(container, new TrueMatcher());
 
@@ -100,7 +106,7 @@ public class ExtensionInstallerTest {
     when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(Foo.class, MavenExtension.class, AntExtension.class, new BarProvider()));
 
     ComponentContainer container = new ComponentContainer();
-    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
+    ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), mode);
 
     installer.install(container, new TrueMatcher());
 
index d58090815051faef2c340504559f6b6539c1271c..7825e2592d9fa8b9a07a8ea0a758801d90ee4e88 100644 (file)
@@ -81,10 +81,10 @@ public class ExtensionUtilsTest {
 
   @Test
   public void shouldSupportDryRun() {
-    assertThat(ExtensionUtils.supportsDryRun(BatchService.class)).isTrue();
-    assertThat(ExtensionUtils.supportsDryRun(new BatchService())).isTrue();
-    assertThat(ExtensionUtils.supportsDryRun(PersistentService.class)).isFalse();
-    assertThat(ExtensionUtils.supportsDryRun(new PersistentService())).isFalse();
+    assertThat(ExtensionUtils.supportsPreview(BatchService.class)).isTrue();
+    assertThat(ExtensionUtils.supportsPreview(new BatchService())).isTrue();
+    assertThat(ExtensionUtils.supportsPreview(PersistentService.class)).isFalse();
+    assertThat(ExtensionUtils.supportsPreview(new PersistentService())).isFalse();
   }
 
   @InstantiationStrategy(InstantiationStrategy.PER_BATCH)
index f54e45b464c39edeba6409824317c5f1bcc9352f..3e36a9b103d887ac9b496eb9c186c6260a120aaa 100644 (file)
@@ -25,8 +25,6 @@ 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.config.Settings;
 import org.sonar.home.cache.FileCache;
 
 import java.io.File;
@@ -47,10 +45,12 @@ public class JdbcDriverHolderTest {
   public ExpectedException thrown = ExpectedException.none();
 
   ClassLoader initialThreadClassloader;
+  private AnalysisMode mode;
 
   @Before
   public void before() {
     initialThreadClassloader = Thread.currentThread().getContextClassLoader();
+    mode = mock(AnalysisMode.class);
   }
 
   @After
@@ -72,7 +72,7 @@ public class JdbcDriverHolderTest {
     when(server.request("/deploy/jdbc-driver.txt")).thenReturn("ojdbc14.jar|fakemd5");
     when(server.request("/deploy/ojdbc14.jar")).thenReturn("fakecontent");
 
-    JdbcDriverHolder holder = new JdbcDriverHolder(cache, new Settings(), server);
+    JdbcDriverHolder holder = new JdbcDriverHolder(cache, mode, server);
     holder.start();
 
     assertThat(holder.getClassLoader().getResource("foo/foo.txt")).isNotNull();
@@ -85,11 +85,11 @@ public class JdbcDriverHolderTest {
   }
 
   @Test
-  public void should_be_disabled_if_dry_run() {
+  public void should_be_disabled_if_preview() {
     FileCache cache = mock(FileCache.class);
-    Settings settings = new Settings().setProperty(CoreProperties.DRY_RUN, true);
+    when(mode.isPreview()).thenReturn(true);
     ServerClient server = mock(ServerClient.class);
-    JdbcDriverHolder holder = new JdbcDriverHolder(cache, settings, server);
+    JdbcDriverHolder holder = new JdbcDriverHolder(cache, mode, server);
 
     holder.start();
 
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java
new file mode 100644 (file)
index 0000000..cd41618
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.bootstrap;
+
+import org.apache.commons.lang.StringUtils;
+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.config.Settings;
+import org.sonar.api.database.DatabaseProperties;
+import org.sonar.api.utils.HttpDownloader;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.net.SocketTimeoutException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class PreviewDatabaseTest {
+  Settings settings;
+  ServerClient server = mock(ServerClient.class);
+  TempDirectories tempDirectories = mock(TempDirectories.class);
+  File databaseFile;
+  private AnalysisMode mode;
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Before
+  public void setUp() throws Exception {
+    databaseFile = temp.newFile("preview.h2.db");
+    when(tempDirectories.getFile("", "preview.h2.db")).thenReturn(databaseFile);
+    settings = new Settings();
+    settings.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "group:project");
+
+    mode = mock(AnalysisMode.class);
+    when(mode.isPreview()).thenReturn(true);
+  }
+
+  @Test
+  public void should_be_disabled_if_not_preview() {
+    when(mode.isPreview()).thenReturn(false);
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+
+    verifyZeroInteractions(tempDirectories, server);
+  }
+
+  @Test
+  public void should_download_database() {
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+
+    verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
+  }
+
+  @Test
+  public void should_download_database_with_deprecated_overriden_timeout() {
+    settings.setProperty(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, 80);
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+
+    verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 80000);
+  }
+
+  @Test
+  public void should_download_database_with_overriden_timeout() {
+    settings.setProperty(CoreProperties.PREVIEW_READ_TIMEOUT_SEC, 80);
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+
+    verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 80000);
+  }
+
+  @Test
+  public void should_download_database_on_branch() {
+    settings.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch");
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+
+    verify(server).download("/batch_bootstrap/db?project=group:project:mybranch", databaseFile, 60000);
+  }
+
+  @Test
+  public void should_replace_database_settings() {
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+
+    assertThat(settings.getString(DatabaseProperties.PROP_DIALECT)).isEqualTo("h2");
+    assertThat(settings.getString(DatabaseProperties.PROP_DRIVER)).isEqualTo("org.h2.Driver");
+    assertThat(settings.getString(DatabaseProperties.PROP_USER)).isEqualTo("sonar");
+    assertThat(settings.getString(DatabaseProperties.PROP_PASSWORD)).isEqualTo("sonar");
+    assertThat(settings.getString(DatabaseProperties.PROP_URL)).isEqualTo("jdbc:h2:" + StringUtils.removeEnd(databaseFile.getAbsolutePath(), ".h2.db"));
+  }
+
+  @Test
+  public void should_fail_on_invalid_role() {
+    doThrow(new SonarException(new HttpDownloader.HttpException(null, 401))).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
+
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("You don't have access rights to project [group:project]");
+
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+  }
+
+  @Test
+  public void should_fail_on_read_timeout() {
+    doThrow(new SonarException(new SocketTimeoutException())).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
+
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("Preview database read timed out after 60000 ms. You can try to increase read timeout with property -Dsonar.preview.readTimeout (in seconds)");
+
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+  }
+
+  @Test
+  public void should_fail() {
+    doThrow(new SonarException("BUG")).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
+
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("BUG");
+
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+  }
+
+  @Test
+  public void project_should_be_optional() {
+    // on non-scan tasks
+    settings.removeProperty(CoreProperties.PROJECT_KEY_PROPERTY);
+    new PreviewDatabase(settings, server, tempDirectories, mode).start();
+    verify(server).download("/batch_bootstrap/db", databaseFile, 60000);
+  }
+}
index 0a30195aa1f5f16d49a4887826450486c6442377..baa08006d3c5548e5e21ec0f222db0927dd4e863 100644 (file)
@@ -21,8 +21,8 @@ package org.sonar.batch.issue;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
 import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.core.persistence.AbstractDaoTestCase;
 
 import java.util.Arrays;
@@ -39,7 +39,7 @@ public class IssuePersisterTest extends AbstractDaoTestCase {
   IssuePersister persister;
   private ScanIssueStorage storage;
   private List<DefaultIssue> issues;
-  private Settings settings;
+  private AnalysisMode mode;
 
   @Before
   public void prepare() {
@@ -48,8 +48,8 @@ public class IssuePersisterTest extends AbstractDaoTestCase {
     when(issueCache.all()).thenReturn(issues);
     storage = mock(ScanIssueStorage.class);
 
-    settings = new Settings();
-    persister = new IssuePersister(issueCache, storage, settings);
+    mode = mock(AnalysisMode.class);
+    persister = new IssuePersister(issueCache, storage, mode);
   }
 
   @Test
@@ -60,8 +60,8 @@ public class IssuePersisterTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_not_persist_issues_in_dry_run() throws Exception {
-    settings.setProperty("sonar.dryRun", true);
+  public void should_not_persist_issues_in_preview_mode() throws Exception {
+    when(mode.isPreview()).thenReturn(true);
 
     persister.persist();
 
index fd975e034de3b6fa9269278144864adb1b985564..88e21cc4a36a7b8364581c86e8f47053ce30e8ce 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.batch.phases;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.sonar.api.CoreProperties;
@@ -27,6 +28,8 @@ import org.sonar.api.database.DatabaseSession;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.resources.Project;
 import org.sonar.api.security.ResourcePermissions;
+import org.sonar.batch.bootstrap.AnalysisMode;
+import org.sonar.batch.bootstrap.BootstrapSettings;
 import org.sonar.batch.bootstrap.ServerClient;
 import org.sonar.batch.index.DefaultResourcePersister;
 import org.sonar.batch.index.ResourceCache;
@@ -41,9 +44,18 @@ import static org.mockito.Matchers.contains;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
 
+  private AnalysisMode mode;
+  private BootstrapSettings bootstrapSettings;
+
+  @Before
+  public void setUp() {
+    mode = mock(AnalysisMode.class);
+  }
+
   @Test
   public void shouldUnflagPenultimateLastSnapshot() {
     assertAnalysis(11, "shouldUnflagPenultimateLastSnapshot");
@@ -67,7 +79,7 @@ public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
     project.setId(1);
     UpdateStatusJob job = new UpdateStatusJob(new Settings().appendProperty(CoreProperties.SERVER_BASE_URL, "http://myserver/"), mock(ServerClient.class), session,
       new DefaultResourcePersister(session, mock(ResourcePermissions.class), mock(SnapshotCache.class), mock(ResourceCache.class)),
-      project, loadSnapshot(snapshotId));
+      project, loadSnapshot(snapshotId), mode);
     job.execute();
 
     checkTables(fixture, "snapshots");
@@ -85,7 +97,7 @@ public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
     settings.setProperty(CoreProperties.SERVER_BASE_URL, "http://myserver/");
     Project project = new Project("struts");
     UpdateStatusJob job = new UpdateStatusJob(settings, mock(ServerClient.class), mock(DatabaseSession.class),
-      mock(ResourcePersister.class), project, mock(Snapshot.class));
+      mock(ResourcePersister.class), project, mock(Snapshot.class), mode);
 
     Logger logger = mock(Logger.class);
     job.logSuccess(logger);
@@ -94,12 +106,12 @@ public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
   }
 
   @Test
-  public void should_log_successful_dry_run_analysis() throws Exception {
+  public void should_log_successful_preview_analysis() throws Exception {
     Settings settings = new Settings();
-    settings.setProperty("sonar.dryRun", true);
+    when(mode.isPreview()).thenReturn(true);
     Project project = new Project("struts");
     UpdateStatusJob job = new UpdateStatusJob(settings, mock(ServerClient.class), mock(DatabaseSession.class),
-      mock(ResourcePersister.class), project, mock(Snapshot.class));
+      mock(ResourcePersister.class), project, mock(Snapshot.class), mode);
 
     Logger logger = mock(Logger.class);
     job.logSuccess(logger);
@@ -113,22 +125,22 @@ public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
     Project project = new Project("struts");
     ServerClient serverClient = mock(ServerClient.class);
     UpdateStatusJob job = new UpdateStatusJob(settings, serverClient, mock(DatabaseSession.class),
-      mock(ResourcePersister.class), project, mock(Snapshot.class));
+      mock(ResourcePersister.class), project, mock(Snapshot.class), mode);
 
-    job.evictDryRunDB();
+    job.evictPreviewDB();
     verify(serverClient).request(contains("/batch_bootstrap/evict"));
   }
 
   @Test
-  public void should_not_evict_cache_for_dry_run_analysis() throws Exception {
+  public void should_not_evict_cache_for_preview_analysis() throws Exception {
     Settings settings = new Settings();
-    settings.setProperty("sonar.dryRun", true);
+    when(mode.isPreview()).thenReturn(true);
     Project project = new Project("struts");
     ServerClient serverClient = mock(ServerClient.class);
     UpdateStatusJob job = new UpdateStatusJob(settings, serverClient, mock(DatabaseSession.class),
-      mock(ResourcePersister.class), project, mock(Snapshot.class));
+      mock(ResourcePersister.class), project, mock(Snapshot.class), mode);
 
-    job.evictDryRunDB();
+    job.evictPreviewDB();
     verify(serverClient, never()).request(anyString());
   }
 }
index fe2a78750dee27d8c1235b5862a1300c646e5cc0..d712ee662455f0ef68ffde035f74bed73fed0eac 100644 (file)
  */
 package org.sonar.batch.scan;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
 import org.sonar.api.resources.File;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.HttpDownloader;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.bootstrap.ServerClient;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
 
@@ -36,19 +36,28 @@ import java.net.URISyntaxException;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 public class LastSnapshotsTest extends AbstractDbUnitTestCase {
 
   @Rule
   public ExpectedException thrown = ExpectedException.none();
+  private AnalysisMode mode;
+
+  @Before
+  public void before() {
+    mode = mock(AnalysisMode.class);
+  }
 
   @Test
   public void should_get_source_of_last_snapshot() {
     setupData("last_snapshot");
     ServerClient server = mock(ServerClient.class);
 
-    LastSnapshots lastSnapshots = new LastSnapshots(new Settings(), getSession(), server);
+    LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     assertThat(lastSnapshots.getSource(newFile())).isEqualTo("this is bar");
     verifyZeroInteractions(server);
@@ -59,21 +68,20 @@ public class LastSnapshotsTest extends AbstractDbUnitTestCase {
     setupData("no_last_snapshot");
     ServerClient server = mock(ServerClient.class);
 
-    LastSnapshots lastSnapshots = new LastSnapshots(new Settings(), getSession(), server);
+    LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     assertThat(lastSnapshots.getSource(newFile())).isEqualTo("");
     verifyZeroInteractions(server);
   }
 
   @Test
-  public void should_download_source_from_ws_if_dry_run() {
+  public void should_download_source_from_ws_if_preview_mode() {
     setupData("last_snapshot");
     ServerClient server = mock(ServerClient.class);
     when(server.request(anyString(), eq(false))).thenReturn("downloaded source of Bar.c");
 
-    Settings settings = new Settings();
-    settings.setProperty(CoreProperties.DRY_RUN, true);
-    LastSnapshots lastSnapshots = new LastSnapshots(settings, getSession(), server);
+    when(mode.isPreview()).thenReturn(true);
+    LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     String source = lastSnapshots.getSource(newFile());
     assertThat(source).isEqualTo("downloaded source of Bar.c");
@@ -86,23 +94,21 @@ public class LastSnapshotsTest extends AbstractDbUnitTestCase {
     ServerClient server = mock(ServerClient.class);
     when(server.request(anyString(), eq(false))).thenThrow(new HttpDownloader.HttpException(new URI(""), 500));
 
-    Settings settings = new Settings();
-    settings.setProperty(CoreProperties.DRY_RUN, true);
-    LastSnapshots lastSnapshots = new LastSnapshots(settings, getSession(), server);
+    when(mode.isPreview()).thenReturn(true);
+    LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     thrown.expect(HttpDownloader.HttpException.class);
     lastSnapshots.getSource(newFile());
   }
 
   @Test
-  public void should_return_empty_source_if_dry_run_and_no_last_snapshot() throws URISyntaxException {
+  public void should_return_empty_source_if_preview_mode_and_no_last_snapshot() throws URISyntaxException {
     setupData("last_snapshot");
     ServerClient server = mock(ServerClient.class);
     when(server.request(anyString(), eq(false))).thenThrow(new HttpDownloader.HttpException(new URI(""), 404));
 
-    Settings settings = new Settings();
-    settings.setProperty(CoreProperties.DRY_RUN, true);
-    LastSnapshots lastSnapshots = new LastSnapshots(settings, getSession(), server);
+    when(mode.isPreview()).thenReturn(true);
+    LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     String source = lastSnapshots.getSource(newFile());
     assertThat(source).isEqualTo("");
@@ -114,7 +120,7 @@ public class LastSnapshotsTest extends AbstractDbUnitTestCase {
     setupData("last_snapshot");
     ServerClient server = mock(ServerClient.class);
 
-    LastSnapshots lastSnapshots = new LastSnapshots(new Settings(), getSession(), server);
+    LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     String source = lastSnapshots.getSource(new Project("my-project"));
     assertThat(source).isEqualTo("");
index 9df1e2aace3e0f9f40dcaf45b3682dd7246bd9c3..61f2a5c8043a8f5d1a8225b64f8892684026cf09 100644 (file)
@@ -22,13 +22,14 @@ package org.sonar.batch.scan;
 import com.google.common.collect.ImmutableMap;
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.PropertiesConfiguration;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.bootstrap.BatchSettings;
 import org.sonar.batch.bootstrap.ServerClient;
 
@@ -44,6 +45,12 @@ public class ModuleSettingsTest {
   public ExpectedException thrown = ExpectedException.none();
 
   ServerClient client = mock(ServerClient.class);
+  private AnalysisMode mode;
+
+  @Before
+  public void before() {
+    mode = mock(AnalysisMode.class);
+  }
 
   @Test
   public void testOrderedProjects() {
@@ -74,7 +81,7 @@ public class ModuleSettingsTest {
     ProjectDefinition module = ProjectDefinition.create().setKey("struts-core");
     Configuration deprecatedConf = new PropertiesConfiguration();
 
-    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client);
+    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client, mode);
 
     assertThat(moduleSettings.getString("overridding")).isEqualTo("module");
     assertThat(moduleSettings.getString("on-batch")).isEqualTo("true");
@@ -98,33 +105,35 @@ public class ModuleSettingsTest {
     ProjectDefinition module = ProjectDefinition.create().setKey("struts-core");
     Configuration deprecatedConf = new PropertiesConfiguration();
 
-    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client);
+    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client, mode);
 
     assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
     assertThat(moduleSettings.getString("sonar.foo.secured")).isEqualTo("bar");
   }
 
   @Test
-  public void should_fail_when_accessing_secured_properties_in_dryrun() {
+  public void should_fail_when_accessing_secured_properties_in_preview() {
     BatchSettings batchSettings = mock(BatchSettings.class);
     when(batchSettings.getDefinitions()).thenReturn(new PropertyDefinitions());
-    when(batchSettings.getString(CoreProperties.DRY_RUN)).thenReturn("true");
     when(batchSettings.getProperties()).thenReturn(ImmutableMap.of(
       "sonar.foo.secured", "bar"
       ));
+
+    when(mode.isPreview()).thenReturn(true);
+
     when(client.request("/batch_bootstrap/properties?project=struts-core&dryRun=true"))
       .thenReturn("[{\"k\":\"sonar.foo.license.secured\",\"v\":\"bar2\"}]");
 
     ProjectDefinition module = ProjectDefinition.create().setKey("struts-core");
     Configuration deprecatedConf = new PropertiesConfiguration();
 
-    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client);
+    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client, mode);
 
     assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
 
     thrown.expect(SonarException.class);
     thrown
-      .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin which requires this property must be deactivated in dry run mode.");
+      .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode.");
     moduleSettings.getString("sonar.foo.secured");
   }
 }
index c32829a13fcf01bfafc3d1f74c30bbf2cfec6a44..30a5c367ef8275b8c714d075c01627213879461e 100644 (file)
@@ -21,12 +21,12 @@ package org.sonar.batch.scan;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.Semaphores;
 import org.sonar.api.utils.SonarException;
 import org.sonar.batch.ProjectTree;
+import org.sonar.batch.bootstrap.AnalysisMode;
 
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
@@ -42,15 +42,16 @@ public class ProjectLockTest {
   ProjectTree projectTree = mock(ProjectTree.class);
   Settings settings;
   Project project;
+  private AnalysisMode mode;
 
   @Before
   public void setUp() {
-    settings = new Settings();
-    setDryRunMode(false);
+    mode = mock(AnalysisMode.class);
+
     project = new Project("my-project-key");
     when(projectTree.getRootProject()).thenReturn(project);
 
-    projectLock = new ProjectLock(semaphores, projectTree, settings);
+    projectLock = new ProjectLock(semaphores, projectTree, mode);
   }
 
   @Test
@@ -69,8 +70,7 @@ public class ProjectLockTest {
 
   @Test
   public void shouldNotAcquireSemaphoreInDryRunMode() {
-    setDryRunMode(true);
-    settings = new Settings().setProperty(CoreProperties.DRY_RUN, true);
+    when(mode.isPreview()).thenReturn(true);
     projectLock.start();
     verifyZeroInteractions(semaphores);
   }
@@ -82,14 +82,10 @@ public class ProjectLockTest {
   }
 
   @Test
-  public void shouldNotReleaseSemaphoreInDryRunMode() {
-    setDryRunMode(true);
+  public void shouldNotReleaseSemaphoreInPreviewMode() {
+    when(mode.isPreview()).thenReturn(true);
     projectLock.stop();
     verifyZeroInteractions(semaphores);
   }
 
-  private void setDryRunMode(boolean isInDryRunMode) {
-    settings.setProperty(CoreProperties.DRY_RUN, isInDryRunMode);
-  }
-
 }
index f5246e640996b9a94d6a649c4a2f5c3096b9c805..1e61091991cd5f522e29a9ea7cadc04412f41003 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.batch.scan;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.MessageException;
 
@@ -46,23 +45,4 @@ public class UnsupportedPropertiesTest {
     Settings settings = new Settings();
     new UnsupportedProperties(settings).start();
   }
-
-  @Test
-  public void should_fail_if_incremental_but_not_preview_mode() {
-    thrown.expect(MessageException.class);
-    thrown.expectMessage("Incremental mode is only supported with preview mode");
-
-    Settings settings = new Settings();
-    settings.setProperty(CoreProperties.INCREMENTAL_PREVIEW, true);
-    settings.setProperty(CoreProperties.DRY_RUN, false);
-    new UnsupportedProperties(settings).start();
-  }
-
-  @Test
-  public void should_not_fail_if_incremental_preview_mode() {
-    Settings settings = new Settings();
-    settings.setProperty(CoreProperties.INCREMENTAL_PREVIEW, true);
-    settings.setProperty(CoreProperties.DRY_RUN, true);
-    new UnsupportedProperties(settings).start();
-  }
 }
index b7948e7f5bd7b243fb4184d66aa2cbe1f12e4d7d..eeded167a4604ea8090f1d8bb63a518572e62f76 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.batch.scan.filesystem;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -31,6 +32,7 @@ import org.sonar.api.config.Settings;
 import org.sonar.api.scan.filesystem.FileQuery;
 import org.sonar.api.scan.filesystem.InputFile;
 import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.batch.bootstrap.AnalysisMode;
 
 import java.io.File;
 import java.io.IOException;
@@ -39,7 +41,10 @@ import java.util.Arrays;
 import java.util.List;
 
 import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 public class DefaultModuleFileSystemTest {
 
@@ -52,12 +57,18 @@ public class DefaultModuleFileSystemTest {
   Settings settings = new Settings();
   FileIndex fileIndex = mock(FileIndex.class);
   ModuleFileSystemInitializer initializer = mock(ModuleFileSystemInitializer.class, Mockito.RETURNS_DEEP_STUBS);
+  private AnalysisMode mode;
+
+  @Before
+  public void before() {
+    mode = mock(AnalysisMode.class);
+  }
 
   @Test
   public void test_equals_and_hashCode() throws Exception {
-    DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
-    DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
-    DefaultModuleFileSystem bar = new DefaultModuleFileSystem("bar", settings, fileIndex, initializer);
+    DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
+    DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
+    DefaultModuleFileSystem bar = new DefaultModuleFileSystem("bar", settings, fileIndex, initializer, mode);
 
     assertThat(foo1.moduleKey()).isEqualTo("foo");
     assertThat(foo1.equals(foo1)).isTrue();
@@ -70,7 +81,7 @@ public class DefaultModuleFileSystemTest {
 
   @Test
   public void default_source_encoding() {
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
 
     assertThat(fs.sourceCharset()).isEqualTo(Charset.defaultCharset());
     assertThat(fs.isDefaultSourceCharset()).isTrue();
@@ -79,7 +90,7 @@ public class DefaultModuleFileSystemTest {
   @Test
   public void source_encoding_is_set() {
     settings.setProperty(CoreProperties.ENCODING_PROPERTY, "Cp1124");
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
 
     assertThat(fs.sourceCharset()).isEqualTo(Charset.forName("Cp1124"));
 
@@ -103,8 +114,7 @@ public class DefaultModuleFileSystemTest {
     when(initializer.additionalSourceFiles()).thenReturn(Arrays.asList(additionalFile));
     when(initializer.additionalTestFiles()).thenReturn(Arrays.asList(additionalTest));
 
-
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
 
     assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath());
     assertThat(fs.workingDir().getCanonicalPath()).isEqualTo(workingDir.getCanonicalPath());
@@ -123,7 +133,7 @@ public class DefaultModuleFileSystemTest {
     when(initializer.workingDir()).thenReturn(basedir);
     when(initializer.sourceDirs()).thenReturn(Arrays.asList(new File(basedir, "src/main/java")));
 
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
 
     File existingDir = temp.newFolder("new_folder");
     File notExistingDir = new File(existingDir, "not_exist");
@@ -144,7 +154,7 @@ public class DefaultModuleFileSystemTest {
 
   @Test
   public void should_search_input_files() throws Exception {
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
 
     File mainFile = temp.newFile();
     InputFile mainInput = DefaultInputFile.create(mainFile, "Main.java", ImmutableMap.of(InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_SOURCE));
@@ -161,7 +171,7 @@ public class DefaultModuleFileSystemTest {
 
   @Test
   public void should_index() throws Exception {
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem("foo", settings, fileIndex, initializer, mode);
 
     verifyZeroInteractions(fileIndex);
 
index b149bbf457606507c1da60da449c01a0008946b0..49cdd51ba14e4aa881e30136116b658f0a476497 100644 (file)
  */
 package org.sonar.batch.scan.filesystem;
 
+import org.junit.Before;
 import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
 import org.sonar.api.scan.filesystem.FileQuery;
 import org.sonar.api.scan.filesystem.InputFile;
 import org.sonar.api.scan.filesystem.InputFileFilter;
+import org.sonar.batch.bootstrap.AnalysisMode;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class FileQueryFilterTest {
 
-  Settings settings = new Settings();
+  private AnalysisMode mode;
+
+  @Before
+  public void before() {
+    mode = mock(AnalysisMode.class);
+  }
 
   @Test
   public void wrap_query_on_attributes() throws Exception {
     FileQuery query = FileQuery.onSource();
-    FileQueryFilter filter = new FileQueryFilter(settings, query);
+    FileQueryFilter filter = new FileQueryFilter(mode, query);
 
     assertThat(filter.filters()).hasSize(1);
     InputFileFilter typeFilter = filter.filters().get(0);
@@ -47,7 +54,7 @@ public class FileQueryFilterTest {
   @Test
   public void wrap_query_on_inclusions() throws Exception {
     FileQuery query = FileQuery.on().withInclusions("Foo*.java");
-    FileQueryFilter filter = new FileQueryFilter(settings, query);
+    FileQueryFilter filter = new FileQueryFilter(mode, query);
 
     assertThat(filter.filters()).hasSize(1);
     InputFileFilter inclusionFilter = filter.filters().get(0);
@@ -58,7 +65,7 @@ public class FileQueryFilterTest {
   @Test
   public void wrap_query_on_exclusions() throws Exception {
     FileQuery query = FileQuery.on().withExclusions("Foo*.java");
-    FileQueryFilter filter = new FileQueryFilter(settings, query);
+    FileQueryFilter filter = new FileQueryFilter(mode, query);
 
     assertThat(filter.filters()).hasSize(1);
     InputFileFilter exclusionFilter = filter.filters().get(0);
@@ -69,16 +76,16 @@ public class FileQueryFilterTest {
   @Test
   public void all_files_by_default() throws Exception {
     FileQuery query = FileQuery.on();
-    FileQueryFilter filter = new FileQueryFilter(settings, query);
+    FileQueryFilter filter = new FileQueryFilter(mode, query);
     assertThat(filter.filters()).isEmpty();
   }
 
   @Test
   public void only_changed_files_by_default_if_incremental_mode() throws Exception {
-    settings.setProperty(CoreProperties.INCREMENTAL_PREVIEW, true);
+    when(mode.isIncremental()).thenReturn(true);
 
     FileQuery query = FileQuery.on();
-    FileQueryFilter filter = new FileQueryFilter(settings, query);
+    FileQueryFilter filter = new FileQueryFilter(mode, query);
 
     assertThat(filter.filters()).hasSize(1);
     AttributeFilter statusFilter = (AttributeFilter) filter.filters().get(0);
@@ -88,10 +95,10 @@ public class FileQueryFilterTest {
 
   @Test
   public void get_all_files_even_if_incremental_mode() throws Exception {
-    settings.setProperty(CoreProperties.INCREMENTAL_PREVIEW, true);
+    when(mode.isIncremental()).thenReturn(true);
 
     FileQuery query = FileQuery.on().on(InputFile.ATTRIBUTE_STATUS, InputFile.STATUS_SAME);
-    FileQueryFilter filter = new FileQueryFilter(settings, query);
+    FileQueryFilter filter = new FileQueryFilter(mode, query);
 
     assertThat(filter.filters()).hasSize(1);
     AttributeFilter statusFilter = (AttributeFilter) filter.filters().get(0);
index 74d6b6ce413b6afe3ebfb1c9ee8d44c17adef570..2c8d070c97d22c7f4cdcf7c4998efac3d6189746 100644 (file)
@@ -25,7 +25,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.skyscreamer.jsonassert.JSONAssert;
-import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.internal.DefaultIssue;
@@ -34,6 +33,7 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.scan.filesystem.ModuleFileSystem;
+import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.events.EventBus;
 import org.sonar.batch.issue.IssueCache;
 import org.sonar.core.i18n.RuleI18nManager;
@@ -62,6 +62,7 @@ public class JsonReportTest {
   RuleI18nManager ruleI18nManager = mock(RuleI18nManager.class);
   Settings settings;
   IssueCache issueCache = mock(IssueCache.class);
+  private AnalysisMode mode;
 
   @Before
   public void setUp() {
@@ -69,62 +70,63 @@ public class JsonReportTest {
     when(server.getVersion()).thenReturn("3.6");
 
     settings = new Settings();
-    settings.setProperty(CoreProperties.DRY_RUN, true);
-    jsonReport = new JsonReport(settings, fileSystem, server, ruleI18nManager, issueCache, mock(EventBus.class), new DefaultComponentSelector());
+    mode = mock(AnalysisMode.class);
+    when(mode.isPreview()).thenReturn(true);
+    jsonReport = new JsonReport(settings, fileSystem, server, ruleI18nManager, issueCache, mock(EventBus.class), new DefaultComponentSelector(), mode);
   }
 
   @Test
   public void should_write_json() throws Exception {
     DefaultIssue issue = new DefaultIssue()
-        .setKey("200")
-        .setComponentKey("struts:org.apache.struts.Action")
-        .setRuleKey(RuleKey.of("squid", "AvoidCycles"))
-        .setMessage("There are 2 cycles")
-        .setSeverity("MINOR")
-        .setStatus(Issue.STATUS_OPEN)
-        .setResolution(null)
-        .setLine(1)
-        .setEffortToFix(3.14)
-        .setReporter("julien")
-        .setAssignee("simon")
-        .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-24"))
-          .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-25"))
-          .setNew(false);
+      .setKey("200")
+      .setComponentKey("struts:org.apache.struts.Action")
+      .setRuleKey(RuleKey.of("squid", "AvoidCycles"))
+      .setMessage("There are 2 cycles")
+      .setSeverity("MINOR")
+      .setStatus(Issue.STATUS_OPEN)
+      .setResolution(null)
+      .setLine(1)
+      .setEffortToFix(3.14)
+      .setReporter("julien")
+      .setAssignee("simon")
+      .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-24"))
+      .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-25"))
+      .setNew(false);
     when(ruleI18nManager.getName("squid", "AvoidCycles", Locale.getDefault())).thenReturn("Avoid Cycles");
-    when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue> newArrayList(issue));
+    when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue));
 
     StringWriter writer = new StringWriter();
     jsonReport.writeJson(writer);
 
     JSONAssert.assertEquals(TestUtils.getResourceContent("/org/sonar/batch/scan/report/JsonReportTest/report.json"),
-        writer.toString(), false);
+      writer.toString(), false);
   }
 
   @Test
   public void should_exclude_resolved_issues() throws Exception {
     DefaultIssue issue = new DefaultIssue()
-        .setKey("200")
-        .setComponentKey("struts:org.apache.struts.Action")
-        .setRuleKey(RuleKey.of("squid", "AvoidCycles"))
-        .setStatus(Issue.STATUS_CLOSED)
-        .setResolution(Issue.RESOLUTION_FIXED)
-        .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-24"))
-        .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-25"))
-        .setCloseDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-26"))
-        .setNew(false);
+      .setKey("200")
+      .setComponentKey("struts:org.apache.struts.Action")
+      .setRuleKey(RuleKey.of("squid", "AvoidCycles"))
+      .setStatus(Issue.STATUS_CLOSED)
+      .setResolution(Issue.RESOLUTION_FIXED)
+      .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-24"))
+      .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-25"))
+      .setCloseDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-04-26"))
+      .setNew(false);
     when(ruleI18nManager.getName("squid", "AvoidCycles", Locale.getDefault())).thenReturn("Avoid Cycles");
-    when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue> newArrayList(issue));
+    when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue));
 
     StringWriter writer = new StringWriter();
     jsonReport.writeJson(writer);
 
     JSONAssert.assertEquals(TestUtils.getResourceContent("/org/sonar/batch/scan/report/JsonReportTest/report-without-resolved-issues.json"),
-        writer.toString(), false);
+      writer.toString(), false);
   }
 
   @Test
   public void should_ignore_components_without_issue() throws JSONException {
-    when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue> emptyList());
+    when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList());
 
     StringWriter writer = new StringWriter();
     jsonReport.writeJson(writer);
@@ -138,7 +140,7 @@ public class JsonReportTest {
 
     Rule rule = Rule.create("squid", "AvoidCycles");
     when(ruleI18nManager.getName(rule, Locale.getDefault())).thenReturn("Avoid Cycles");
-    when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue> emptyList());
+    when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList());
 
     settings.setProperty("sonar.report.export.path", "output.json");
     when(fileSystem.workingDir()).thenReturn(sonarDirectory);
diff --git a/sonar-core/src/main/java/org/sonar/core/dryrun/DryRunCache.java b/sonar-core/src/main/java/org/sonar/core/dryrun/DryRunCache.java
deleted file mode 100644 (file)
index d85053d..0000000
+++ /dev/null
@@ -1,202 +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.core.dryrun;
-
-import com.google.common.io.Files;
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.ServerExtension;
-import org.sonar.api.platform.ServerFileSystem;
-import org.sonar.api.utils.SonarException;
-import org.sonar.core.persistence.DryRunDatabaseFactory;
-import org.sonar.core.properties.PropertiesDao;
-import org.sonar.core.properties.PropertyDto;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-
-import javax.annotation.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * @since 3.7.1
- */
-public class DryRunCache implements ServerExtension {
-
-  private static final Logger LOG = LoggerFactory.getLogger(DryRunCache.class);
-
-  public static final String SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY = "sonar.dryRun.cache.lastUpdate";
-
-  private ServerFileSystem serverFileSystem;
-  private PropertiesDao propertiesDao;
-  private ResourceDao resourceDao;
-
-  private Map<Long, ReadWriteLock> lockPerProject = new HashMap<Long, ReadWriteLock>();
-  private Map<Long, Long> lastTimestampPerProject = new HashMap<Long, Long>();
-
-  private DryRunDatabaseFactory dryRunDatabaseFactory;
-
-  public DryRunCache(ServerFileSystem serverFileSystem, PropertiesDao propertiesDao, ResourceDao resourceDao, DryRunDatabaseFactory dryRunDatabaseFactory) {
-    this.serverFileSystem = serverFileSystem;
-    this.propertiesDao = propertiesDao;
-    this.resourceDao = resourceDao;
-    this.dryRunDatabaseFactory = dryRunDatabaseFactory;
-  }
-
-  public byte[] getDatabaseForDryRun(@Nullable Long projectId) {
-    long notNullProjectId = projectId != null ? projectId.longValue() : 0L;
-    ReadWriteLock rwl = getLock(notNullProjectId);
-    try {
-      rwl.readLock().lock();
-      if (!isCacheValid(projectId)) {
-        // upgrade lock manually
-        // must unlock first to obtain writelock
-        rwl.readLock().unlock();
-        rwl.writeLock().lock();
-        // recheck
-        if (!isCacheValid(projectId)) {
-          generateNewDB(projectId);
-        }
-        // downgrade lock
-        // reacquire read without giving up write lock
-        rwl.readLock().lock();
-        // unlock write, still hold read
-        rwl.writeLock().unlock();
-      }
-      File dbFile = new File(getCacheLocation(projectId), lastTimestampPerProject.get(notNullProjectId) + DryRunDatabaseFactory.H2_FILE_SUFFIX);
-      return fileToByte(dbFile);
-    } finally {
-      rwl.readLock().unlock();
-    }
-  }
-
-  private boolean isCacheValid(@Nullable Long projectId) {
-    long notNullProjectId = projectId != null ? projectId.longValue() : 0L;
-    Long lastTimestampInCache = lastTimestampPerProject.get(notNullProjectId);
-    LOG.debug("Timestamp of last cached DB is {}", lastTimestampInCache);
-    if (lastTimestampInCache != null && isValid(projectId, lastTimestampInCache.longValue())) {
-      File dbFile = new File(getCacheLocation(projectId), lastTimestampInCache + DryRunDatabaseFactory.H2_FILE_SUFFIX);
-      LOG.debug("Look for existence of cached DB at {}", dbFile);
-      if (dbFile.exists()) {
-        LOG.debug("Found cached DB at {}", dbFile);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private void generateNewDB(@Nullable Long projectId) {
-    if (projectId != null) {
-      LOG.debug("Generate new dryRun database for project [id={}]", projectId);
-    } else {
-      LOG.debug("Generate new dryRun database for new project");
-    }
-    long notNullProjectId = projectId != null ? projectId.longValue() : 0L;
-    long newTimestamp = System.currentTimeMillis();
-    File cacheLocation = getCacheLocation(projectId);
-    FileUtils.deleteQuietly(cacheLocation);
-    File dbFile = dryRunDatabaseFactory.createNewDatabaseForDryRun(projectId, cacheLocation, String.valueOf(newTimestamp));
-    LOG.debug("Cached DB at {}", dbFile);
-    lastTimestampPerProject.put(notNullProjectId, newTimestamp);
-  }
-
-  private byte[] fileToByte(File dbFile) {
-    try {
-      return Files.toByteArray(dbFile);
-    } catch (IOException e) {
-      throw new SonarException("Unable to create h2 database file", e);
-    }
-  }
-
-  private synchronized ReadWriteLock getLock(long notNullProjectId) {
-    if (!lockPerProject.containsKey(notNullProjectId)) {
-      lockPerProject.put(notNullProjectId, new ReentrantReadWriteLock(true));
-    }
-    return lockPerProject.get(notNullProjectId);
-  }
-
-  private File getRootCacheLocation() {
-    return new File(serverFileSystem.getTempDir(), "dryRun");
-  }
-
-  public File getCacheLocation(@Nullable Long projectId) {
-    return new File(getRootCacheLocation(), projectId != null ? projectId.toString() : "default");
-  }
-
-  private boolean isValid(@Nullable Long projectId, long lastTimestampInCache) {
-    long globalTimestamp = getModificationTimestamp(null);
-    if (globalTimestamp > lastTimestampInCache) {
-      return false;
-    }
-    if (projectId != null) {
-      long projectTimestamp = getModificationTimestamp(projectId);
-      if (projectTimestamp > lastTimestampInCache) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private long getModificationTimestamp(@Nullable Long projectId) {
-    if (projectId == null) {
-      PropertyDto dto = propertiesDao.selectGlobalProperty(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
-      if (dto == null) {
-        return 0;
-      }
-      return Long.valueOf(dto.getValue());
-    }
-    // For modules look for root project last modification timestamp
-    ResourceDto rootProject = resourceDao.getRootProjectByComponentId(projectId);
-    if (rootProject == null) {
-      throw new SonarException("Unable to find root project for project with [id=" + projectId + "]");
-    }
-    PropertyDto dto = propertiesDao.selectProjectProperty(rootProject.getId(), SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
-    if (dto == null) {
-      return 0;
-    }
-    return Long.valueOf(dto.getValue());
-  }
-
-  public void cleanAll() {
-    // Delete folder where dryRun DB are stored
-    FileUtils.deleteQuietly(getRootCacheLocation());
-    // Delete all lastUpdate properties to force generation of new DB
-    propertiesDao.deleteAllProperties(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
-  }
-
-  public void reportGlobalModification() {
-    propertiesDao.setProperty(new PropertyDto().setKey(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY).setValue(String.valueOf(System.currentTimeMillis())));
-  }
-
-  public void reportResourceModification(String resourceKey) {
-    ResourceDto rootProject = resourceDao.getRootProjectByComponentKey(resourceKey);
-    if (rootProject == null) {
-      throw new SonarException("Unable to find root project for component with [key=" + resourceKey + "]");
-    }
-    propertiesDao.setProperty(new PropertyDto().setKey(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY).setResourceId(rootProject.getId())
-      .setValue(String.valueOf(System.currentTimeMillis())));
-  }
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/dryrun/package-info.java b/sonar-core/src/main/java/org/sonar/core/dryrun/package-info.java
deleted file mode 100644 (file)
index fbdd95c..0000000
+++ /dev/null
@@ -1,24 +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.core.dryrun;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
index 202deabe441f2a8ee85e8fd60d1e566c1a612861..3e4ab3683efbb32bac11ba24ec00ae01c645f47d 100644 (file)
@@ -27,10 +27,13 @@ import org.apache.commons.lang.StringUtils;
 import org.hibernate.cfg.Environment;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.database.DatabaseProperties;
-import org.sonar.core.persistence.dialect.*;
+import org.sonar.core.persistence.dialect.Dialect;
+import org.sonar.core.persistence.dialect.DialectUtils;
+import org.sonar.core.persistence.dialect.H2;
+import org.sonar.core.persistence.dialect.Oracle;
+import org.sonar.core.persistence.dialect.PostgreSql;
 import org.sonar.jpa.session.CustomHibernateConnectionProvider;
 
 import javax.sql.DataSource;
@@ -104,16 +107,20 @@ public class DefaultDatabase implements Database {
   private void initDialect() {
     dialect = DialectUtils.find(properties.getProperty(SONAR_JDBC_DIALECT), properties.getProperty(SONAR_JDBC_URL));
     if (dialect == null) {
-      throw new IllegalStateException("Can not guess the JDBC dialect. Please check the property "+ SONAR_JDBC_URL + ".");
-    }
-    if (H2.ID.equals(dialect.getId()) && !settings.getBoolean(CoreProperties.DRY_RUN)) {
-      LoggerFactory.getLogger(DefaultDatabase.class).warn("H2 database should be used for evaluation purpose only");
+      throw new IllegalStateException("Can not guess the JDBC dialect. Please check the property " + SONAR_JDBC_URL + ".");
     }
+    checkH2Database();
     if (!properties.containsKey(SONAR_JDBC_DRIVER_CLASS_NAME)) {
       properties.setProperty(SONAR_JDBC_DRIVER_CLASS_NAME, dialect.getDefaultDriverClassName());
     }
   }
 
+  protected void checkH2Database() {
+    if (H2.ID.equals(dialect.getId())) {
+      LoggerFactory.getLogger(DefaultDatabase.class).warn("H2 database should be used for evaluation purpose only");
+    }
+  }
+
   private void initSchema() {
     String deprecatedSchema = null;
     if (PostgreSql.ID.equals(dialect.getId())) {
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DryRunDatabaseFactory.java b/sonar-core/src/main/java/org/sonar/core/persistence/DryRunDatabaseFactory.java
deleted file mode 100644 (file)
index 7820813..0000000
+++ /dev/null
@@ -1,170 +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.core.persistence;
-
-import org.apache.commons.dbcp.BasicDataSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.utils.SonarException;
-import org.sonar.core.source.SnapshotDataTypes;
-
-import javax.annotation.Nullable;
-import javax.sql.DataSource;
-
-import java.io.File;
-import java.sql.SQLException;
-
-public class DryRunDatabaseFactory implements ServerComponent {
-  private static final Logger LOG = LoggerFactory.getLogger(DryRunDatabaseFactory.class);
-  private static final String DIALECT = "h2";
-  private static final String DRIVER = "org.h2.Driver";
-  private static final String URL = "jdbc:h2:";
-  public static final String H2_FILE_SUFFIX = ".h2.db";
-  private static final String SONAR = "sonar";
-  private static final String USER = SONAR;
-  private static final String PASSWORD = SONAR;
-
-  private final Database database;
-
-  public DryRunDatabaseFactory(Database database) {
-    this.database = database;
-  }
-
-  public File createNewDatabaseForDryRun(Long projectId, File destFolder, String dbFileName) {
-    long startup = System.currentTimeMillis();
-
-    String h2Name = destFolder.getAbsolutePath() + File.separator + dbFileName;
-
-    try {
-      DataSource source = database.getDataSource();
-      BasicDataSource destination = create(DIALECT, DRIVER, USER, PASSWORD, URL + h2Name);
-
-      copy(source, destination, projectId);
-      close(destination);
-
-      File dbFile = new File(h2Name + H2_FILE_SUFFIX);
-      if (LOG.isDebugEnabled()) {
-        long size = dbFile.length();
-        long duration = System.currentTimeMillis() - startup;
-        if (projectId == null) {
-          LOG.debug("Dry Run Database created in " + duration + " ms, size is " + size + " bytes");
-        } else {
-          LOG.debug("Dry Run Database for project " + projectId + " created in " + duration + " ms, size is " + size + " bytes");
-        }
-      }
-      return dbFile;
-
-    } catch (SQLException e) {
-      throw new SonarException("Unable to create database for DryRun", e);
-    }
-
-  }
-
-  private void copy(DataSource source, DataSource dest, @Nullable Long projectId) {
-    DbTemplate template = new DbTemplate();
-    template
-      .copyTable(source, dest, "active_rules")
-      .copyTable(source, dest, "active_rule_parameters")
-      .copyTable(source, dest, "characteristics")
-      .copyTable(source, dest, "characteristic_edges")
-      .copyTable(source, dest, "characteristic_properties")
-      .copyTable(source, dest, "metrics")
-      .copyTable(source, dest, "permission_templates")
-      .copyTable(source, dest, "perm_templates_users")
-      .copyTable(source, dest, "perm_templates_groups")
-      .copyTable(source, dest, "quality_models")
-      .copyTable(source, dest, "rules")
-      .copyTable(source, dest, "rules_parameters")
-      .copyTable(source, dest, "rules_profiles")
-      .copyTable(source, dest, "alerts");
-    if (projectId != null) {
-      template.copyTable(source, dest, "projects", projectQuery(projectId, false));
-
-      template.copyTable(source, dest, "events", "SELECT * FROM events WHERE resource_id=" + projectId);
-
-      StringBuilder snapshotQuery = new StringBuilder()
-        // All snapshots of root_project for alerts on differential periods
-        .append("SELECT * FROM snapshots WHERE project_id=")
-        .append(projectId)
-        // Plus all last snapshots of all modules having hash data for partial analysis
-        .append(" UNION SELECT snap.* FROM snapshots snap")
-        .append(" INNER JOIN (")
-        .append(projectQuery(projectId, true))
-        .append(") res")
-        .append(" ON snap.project_id=res.id")
-        .append(" INNER JOIN snapshot_data data")
-        .append(" ON snap.id=data.snapshot_id")
-        .append(" AND data.data_type='").append(SnapshotDataTypes.FILE_HASHES).append("'")
-        .append(" AND snap.islast=").append(database.getDialect().getTrueSqlValue());
-      template.copyTable(source, dest, "snapshots", snapshotQuery.toString());
-
-      StringBuilder snapshotDataQuery = new StringBuilder()
-        .append("SELECT data.* FROM snapshot_data data")
-        .append(" INNER JOIN snapshots s")
-        .append(" ON s.id=data.snapshot_id")
-        .append(" AND s.islast=").append(database.getDialect().getTrueSqlValue())
-        .append(" INNER JOIN (")
-        .append(projectQuery(projectId, true))
-        .append(") res")
-        .append(" ON data.resource_id=res.id")
-        .append(" AND data.data_type='").append(SnapshotDataTypes.FILE_HASHES).append("'");
-      template.copyTable(source, dest, "snapshot_data", snapshotDataQuery.toString());
-
-      // All measures of snapshots of root project for alerts on differential periods
-      template.copyTable(source, dest, "project_measures", "SELECT m.* FROM project_measures m INNER JOIN snapshots s on m.snapshot_id=s.id "
-        + "WHERE s.project_id=" + projectId);
-
-      StringBuilder issueQuery = new StringBuilder()
-        .append("SELECT issues.* FROM issues")
-        .append(" INNER JOIN (")
-        .append(projectQuery(projectId, true))
-        .append(") resources")
-        .append(" ON issues.component_id=resources.id")
-        .append(" AND status <> '").append(Issue.STATUS_CLOSED).append("'");
-      template.copyTable(source, dest, "issues", issueQuery.toString());
-    }
-  }
-
-  private String projectQuery(Long projectId, boolean returnOnlyIds) {
-    return new StringBuilder()
-      .append("SELECT p.").append(returnOnlyIds ? "id" : "*")
-      .append(" FROM projects p INNER JOIN snapshots s ON p.id = s.project_id")
-      .append(" WHERE s.islast=").append(database.getDialect().getTrueSqlValue())
-      .append(" AND s.root_project_id=").append(projectId)
-      .append(" UNION")
-      .append(" SELECT p.").append(returnOnlyIds ? "id" : "*")
-      .append(" FROM projects p")
-      .append(" WHERE p.id=").append(projectId)
-      .append(" OR p.root_id=").append(projectId).toString();
-  }
-
-  private BasicDataSource create(String dialect, String driver, String user, String password, String url) {
-    BasicDataSource dataSource = new DbTemplate().dataSource(driver, user, password, url);
-    new DbTemplate().createSchema(dataSource, dialect);
-    return dataSource;
-  }
-
-  private void close(BasicDataSource destination) throws SQLException {
-    destination.close();
-  }
-
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/PreviewDatabaseFactory.java b/sonar-core/src/main/java/org/sonar/core/persistence/PreviewDatabaseFactory.java
new file mode 100644 (file)
index 0000000..032a58d
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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.core.persistence;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.utils.SonarException;
+import org.sonar.core.source.SnapshotDataTypes;
+
+import javax.annotation.Nullable;
+import javax.sql.DataSource;
+
+import java.io.File;
+import java.sql.SQLException;
+
+public class PreviewDatabaseFactory implements ServerComponent {
+  private static final Logger LOG = LoggerFactory.getLogger(PreviewDatabaseFactory.class);
+  private static final String DIALECT = "h2";
+  private static final String DRIVER = "org.h2.Driver";
+  private static final String URL = "jdbc:h2:";
+  public static final String H2_FILE_SUFFIX = ".h2.db";
+  private static final String SONAR = "sonar";
+  private static final String USER = SONAR;
+  private static final String PASSWORD = SONAR;
+
+  private final Database database;
+
+  public PreviewDatabaseFactory(Database database) {
+    this.database = database;
+  }
+
+  public File createNewDatabaseForDryRun(Long projectId, File destFolder, String dbFileName) {
+    long startup = System.currentTimeMillis();
+
+    String h2Name = destFolder.getAbsolutePath() + File.separator + dbFileName;
+
+    try {
+      DataSource source = database.getDataSource();
+      BasicDataSource destination = create(DIALECT, DRIVER, USER, PASSWORD, URL + h2Name);
+
+      copy(source, destination, projectId);
+      close(destination);
+
+      File dbFile = new File(h2Name + H2_FILE_SUFFIX);
+      if (LOG.isDebugEnabled()) {
+        long size = dbFile.length();
+        long duration = System.currentTimeMillis() - startup;
+        if (projectId == null) {
+          LOG.debug("Preview Database created in " + duration + " ms, size is " + size + " bytes");
+        } else {
+          LOG.debug("Preview Database for project " + projectId + " created in " + duration + " ms, size is " + size + " bytes");
+        }
+      }
+      return dbFile;
+
+    } catch (SQLException e) {
+      throw new SonarException("Unable to create database for DryRun", e);
+    }
+
+  }
+
+  private void copy(DataSource source, DataSource dest, @Nullable Long projectId) {
+    DbTemplate template = new DbTemplate();
+    template
+      .copyTable(source, dest, "active_rules")
+      .copyTable(source, dest, "active_rule_parameters")
+      .copyTable(source, dest, "characteristics")
+      .copyTable(source, dest, "characteristic_edges")
+      .copyTable(source, dest, "characteristic_properties")
+      .copyTable(source, dest, "metrics")
+      .copyTable(source, dest, "permission_templates")
+      .copyTable(source, dest, "perm_templates_users")
+      .copyTable(source, dest, "perm_templates_groups")
+      .copyTable(source, dest, "quality_models")
+      .copyTable(source, dest, "rules")
+      .copyTable(source, dest, "rules_parameters")
+      .copyTable(source, dest, "rules_profiles")
+      .copyTable(source, dest, "alerts");
+    if (projectId != null) {
+      template.copyTable(source, dest, "projects", projectQuery(projectId, false));
+
+      template.copyTable(source, dest, "events", "SELECT * FROM events WHERE resource_id=" + projectId);
+
+      StringBuilder snapshotQuery = new StringBuilder()
+        // All snapshots of root_project for alerts on differential periods
+        .append("SELECT * FROM snapshots WHERE project_id=")
+        .append(projectId)
+        // Plus all last snapshots of all modules having hash data for partial analysis
+        .append(" UNION SELECT snap.* FROM snapshots snap")
+        .append(" INNER JOIN (")
+        .append(projectQuery(projectId, true))
+        .append(") res")
+        .append(" ON snap.project_id=res.id")
+        .append(" INNER JOIN snapshot_data data")
+        .append(" ON snap.id=data.snapshot_id")
+        .append(" AND data.data_type='").append(SnapshotDataTypes.FILE_HASHES).append("'")
+        .append(" AND snap.islast=").append(database.getDialect().getTrueSqlValue());
+      template.copyTable(source, dest, "snapshots", snapshotQuery.toString());
+
+      StringBuilder snapshotDataQuery = new StringBuilder()
+        .append("SELECT data.* FROM snapshot_data data")
+        .append(" INNER JOIN snapshots s")
+        .append(" ON s.id=data.snapshot_id")
+        .append(" AND s.islast=").append(database.getDialect().getTrueSqlValue())
+        .append(" INNER JOIN (")
+        .append(projectQuery(projectId, true))
+        .append(") res")
+        .append(" ON data.resource_id=res.id")
+        .append(" AND data.data_type='").append(SnapshotDataTypes.FILE_HASHES).append("'");
+      template.copyTable(source, dest, "snapshot_data", snapshotDataQuery.toString());
+
+      // All measures of snapshots of root project for alerts on differential periods
+      template.copyTable(source, dest, "project_measures", "SELECT m.* FROM project_measures m INNER JOIN snapshots s on m.snapshot_id=s.id "
+        + "WHERE s.project_id=" + projectId);
+
+      StringBuilder issueQuery = new StringBuilder()
+        .append("SELECT issues.* FROM issues")
+        .append(" INNER JOIN (")
+        .append(projectQuery(projectId, true))
+        .append(") resources")
+        .append(" ON issues.component_id=resources.id")
+        .append(" AND status <> '").append(Issue.STATUS_CLOSED).append("'");
+      template.copyTable(source, dest, "issues", issueQuery.toString());
+    }
+  }
+
+  private String projectQuery(Long projectId, boolean returnOnlyIds) {
+    return new StringBuilder()
+      .append("SELECT p.").append(returnOnlyIds ? "id" : "*")
+      .append(" FROM projects p INNER JOIN snapshots s ON p.id = s.project_id")
+      .append(" WHERE s.islast=").append(database.getDialect().getTrueSqlValue())
+      .append(" AND s.root_project_id=").append(projectId)
+      .append(" UNION")
+      .append(" SELECT p.").append(returnOnlyIds ? "id" : "*")
+      .append(" FROM projects p")
+      .append(" WHERE p.id=").append(projectId)
+      .append(" OR p.root_id=").append(projectId).toString();
+  }
+
+  private BasicDataSource create(String dialect, String driver, String user, String password, String url) {
+    BasicDataSource dataSource = new DbTemplate().dataSource(driver, user, password, url);
+    new DbTemplate().createSchema(dataSource, dialect);
+    return dataSource;
+  }
+
+  private void close(BasicDataSource destination) throws SQLException {
+    destination.close();
+  }
+
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/preview/PreviewCache.java b/sonar-core/src/main/java/org/sonar/core/preview/PreviewCache.java
new file mode 100644 (file)
index 0000000..d12edcc
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * 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.core.preview;
+
+import com.google.common.io.Files;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.platform.ServerFileSystem;
+import org.sonar.api.utils.SonarException;
+import org.sonar.core.persistence.PreviewDatabaseFactory;
+import org.sonar.core.properties.PropertiesDao;
+import org.sonar.core.properties.PropertyDto;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+
+import javax.annotation.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * @since 3.7.1
+ */
+public class PreviewCache implements ServerExtension {
+
+  private static final Logger LOG = LoggerFactory.getLogger(PreviewCache.class);
+
+  public static final String SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY = "sonar.dryRun.cache.lastUpdate";
+
+  private ServerFileSystem serverFileSystem;
+  private PropertiesDao propertiesDao;
+  private ResourceDao resourceDao;
+
+  private Map<Long, ReadWriteLock> lockPerProject = new HashMap<Long, ReadWriteLock>();
+  private Map<Long, Long> lastTimestampPerProject = new HashMap<Long, Long>();
+
+  private PreviewDatabaseFactory previewDatabaseFactory;
+
+  public PreviewCache(ServerFileSystem serverFileSystem, PropertiesDao propertiesDao, ResourceDao resourceDao, PreviewDatabaseFactory previewDatabaseFactory) {
+    this.serverFileSystem = serverFileSystem;
+    this.propertiesDao = propertiesDao;
+    this.resourceDao = resourceDao;
+    this.previewDatabaseFactory = previewDatabaseFactory;
+  }
+
+  public byte[] getDatabaseForPreview(@Nullable Long projectId) {
+    long notNullProjectId = projectId != null ? projectId.longValue() : 0L;
+    ReadWriteLock rwl = getLock(notNullProjectId);
+    try {
+      rwl.readLock().lock();
+      if (!isCacheValid(projectId)) {
+        // upgrade lock manually
+        // must unlock first to obtain writelock
+        rwl.readLock().unlock();
+        rwl.writeLock().lock();
+        // recheck
+        if (!isCacheValid(projectId)) {
+          generateNewDB(projectId);
+        }
+        // downgrade lock
+        // reacquire read without giving up write lock
+        rwl.readLock().lock();
+        // unlock write, still hold read
+        rwl.writeLock().unlock();
+      }
+      File dbFile = new File(getCacheLocation(projectId), lastTimestampPerProject.get(notNullProjectId) + PreviewDatabaseFactory.H2_FILE_SUFFIX);
+      return fileToByte(dbFile);
+    } finally {
+      rwl.readLock().unlock();
+    }
+  }
+
+  private boolean isCacheValid(@Nullable Long projectId) {
+    long notNullProjectId = projectId != null ? projectId.longValue() : 0L;
+    Long lastTimestampInCache = lastTimestampPerProject.get(notNullProjectId);
+    LOG.debug("Timestamp of last cached DB is {}", lastTimestampInCache);
+    if (lastTimestampInCache != null && isValid(projectId, lastTimestampInCache.longValue())) {
+      File dbFile = new File(getCacheLocation(projectId), lastTimestampInCache + PreviewDatabaseFactory.H2_FILE_SUFFIX);
+      LOG.debug("Look for existence of cached DB at {}", dbFile);
+      if (dbFile.exists()) {
+        LOG.debug("Found cached DB at {}", dbFile);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private void generateNewDB(@Nullable Long projectId) {
+    if (projectId != null) {
+      LOG.debug("Generate new preview database for project [id={}]", projectId);
+    } else {
+      LOG.debug("Generate new preview database for new project");
+    }
+    long notNullProjectId = projectId != null ? projectId.longValue() : 0L;
+    long newTimestamp = System.currentTimeMillis();
+    File cacheLocation = getCacheLocation(projectId);
+    FileUtils.deleteQuietly(cacheLocation);
+    File dbFile = previewDatabaseFactory.createNewDatabaseForDryRun(projectId, cacheLocation, String.valueOf(newTimestamp));
+    LOG.debug("Cached DB at {}", dbFile);
+    lastTimestampPerProject.put(notNullProjectId, newTimestamp);
+  }
+
+  private byte[] fileToByte(File dbFile) {
+    try {
+      return Files.toByteArray(dbFile);
+    } catch (IOException e) {
+      throw new SonarException("Unable to create h2 database file", e);
+    }
+  }
+
+  private synchronized ReadWriteLock getLock(long notNullProjectId) {
+    if (!lockPerProject.containsKey(notNullProjectId)) {
+      lockPerProject.put(notNullProjectId, new ReentrantReadWriteLock(true));
+    }
+    return lockPerProject.get(notNullProjectId);
+  }
+
+  private File getRootCacheLocation() {
+    return new File(serverFileSystem.getTempDir(), "dryRun");
+  }
+
+  public File getCacheLocation(@Nullable Long projectId) {
+    return new File(getRootCacheLocation(), projectId != null ? projectId.toString() : "default");
+  }
+
+  private boolean isValid(@Nullable Long projectId, long lastTimestampInCache) {
+    long globalTimestamp = getModificationTimestamp(null);
+    if (globalTimestamp > lastTimestampInCache) {
+      return false;
+    }
+    if (projectId != null) {
+      long projectTimestamp = getModificationTimestamp(projectId);
+      if (projectTimestamp > lastTimestampInCache) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private long getModificationTimestamp(@Nullable Long projectId) {
+    if (projectId == null) {
+      PropertyDto dto = propertiesDao.selectGlobalProperty(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY);
+      if (dto == null) {
+        return 0;
+      }
+      return Long.valueOf(dto.getValue());
+    }
+    // For modules look for root project last modification timestamp
+    ResourceDto rootProject = resourceDao.getRootProjectByComponentId(projectId);
+    if (rootProject == null) {
+      throw new SonarException("Unable to find root project for project with [id=" + projectId + "]");
+    }
+    PropertyDto dto = propertiesDao.selectProjectProperty(rootProject.getId(), SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY);
+    if (dto == null) {
+      return 0;
+    }
+    return Long.valueOf(dto.getValue());
+  }
+
+  public void cleanAll() {
+    // Delete folder where preview DBs are stored
+    FileUtils.deleteQuietly(getRootCacheLocation());
+    // Delete all lastUpdate properties to force generation of new DB
+    propertiesDao.deleteAllProperties(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY);
+  }
+
+  public void reportGlobalModification() {
+    propertiesDao.setProperty(new PropertyDto().setKey(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY).setValue(String.valueOf(System.currentTimeMillis())));
+  }
+
+  public void reportResourceModification(String resourceKey) {
+    ResourceDto rootProject = resourceDao.getRootProjectByComponentKey(resourceKey);
+    if (rootProject == null) {
+      throw new SonarException("Unable to find root project for component with [key=" + resourceKey + "]");
+    }
+    propertiesDao.setProperty(new PropertyDto().setKey(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY).setResourceId(rootProject.getId())
+      .setValue(String.valueOf(System.currentTimeMillis())));
+  }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/preview/package-info.java b/sonar-core/src/main/java/org/sonar/core/preview/package-info.java
new file mode 100644 (file)
index 0000000..7dde324
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.core.preview;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-core/src/test/java/org/sonar/core/dryrun/DryRunCacheTest.java b/sonar-core/src/test/java/org/sonar/core/dryrun/DryRunCacheTest.java
deleted file mode 100644 (file)
index 935cc2a..0000000
+++ /dev/null
@@ -1,227 +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.core.dryrun;
-
-import org.apache.commons.io.FileUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.platform.ServerFileSystem;
-import org.sonar.core.persistence.DryRunDatabaseFactory;
-import org.sonar.core.properties.PropertiesDao;
-import org.sonar.core.properties.PropertyDto;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-
-import java.io.File;
-import java.io.IOException;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class DryRunCacheTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  private DryRunCache dryRunCache;
-  private ServerFileSystem serverFileSystem;
-  private PropertiesDao propertiesDao;
-  private ResourceDao resourceDao;
-
-  private DryRunDatabaseFactory dryRunDatabaseFactory;
-
-  private File dryRunCacheLocation;
-
-  @Before
-  public void prepare() throws IOException {
-    serverFileSystem = mock(ServerFileSystem.class);
-    propertiesDao = mock(PropertiesDao.class);
-    resourceDao = mock(ResourceDao.class);
-    dryRunDatabaseFactory = mock(DryRunDatabaseFactory.class);
-
-    File tempLocation = temp.newFolder();
-    when(serverFileSystem.getTempDir()).thenReturn(tempLocation);
-    dryRunCacheLocation = new File(tempLocation, "dryRun");
-
-    dryRunCache = new DryRunCache(serverFileSystem, propertiesDao, resourceDao, dryRunDatabaseFactory);
-  }
-
-  @Test
-  public void test_getDatabaseForDryRun_on_new_project() throws Exception {
-    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(isNull(Long.class), any(File.class), anyString())).thenAnswer(new Answer<File>() {
-      public File answer(InvocationOnMock invocation) throws IOException {
-        Object[] args = invocation.getArguments();
-        File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db");
-        FileUtils.write(dbFile, "fake db content");
-        return dbFile;
-      }
-    });
-    byte[] dbContent = dryRunCache.getDatabaseForDryRun(null);
-    assertThat(new String(dbContent)).isEqualTo("fake db content");
-
-    dbContent = dryRunCache.getDatabaseForDryRun(null);
-    assertThat(new String(dbContent)).isEqualTo("fake db content");
-
-    verify(dryRunDatabaseFactory, times(1)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
-  }
-
-  @Test
-  public void test_getDatabaseForDryRun_on_existing_project() throws Exception {
-    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(eq(123L), any(File.class), anyString())).thenAnswer(new Answer<File>() {
-      public File answer(InvocationOnMock invocation) throws IOException {
-        Object[] args = invocation.getArguments();
-        File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db");
-        FileUtils.write(dbFile, "fake db content");
-        return dbFile;
-      }
-    });
-    when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L));
-    byte[] dbContent = dryRunCache.getDatabaseForDryRun(123L);
-    assertThat(new String(dbContent)).isEqualTo("fake db content");
-
-    dbContent = dryRunCache.getDatabaseForDryRun(123L);
-    assertThat(new String(dbContent)).isEqualTo("fake db content");
-
-    verify(dryRunDatabaseFactory, times(1)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
-  }
-
-  @Test
-  public void test_getDatabaseForDryRun_global_invalidation() throws Exception {
-    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(isNull(Long.class), any(File.class), anyString()))
-      .thenAnswer(new Answer<File>() {
-        public File answer(InvocationOnMock invocation) throws IOException {
-          Object[] args = invocation.getArguments();
-          File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db");
-          FileUtils.write(dbFile, "fake db content 1");
-          return dbFile;
-        }
-      })
-      .thenAnswer(new Answer<File>() {
-        public File answer(InvocationOnMock invocation) throws IOException {
-          Object[] args = invocation.getArguments();
-          File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db");
-          FileUtils.write(dbFile, "fake db content 2");
-          return dbFile;
-        }
-      });
-    byte[] dbContent = dryRunCache.getDatabaseForDryRun(null);
-    assertThat(new String(dbContent)).isEqualTo("fake db content 1");
-
-    // Emulate invalidation of cache
-    Thread.sleep(100);
-    when(propertiesDao.selectGlobalProperty(DryRunCache.SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY)).thenReturn(new PropertyDto().setValue("" + System.currentTimeMillis()));
-
-    dbContent = dryRunCache.getDatabaseForDryRun(null);
-    assertThat(new String(dbContent)).isEqualTo("fake db content 2");
-
-    verify(dryRunDatabaseFactory, times(2)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
-  }
-
-  @Test
-  public void test_getDatabaseForDryRun_project_invalidation() throws Exception {
-    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(eq(123L), any(File.class), anyString()))
-      .thenAnswer(new Answer<File>() {
-        public File answer(InvocationOnMock invocation) throws IOException {
-          Object[] args = invocation.getArguments();
-          File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db");
-          FileUtils.write(dbFile, "fake db content 1");
-          return dbFile;
-        }
-      })
-      .thenAnswer(new Answer<File>() {
-        public File answer(InvocationOnMock invocation) throws IOException {
-          Object[] args = invocation.getArguments();
-          File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db");
-          FileUtils.write(dbFile, "fake db content 2");
-          return dbFile;
-        }
-      });
-    when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L));
-
-    byte[] dbContent = dryRunCache.getDatabaseForDryRun(123L);
-    assertThat(new String(dbContent)).isEqualTo("fake db content 1");
-
-    // Emulate invalidation of cache
-    Thread.sleep(100);
-    when(propertiesDao.selectProjectProperty(123L, DryRunCache.SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY)).thenReturn(new PropertyDto().setValue("" + System.currentTimeMillis()));
-
-    dbContent = dryRunCache.getDatabaseForDryRun(123L);
-    assertThat(new String(dbContent)).isEqualTo("fake db content 2");
-
-    verify(dryRunDatabaseFactory, times(2)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
-  }
-
-  @Test
-  public void test_get_cache_location() throws Exception {
-    File tempFolder = temp.newFolder();
-    when(serverFileSystem.getTempDir()).thenReturn(tempFolder);
-
-    assertThat(dryRunCache.getCacheLocation(null)).isEqualTo(new File(new File(tempFolder, "dryRun"), "default"));
-    assertThat(dryRunCache.getCacheLocation(123L)).isEqualTo(new File(new File(tempFolder, "dryRun"), "123"));
-  }
-
-  @Test
-  public void test_clean_all() throws Exception {
-    File tempFolder = temp.newFolder();
-    when(serverFileSystem.getTempDir()).thenReturn(tempFolder);
-    File cacheLocation = dryRunCache.getCacheLocation(null);
-    FileUtils.forceMkdir(cacheLocation);
-
-    dryRunCache.cleanAll();
-    verify(propertiesDao).deleteAllProperties(DryRunCache.SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
-
-    assertThat(cacheLocation).doesNotExist();
-  }
-
-  @Test
-  public void test_report_global_modification() {
-    dryRunCache.reportGlobalModification();
-
-    verify(propertiesDao).setProperty(
-      new PropertyDto()
-        .setKey(DryRunCache.SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY)
-        .setValue(anyString()));
-  }
-
-  @Test
-  public void test_report_resource_modification() {
-    when(resourceDao.getRootProjectByComponentKey("foo")).thenReturn(new ResourceDto().setId(456L));
-
-    dryRunCache.reportResourceModification("foo");
-
-    verify(propertiesDao).setProperty(
-      new PropertyDto()
-        .setKey(DryRunCache.SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY)
-        .setValue(anyString())
-        .setResourceId(456L));
-  }
-}
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/DryRunDatabaseFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/DryRunDatabaseFactoryTest.java
deleted file mode 100644 (file)
index e5389e9..0000000
+++ /dev/null
@@ -1,154 +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.core.persistence;
-
-import com.google.common.io.Files;
-import org.apache.commons.dbcp.BasicDataSource;
-import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-import java.io.IOException;
-import java.sql.SQLException;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DryRunDatabaseFactoryTest extends AbstractDaoTestCase {
-  DryRunDatabaseFactory localDatabaseFactory;
-  BasicDataSource dataSource;
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Before
-  public void setUp() throws Exception {
-    localDatabaseFactory = new DryRunDatabaseFactory(getDatabase());
-  }
-
-  @After
-  public void closeDatabase() throws SQLException {
-    if (dataSource != null) {
-      dataSource.close();
-    }
-  }
-
-  @Test
-  public void should_create_database_without_project() throws Exception {
-    setupData("should_create_database");
-
-    byte[] db = createDb(null);
-    dataSource = createDatabase(db);
-
-    assertThat(rowCount("metrics")).isEqualTo(2);
-    assertThat(rowCount("projects")).isZero();
-    assertThat(rowCount("alerts")).isEqualTo(1);
-    assertThat(rowCount("events")).isZero();
-  }
-
-  private byte[] createDb(Long projectId) throws IOException {
-    return FileUtils.readFileToByteArray(localDatabaseFactory.createNewDatabaseForDryRun(projectId, temporaryFolder.newFolder(), "foo"));
-  }
-
-  @Test
-  public void should_create_database_with_project() throws Exception {
-    setupData("should_create_database");
-
-    byte[] database = createDb(123L);
-    dataSource = createDatabase(database);
-
-    assertThat(rowCount("metrics")).isEqualTo(2);
-    assertThat(rowCount("projects")).isEqualTo(1);
-    assertThat(rowCount("snapshots")).isEqualTo(1);
-    assertThat(rowCount("project_measures")).isEqualTo(1);
-    assertThat(rowCount("events")).isEqualTo(2);
-  }
-
-  @Test
-  public void should_create_database_with_issues() throws Exception {
-    setupData("should_create_database_with_issues");
-
-    byte[] database = createDb(399L);
-    dataSource = createDatabase(database);
-
-    assertThat(rowCount("issues")).isEqualTo(1);
-  }
-
-  @Test
-  public void should_export_issues_of_project_tree() throws Exception {
-    setupData("multi-modules-with-issues");
-
-    // 300 : root module -> export issues of all modules
-    byte[] database = createDb(300L);
-    dataSource = createDatabase(database);
-    assertThat(rowCount("issues")).isEqualTo(1);
-    assertThat(rowCount("projects")).isEqualTo(4);
-    assertThat(rowCount("snapshots")).isEqualTo(4);
-    assertThat(rowCount("snapshot_data")).isEqualTo(2);
-    assertThat(rowCount("project_measures")).isEqualTo(4);
-  }
-
-  @Test
-  public void should_export_issues_of_sub_module() throws Exception {
-    setupData("multi-modules-with-issues");
-
-    // 301 : sub module with 1 closed issue and 1 open issue
-    byte[] database = createDb(301L);
-    dataSource = createDatabase(database);
-    assertThat(rowCount("issues")).isEqualTo(1);
-    assertThat(rowCount("projects")).isEqualTo(2);
-    assertThat(rowCount("snapshots")).isEqualTo(2);
-    assertThat(rowCount("project_measures")).isEqualTo(4);
-  }
-
-  @Test
-  public void should_export_issues_of_sub_module_2() throws Exception {
-    setupData("multi-modules-with-issues");
-
-    // 302 : sub module without any issues
-    byte[] database = createDb(302L);
-    dataSource = createDatabase(database);
-    assertThat(rowCount("issues")).isEqualTo(0);
-  }
-
-  @Test
-  public void should_copy_permission_templates_data() throws Exception {
-    setupData("should_copy_permission_templates");
-
-    byte[] database = createDb(null);
-    dataSource = createDatabase(database);
-    assertThat(rowCount("permission_templates")).isEqualTo(1);
-    assertThat(rowCount("perm_templates_users")).isEqualTo(1);
-    assertThat(rowCount("perm_templates_groups")).isEqualTo(1);
-  }
-
-  private BasicDataSource createDatabase(byte[] db) throws IOException {
-    File file = temporaryFolder.newFile("db.h2.db");
-    Files.write(db, file);
-    return new DbTemplate().dataSource("org.h2.Driver", "sonar", "sonar", "jdbc:h2:" + file.getAbsolutePath().replaceAll(".h2.db", ""));
-  }
-
-  private int rowCount(String table) {
-    return new DbTemplate().getRowCount(dataSource, table);
-  }
-}
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/PreviewDatabaseFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/PreviewDatabaseFactoryTest.java
new file mode 100644 (file)
index 0000000..d144f94
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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.core.persistence;
+
+import com.google.common.io.Files;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PreviewDatabaseFactoryTest extends AbstractDaoTestCase {
+  PreviewDatabaseFactory localDatabaseFactory;
+  BasicDataSource dataSource;
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Before
+  public void setUp() throws Exception {
+    localDatabaseFactory = new PreviewDatabaseFactory(getDatabase());
+  }
+
+  @After
+  public void closeDatabase() throws SQLException {
+    if (dataSource != null) {
+      dataSource.close();
+    }
+  }
+
+  @Test
+  public void should_create_database_without_project() throws Exception {
+    setupData("should_create_database");
+
+    byte[] db = createDb(null);
+    dataSource = createDatabase(db);
+
+    assertThat(rowCount("metrics")).isEqualTo(2);
+    assertThat(rowCount("projects")).isZero();
+    assertThat(rowCount("alerts")).isEqualTo(1);
+    assertThat(rowCount("events")).isZero();
+  }
+
+  private byte[] createDb(Long projectId) throws IOException {
+    return FileUtils.readFileToByteArray(localDatabaseFactory.createNewDatabaseForDryRun(projectId, temporaryFolder.newFolder(), "foo"));
+  }
+
+  @Test
+  public void should_create_database_with_project() throws Exception {
+    setupData("should_create_database");
+
+    byte[] database = createDb(123L);
+    dataSource = createDatabase(database);
+
+    assertThat(rowCount("metrics")).isEqualTo(2);
+    assertThat(rowCount("projects")).isEqualTo(1);
+    assertThat(rowCount("snapshots")).isEqualTo(1);
+    assertThat(rowCount("project_measures")).isEqualTo(1);
+    assertThat(rowCount("events")).isEqualTo(2);
+  }
+
+  @Test
+  public void should_create_database_with_issues() throws Exception {
+    setupData("should_create_database_with_issues");
+
+    byte[] database = createDb(399L);
+    dataSource = createDatabase(database);
+
+    assertThat(rowCount("issues")).isEqualTo(1);
+  }
+
+  @Test
+  public void should_export_issues_of_project_tree() throws Exception {
+    setupData("multi-modules-with-issues");
+
+    // 300 : root module -> export issues of all modules
+    byte[] database = createDb(300L);
+    dataSource = createDatabase(database);
+    assertThat(rowCount("issues")).isEqualTo(1);
+    assertThat(rowCount("projects")).isEqualTo(4);
+    assertThat(rowCount("snapshots")).isEqualTo(4);
+    assertThat(rowCount("snapshot_data")).isEqualTo(2);
+    assertThat(rowCount("project_measures")).isEqualTo(4);
+  }
+
+  @Test
+  public void should_export_issues_of_sub_module() throws Exception {
+    setupData("multi-modules-with-issues");
+
+    // 301 : sub module with 1 closed issue and 1 open issue
+    byte[] database = createDb(301L);
+    dataSource = createDatabase(database);
+    assertThat(rowCount("issues")).isEqualTo(1);
+    assertThat(rowCount("projects")).isEqualTo(2);
+    assertThat(rowCount("snapshots")).isEqualTo(2);
+    assertThat(rowCount("project_measures")).isEqualTo(4);
+  }
+
+  @Test
+  public void should_export_issues_of_sub_module_2() throws Exception {
+    setupData("multi-modules-with-issues");
+
+    // 302 : sub module without any issues
+    byte[] database = createDb(302L);
+    dataSource = createDatabase(database);
+    assertThat(rowCount("issues")).isEqualTo(0);
+  }
+
+  @Test
+  public void should_copy_permission_templates_data() throws Exception {
+    setupData("should_copy_permission_templates");
+
+    byte[] database = createDb(null);
+    dataSource = createDatabase(database);
+    assertThat(rowCount("permission_templates")).isEqualTo(1);
+    assertThat(rowCount("perm_templates_users")).isEqualTo(1);
+    assertThat(rowCount("perm_templates_groups")).isEqualTo(1);
+  }
+
+  private BasicDataSource createDatabase(byte[] db) throws IOException {
+    File file = temporaryFolder.newFile("db.h2.db");
+    Files.write(db, file);
+    return new DbTemplate().dataSource("org.h2.Driver", "sonar", "sonar", "jdbc:h2:" + file.getAbsolutePath().replaceAll(".h2.db", ""));
+  }
+
+  private int rowCount(String table) {
+    return new DbTemplate().getRowCount(dataSource, table);
+  }
+}
diff --git a/sonar-core/src/test/java/org/sonar/core/preview/PreviewCacheTest.java b/sonar-core/src/test/java/org/sonar/core/preview/PreviewCacheTest.java
new file mode 100644 (file)
index 0000000..b274436
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * 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.core.preview;
+
+import org.sonar.core.preview.PreviewCache;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.sonar.api.platform.ServerFileSystem;
+import org.sonar.core.persistence.PreviewDatabaseFactory;
+import org.sonar.core.properties.PropertiesDao;
+import org.sonar.core.properties.PropertyDto;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class PreviewCacheTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  private PreviewCache dryRunCache;
+  private ServerFileSystem serverFileSystem;
+  private PropertiesDao propertiesDao;
+  private ResourceDao resourceDao;
+
+  private PreviewDatabaseFactory dryRunDatabaseFactory;
+
+  private File dryRunCacheLocation;
+
+  @Before
+  public void prepare() throws IOException {
+    serverFileSystem = mock(ServerFileSystem.class);
+    propertiesDao = mock(PropertiesDao.class);
+    resourceDao = mock(ResourceDao.class);
+    dryRunDatabaseFactory = mock(PreviewDatabaseFactory.class);
+
+    File tempLocation = temp.newFolder();
+    when(serverFileSystem.getTempDir()).thenReturn(tempLocation);
+    dryRunCacheLocation = new File(tempLocation, "dryRun");
+
+    dryRunCache = new PreviewCache(serverFileSystem, propertiesDao, resourceDao, dryRunDatabaseFactory);
+  }
+
+  @Test
+  public void test_getDatabaseForDryRun_on_new_project() throws Exception {
+    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(isNull(Long.class), any(File.class), anyString())).thenAnswer(new Answer<File>() {
+      public File answer(InvocationOnMock invocation) throws IOException {
+        Object[] args = invocation.getArguments();
+        File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db");
+        FileUtils.write(dbFile, "fake db content");
+        return dbFile;
+      }
+    });
+    byte[] dbContent = dryRunCache.getDatabaseForPreview(null);
+    assertThat(new String(dbContent)).isEqualTo("fake db content");
+
+    dbContent = dryRunCache.getDatabaseForPreview(null);
+    assertThat(new String(dbContent)).isEqualTo("fake db content");
+
+    verify(dryRunDatabaseFactory, times(1)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
+  }
+
+  @Test
+  public void test_getDatabaseForDryRun_on_existing_project() throws Exception {
+    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(eq(123L), any(File.class), anyString())).thenAnswer(new Answer<File>() {
+      public File answer(InvocationOnMock invocation) throws IOException {
+        Object[] args = invocation.getArguments();
+        File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db");
+        FileUtils.write(dbFile, "fake db content");
+        return dbFile;
+      }
+    });
+    when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L));
+    byte[] dbContent = dryRunCache.getDatabaseForPreview(123L);
+    assertThat(new String(dbContent)).isEqualTo("fake db content");
+
+    dbContent = dryRunCache.getDatabaseForPreview(123L);
+    assertThat(new String(dbContent)).isEqualTo("fake db content");
+
+    verify(dryRunDatabaseFactory, times(1)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
+  }
+
+  @Test
+  public void test_getDatabaseForDryRun_global_invalidation() throws Exception {
+    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(isNull(Long.class), any(File.class), anyString()))
+      .thenAnswer(new Answer<File>() {
+        public File answer(InvocationOnMock invocation) throws IOException {
+          Object[] args = invocation.getArguments();
+          File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db");
+          FileUtils.write(dbFile, "fake db content 1");
+          return dbFile;
+        }
+      })
+      .thenAnswer(new Answer<File>() {
+        public File answer(InvocationOnMock invocation) throws IOException {
+          Object[] args = invocation.getArguments();
+          File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db");
+          FileUtils.write(dbFile, "fake db content 2");
+          return dbFile;
+        }
+      });
+    byte[] dbContent = dryRunCache.getDatabaseForPreview(null);
+    assertThat(new String(dbContent)).isEqualTo("fake db content 1");
+
+    // Emulate invalidation of cache
+    Thread.sleep(100);
+    when(propertiesDao.selectGlobalProperty(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY)).thenReturn(new PropertyDto().setValue("" + System.currentTimeMillis()));
+
+    dbContent = dryRunCache.getDatabaseForPreview(null);
+    assertThat(new String(dbContent)).isEqualTo("fake db content 2");
+
+    verify(dryRunDatabaseFactory, times(2)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
+  }
+
+  @Test
+  public void test_getDatabaseForDryRun_project_invalidation() throws Exception {
+    when(dryRunDatabaseFactory.createNewDatabaseForDryRun(eq(123L), any(File.class), anyString()))
+      .thenAnswer(new Answer<File>() {
+        public File answer(InvocationOnMock invocation) throws IOException {
+          Object[] args = invocation.getArguments();
+          File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db");
+          FileUtils.write(dbFile, "fake db content 1");
+          return dbFile;
+        }
+      })
+      .thenAnswer(new Answer<File>() {
+        public File answer(InvocationOnMock invocation) throws IOException {
+          Object[] args = invocation.getArguments();
+          File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db");
+          FileUtils.write(dbFile, "fake db content 2");
+          return dbFile;
+        }
+      });
+    when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L));
+
+    byte[] dbContent = dryRunCache.getDatabaseForPreview(123L);
+    assertThat(new String(dbContent)).isEqualTo("fake db content 1");
+
+    // Emulate invalidation of cache
+    Thread.sleep(100);
+    when(propertiesDao.selectProjectProperty(123L, PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY)).thenReturn(new PropertyDto().setValue("" + System.currentTimeMillis()));
+
+    dbContent = dryRunCache.getDatabaseForPreview(123L);
+    assertThat(new String(dbContent)).isEqualTo("fake db content 2");
+
+    verify(dryRunDatabaseFactory, times(2)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString());
+  }
+
+  @Test
+  public void test_get_cache_location() throws Exception {
+    File tempFolder = temp.newFolder();
+    when(serverFileSystem.getTempDir()).thenReturn(tempFolder);
+
+    assertThat(dryRunCache.getCacheLocation(null)).isEqualTo(new File(new File(tempFolder, "dryRun"), "default"));
+    assertThat(dryRunCache.getCacheLocation(123L)).isEqualTo(new File(new File(tempFolder, "dryRun"), "123"));
+  }
+
+  @Test
+  public void test_clean_all() throws Exception {
+    File tempFolder = temp.newFolder();
+    when(serverFileSystem.getTempDir()).thenReturn(tempFolder);
+    File cacheLocation = dryRunCache.getCacheLocation(null);
+    FileUtils.forceMkdir(cacheLocation);
+
+    dryRunCache.cleanAll();
+    verify(propertiesDao).deleteAllProperties(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY);
+
+    assertThat(cacheLocation).doesNotExist();
+  }
+
+  @Test
+  public void test_report_global_modification() {
+    dryRunCache.reportGlobalModification();
+
+    verify(propertiesDao).setProperty(
+      new PropertyDto()
+        .setKey(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY)
+        .setValue(anyString()));
+  }
+
+  @Test
+  public void test_report_resource_modification() {
+    when(resourceDao.getRootProjectByComponentKey("foo")).thenReturn(new ResourceDto().setId(456L));
+
+    dryRunCache.reportResourceModification("foo");
+
+    verify(propertiesDao).setProperty(
+      new PropertyDto()
+        .setKey(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY)
+        .setValue(anyString())
+        .setResourceId(456L));
+  }
+}
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/multi-modules-with-issues.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/multi-modules-with-issues.xml
deleted file mode 100644 (file)
index d558386..0000000
+++ /dev/null
@@ -1,128 +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.
-  -->
-<dataset>
-  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="[false]" delete_historical_data="[null]"/>
-  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" hidden="[false]" delete_historical_data="[null]"/>
-
-  <rules_profiles id="1" name="Sonar way with Findbugs" language="java" parent_name="" version="1"
-                  used_profile="[false]"/>
-
-  <projects id="300" kee="struts" root_id="[null]" qualifier="TRK" scope="PRJ" />
-  <projects id="301" kee="struts-core" root_id="300" qualifier="BRC" scope="PRJ" />
-  <projects id="302" kee="struts-el" root_id="300" qualifier="BRC" scope="PRJ" />
-  <projects id="303" kee="Action.java" root_id="301" qualifier="CLA" scope="FIL" />
-
-  <snapshots id="3000" project_id="300" root_project_id="300" root_snapshot_id="[null]" path="" islast="[true]"/>
-  <snapshots id="3001" project_id="301" root_project_id="300" root_snapshot_id="3000" path="3000." islast="[true]"/>
-  <snapshots id="3002" project_id="302" root_project_id="300" root_snapshot_id="3000" path="3000." islast="[true]"/>
-  <snapshots id="3003" project_id="303" root_project_id="300" root_snapshot_id="3000" path="3000.3001." islast="[true]"/>
-
-  <snapshots id="3010" project_id="300" root_project_id="300" root_snapshot_id="[null]" path="" islast="[false]"/>
-  <snapshots id="3011" project_id="301" root_project_id="300" root_snapshot_id="3010" path="3010." islast="[false]"/>
-  <snapshots id="3012" project_id="302" root_project_id="300" root_snapshot_id="3010" path="3010." islast="[false]"/>
-  <snapshots id="3013" project_id="303" root_project_id="300" root_snapshot_id="3010" path="3010.3011." islast="[false]"/>
-
-  <snapshot_data id="1" snapshot_id="3001" resource_id="301" snapshot_data="foo=AB12" data_type="file_hashes" />
-  <snapshot_data id="2" snapshot_id="3001" resource_id="301" snapshot_data="bar" data_type="other" />
-  <snapshot_data id="3" snapshot_id="3002" resource_id="302" snapshot_data="bar=DC12" data_type="file_hashes" />
-
-  <snapshot_data id="4" snapshot_id="3011" resource_id="301" snapshot_data="foo=CD34" data_type="file_hashes" />
-  <snapshot_data id="5" snapshot_id="3012" resource_id="302" snapshot_data="bar=EF78" data_type="file_hashes" />
-
-  <project_measures id="1" value="12" metric_id="1" snapshot_id="3000" />
-  <project_measures id="2" value="5" metric_id="1" snapshot_id="3001" />
-  <project_measures id="3" value="7" metric_id="1" snapshot_id="3002" />
-  <project_measures id="4" value="5" metric_id="1" snapshot_id="3003" />
-
-  <project_measures id="5" value="35" metric_id="2" snapshot_id="3000" />
-  <project_measures id="6" value="20" metric_id="2" snapshot_id="3001" />
-  <project_measures id="7" value="30" metric_id="2" snapshot_id="3002" />
-  <project_measures id="8" value="20" metric_id="2" snapshot_id="3003" />
-
-  <project_measures id="11" value="112" metric_id="1" snapshot_id="3010" />
-  <project_measures id="12" value="15" metric_id="1" snapshot_id="3011" />
-  <project_measures id="13" value="17" metric_id="1" snapshot_id="3012" />
-  <project_measures id="14" value="15" metric_id="1" snapshot_id="3013" />
-
-  <project_measures id="15" value="135" metric_id="2" snapshot_id="3010" />
-  <project_measures id="16" value="120" metric_id="2" snapshot_id="3011" />
-  <project_measures id="17" value="130" metric_id="2" snapshot_id="3012" />
-  <project_measures id="18" value="120" metric_id="2" snapshot_id="3013" />
-
-
-  <rules id="500" plugin_rule_key="AvoidCycle" plugin_name="squid"/>
-  <rules id="501" plugin_rule_key="NullRef" plugin_name="squid"/>
-
-  <!-- issues in module -->
-  <issues
-      id="100"
-      kee="ISSUE-100"
-      component_id="303"
-      root_component_id="300"
-
-      rule_id="500"
-      severity="BLOCKER"
-      manual_severity="[false]"
-      message="[null]"
-      line="200"
-      effort_to_fix="[null]"
-      status="OPEN"
-      resolution="[null]"
-      checksum="[null]"
-      reporter="user"
-      assignee="user"
-      author_login="[null]"
-      issue_attributes="[null]"
-      issue_creation_date="2013-04-16"
-      issue_update_date="2013-04-16"
-      issue_close_date="2013-04-16"
-      created_at="[null]"
-      updated_at="[null]"
-      />
-
-  <issues
-      id="101"
-      kee="ISSUE-101"
-      component_id="303"
-      root_component_id="300"
-
-      rule_id="501"
-      severity="MAJOR"
-      manual_severity="[false]"
-      message="[null]"
-      line="120"
-      effort_to_fix="[null]"
-      status="CLOSED"
-      resolution="FIXED"
-      checksum="[null]"
-      reporter="[null]"
-      assignee="user"
-      author_login="[null]"
-      issue_attributes="[null]"
-      issue_creation_date="2013-04-16"
-      issue_update_date="2013-04-16"
-      issue_close_date="2013-04-16"
-      created_at="[null]"
-      updated_at="[null]"
-      />
-
-</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_copy_permission_templates.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_copy_permission_templates.xml
deleted file mode 100644 (file)
index 6bead9e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<dataset>
-
-  <permission_templates id="1" name="my template" kee="my_template_20130101_010203" description="my description"/>
-
-  <perm_templates_users id="1" template_id="1" user_id="1" permission_reference="codeviewer"/>
-
-  <perm_templates_groups id="1" template_id="1" group_id="1" permission_reference="admin"/>
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_create_database.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_create_database.xml
deleted file mode 100644 (file)
index 008976f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-<dataset>
-  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="[false]" delete_historical_data="[null]"/>
-  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" hidden="[false]" delete_historical_data="[null]"/>
-
-  <rules_profiles id="1" name="Sonar way with Findbugs" language="java" parent_name="" version="1"
-                  used_profile="[false]"/>
-
-
-  <projects id="123" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
-            description="[null]" long_name="Apache Struts"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="2013-01-25 02:04:06.00"/>
-
-  <snapshots id="1000" project_id="123" root_project_id="123" root_snapshot_id="1000" parent_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" path="1000." depth="1"
-             purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]"
-             period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]"
-             period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             created_at="2013-01-25 02:04:06.00" build_date="2013-01-25 02:04:06.00"
-             version="1.0" status="P" islast="[true]"/>
-
-  <alerts id="1" profile_id="1" metric_id="1" operator="lt" value_error="5" value_warning="" period="[null]"/>
-
-  <project_measures id="1" value="10" metric_id="1" snapshot_id="1000" />
-
-  <events id="1" name="1.0-SNAPSHOT" resource_id="123" />
-  <events id="2" name="2.0-SNAPSHOT" resource_id="123" />
-  <events id="3" name="1.0-SNAPSHOT" resource_id="456" />
-
-</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_create_database_with_issues.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/DryRunDatabaseFactoryTest/should_create_database_with_issues.xml
deleted file mode 100644 (file)
index d25ce65..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<dataset>
-  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="[false]" delete_historical_data="[null]"/>
-  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" hidden="[false]" delete_historical_data="[null]"/>
-
-  <rules_profiles id="1" name="Sonar way with Findbugs" language="java" parent_name="" version="1"
-                  used_profile="[false]"/>
-
-  <projects id="399" kee="struts" root_id="[null]"/>
-  <projects id="400" kee="Action.java" root_id="399"/>
-  <projects id="401" kee="Filter.java" root_id="399"/>
-
-  <snapshots id="100" project_id="399" root_snapshot_id="[null]" path="" islast="[true]"/>
-  <snapshots id="101" project_id="400" root_snapshot_id="100" path="100." islast="[true]"/>
-  <snapshots id="102" project_id="401" root_snapshot_id="100" path="100." islast="[true]"/>
-
-  <rules id="500" plugin_rule_key="AvoidCycle" plugin_name="squid"/>
-  <rules id="501" plugin_rule_key="NullRef" plugin_name="squid"/>
-
-  <issues
-      id="100"
-      kee="100"
-      component_id="400"
-      rule_id="500"
-      severity="BLOCKER"
-      manual_severity="[false]"
-      message="[null]"
-      line="200"
-      effort_to_fix="[null]"
-      status="OPEN"
-      resolution="[null]"
-      checksum="[null]"
-      reporter="user"
-      assignee="user"
-      author_login="[null]"
-      issue_attributes="[null]"
-      issue_creation_date="2013-04-16"
-      issue_update_date="2013-04-16"
-      issue_close_date="2013-04-16"
-      created_at="[null]"
-      updated_at="[null]"
-      />
-
-  <issues
-      id="101"
-      kee="101"
-      component_id="401"
-      rule_id="501"
-      severity="MAJOR"
-      manual_severity="[false]"
-      message="[null]"
-      line="120"
-      effort_to_fix="[null]"
-      status="CLOSED"
-      resolution="FIXED"
-      checksum="[null]"
-      reporter="[null]"
-      assignee="user"
-      author_login="[null]"
-      issue_attributes="[null]"
-      issue_creation_date="2013-04-16"
-      issue_update_date="2013-04-16"
-      issue_close_date="2013-04-16"
-      created_at="[null]"
-      updated_at="[null]"
-      />
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/multi-modules-with-issues.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/multi-modules-with-issues.xml
new file mode 100644 (file)
index 0000000..d558386
--- /dev/null
@@ -0,0 +1,128 @@
+<!--
+  ~ 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.
+  -->
+<dataset>
+  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="[false]" delete_historical_data="[null]"/>
+  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" hidden="[false]" delete_historical_data="[null]"/>
+
+  <rules_profiles id="1" name="Sonar way with Findbugs" language="java" parent_name="" version="1"
+                  used_profile="[false]"/>
+
+  <projects id="300" kee="struts" root_id="[null]" qualifier="TRK" scope="PRJ" />
+  <projects id="301" kee="struts-core" root_id="300" qualifier="BRC" scope="PRJ" />
+  <projects id="302" kee="struts-el" root_id="300" qualifier="BRC" scope="PRJ" />
+  <projects id="303" kee="Action.java" root_id="301" qualifier="CLA" scope="FIL" />
+
+  <snapshots id="3000" project_id="300" root_project_id="300" root_snapshot_id="[null]" path="" islast="[true]"/>
+  <snapshots id="3001" project_id="301" root_project_id="300" root_snapshot_id="3000" path="3000." islast="[true]"/>
+  <snapshots id="3002" project_id="302" root_project_id="300" root_snapshot_id="3000" path="3000." islast="[true]"/>
+  <snapshots id="3003" project_id="303" root_project_id="300" root_snapshot_id="3000" path="3000.3001." islast="[true]"/>
+
+  <snapshots id="3010" project_id="300" root_project_id="300" root_snapshot_id="[null]" path="" islast="[false]"/>
+  <snapshots id="3011" project_id="301" root_project_id="300" root_snapshot_id="3010" path="3010." islast="[false]"/>
+  <snapshots id="3012" project_id="302" root_project_id="300" root_snapshot_id="3010" path="3010." islast="[false]"/>
+  <snapshots id="3013" project_id="303" root_project_id="300" root_snapshot_id="3010" path="3010.3011." islast="[false]"/>
+
+  <snapshot_data id="1" snapshot_id="3001" resource_id="301" snapshot_data="foo=AB12" data_type="file_hashes" />
+  <snapshot_data id="2" snapshot_id="3001" resource_id="301" snapshot_data="bar" data_type="other" />
+  <snapshot_data id="3" snapshot_id="3002" resource_id="302" snapshot_data="bar=DC12" data_type="file_hashes" />
+
+  <snapshot_data id="4" snapshot_id="3011" resource_id="301" snapshot_data="foo=CD34" data_type="file_hashes" />
+  <snapshot_data id="5" snapshot_id="3012" resource_id="302" snapshot_data="bar=EF78" data_type="file_hashes" />
+
+  <project_measures id="1" value="12" metric_id="1" snapshot_id="3000" />
+  <project_measures id="2" value="5" metric_id="1" snapshot_id="3001" />
+  <project_measures id="3" value="7" metric_id="1" snapshot_id="3002" />
+  <project_measures id="4" value="5" metric_id="1" snapshot_id="3003" />
+
+  <project_measures id="5" value="35" metric_id="2" snapshot_id="3000" />
+  <project_measures id="6" value="20" metric_id="2" snapshot_id="3001" />
+  <project_measures id="7" value="30" metric_id="2" snapshot_id="3002" />
+  <project_measures id="8" value="20" metric_id="2" snapshot_id="3003" />
+
+  <project_measures id="11" value="112" metric_id="1" snapshot_id="3010" />
+  <project_measures id="12" value="15" metric_id="1" snapshot_id="3011" />
+  <project_measures id="13" value="17" metric_id="1" snapshot_id="3012" />
+  <project_measures id="14" value="15" metric_id="1" snapshot_id="3013" />
+
+  <project_measures id="15" value="135" metric_id="2" snapshot_id="3010" />
+  <project_measures id="16" value="120" metric_id="2" snapshot_id="3011" />
+  <project_measures id="17" value="130" metric_id="2" snapshot_id="3012" />
+  <project_measures id="18" value="120" metric_id="2" snapshot_id="3013" />
+
+
+  <rules id="500" plugin_rule_key="AvoidCycle" plugin_name="squid"/>
+  <rules id="501" plugin_rule_key="NullRef" plugin_name="squid"/>
+
+  <!-- issues in module -->
+  <issues
+      id="100"
+      kee="ISSUE-100"
+      component_id="303"
+      root_component_id="300"
+
+      rule_id="500"
+      severity="BLOCKER"
+      manual_severity="[false]"
+      message="[null]"
+      line="200"
+      effort_to_fix="[null]"
+      status="OPEN"
+      resolution="[null]"
+      checksum="[null]"
+      reporter="user"
+      assignee="user"
+      author_login="[null]"
+      issue_attributes="[null]"
+      issue_creation_date="2013-04-16"
+      issue_update_date="2013-04-16"
+      issue_close_date="2013-04-16"
+      created_at="[null]"
+      updated_at="[null]"
+      />
+
+  <issues
+      id="101"
+      kee="ISSUE-101"
+      component_id="303"
+      root_component_id="300"
+
+      rule_id="501"
+      severity="MAJOR"
+      manual_severity="[false]"
+      message="[null]"
+      line="120"
+      effort_to_fix="[null]"
+      status="CLOSED"
+      resolution="FIXED"
+      checksum="[null]"
+      reporter="[null]"
+      assignee="user"
+      author_login="[null]"
+      issue_attributes="[null]"
+      issue_creation_date="2013-04-16"
+      issue_update_date="2013-04-16"
+      issue_close_date="2013-04-16"
+      created_at="[null]"
+      updated_at="[null]"
+      />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_copy_permission_templates.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_copy_permission_templates.xml
new file mode 100644 (file)
index 0000000..6bead9e
--- /dev/null
@@ -0,0 +1,9 @@
+<dataset>
+
+  <permission_templates id="1" name="my template" kee="my_template_20130101_010203" description="my description"/>
+
+  <perm_templates_users id="1" template_id="1" user_id="1" permission_reference="codeviewer"/>
+
+  <perm_templates_groups id="1" template_id="1" group_id="1" permission_reference="admin"/>
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml
new file mode 100644 (file)
index 0000000..008976f
--- /dev/null
@@ -0,0 +1,32 @@
+<dataset>
+  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="[false]" delete_historical_data="[null]"/>
+  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" hidden="[false]" delete_historical_data="[null]"/>
+
+  <rules_profiles id="1" name="Sonar way with Findbugs" language="java" parent_name="" version="1"
+                  used_profile="[false]"/>
+
+
+  <projects id="123" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+            description="[null]" long_name="Apache Struts"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="2013-01-25 02:04:06.00"/>
+
+  <snapshots id="1000" project_id="123" root_project_id="123" root_snapshot_id="1000" parent_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" path="1000." depth="1"
+             purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]"
+             period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]"
+             period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             created_at="2013-01-25 02:04:06.00" build_date="2013-01-25 02:04:06.00"
+             version="1.0" status="P" islast="[true]"/>
+
+  <alerts id="1" profile_id="1" metric_id="1" operator="lt" value_error="5" value_warning="" period="[null]"/>
+
+  <project_measures id="1" value="10" metric_id="1" snapshot_id="1000" />
+
+  <events id="1" name="1.0-SNAPSHOT" resource_id="123" />
+  <events id="2" name="2.0-SNAPSHOT" resource_id="123" />
+  <events id="3" name="1.0-SNAPSHOT" resource_id="456" />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database_with_issues.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database_with_issues.xml
new file mode 100644 (file)
index 0000000..d25ce65
--- /dev/null
@@ -0,0 +1,69 @@
+<dataset>
+  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="[false]" delete_historical_data="[null]"/>
+  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" hidden="[false]" delete_historical_data="[null]"/>
+
+  <rules_profiles id="1" name="Sonar way with Findbugs" language="java" parent_name="" version="1"
+                  used_profile="[false]"/>
+
+  <projects id="399" kee="struts" root_id="[null]"/>
+  <projects id="400" kee="Action.java" root_id="399"/>
+  <projects id="401" kee="Filter.java" root_id="399"/>
+
+  <snapshots id="100" project_id="399" root_snapshot_id="[null]" path="" islast="[true]"/>
+  <snapshots id="101" project_id="400" root_snapshot_id="100" path="100." islast="[true]"/>
+  <snapshots id="102" project_id="401" root_snapshot_id="100" path="100." islast="[true]"/>
+
+  <rules id="500" plugin_rule_key="AvoidCycle" plugin_name="squid"/>
+  <rules id="501" plugin_rule_key="NullRef" plugin_name="squid"/>
+
+  <issues
+      id="100"
+      kee="100"
+      component_id="400"
+      rule_id="500"
+      severity="BLOCKER"
+      manual_severity="[false]"
+      message="[null]"
+      line="200"
+      effort_to_fix="[null]"
+      status="OPEN"
+      resolution="[null]"
+      checksum="[null]"
+      reporter="user"
+      assignee="user"
+      author_login="[null]"
+      issue_attributes="[null]"
+      issue_creation_date="2013-04-16"
+      issue_update_date="2013-04-16"
+      issue_close_date="2013-04-16"
+      created_at="[null]"
+      updated_at="[null]"
+      />
+
+  <issues
+      id="101"
+      kee="101"
+      component_id="401"
+      rule_id="501"
+      severity="MAJOR"
+      manual_severity="[false]"
+      message="[null]"
+      line="120"
+      effort_to_fix="[null]"
+      status="CLOSED"
+      resolution="FIXED"
+      checksum="[null]"
+      reporter="[null]"
+      assignee="user"
+      author_login="[null]"
+      issue_attributes="[null]"
+      issue_creation_date="2013-04-16"
+      issue_update_date="2013-04-16"
+      issue_close_date="2013-04-16"
+      created_at="[null]"
+      updated_at="[null]"
+      />
+
+</dataset>
\ No newline at end of file
index 673c18fc7d206ec438269e68ce7fe0961ebc0178..f877ab0c7983f64779d9ae9799a318510a5f660c 100644 (file)
@@ -255,14 +255,24 @@ public interface CoreProperties {
 
   /**
    * @since 3.4
+   * @deprecated in 4.0 replaced by {@link CoreProperties#PREVIEW_INCLUDE_PLUGINS}
    */
   String DRY_RUN_INCLUDE_PLUGINS = "sonar.dryRun.includePlugins";
+  /**
+   * @since 3.4
+   * @deprecated in 4.0 replaced by {@link CoreProperties#PREVIEW_INCLUDE_PLUGINS_DEFAULT_VALUE}
+   */
   String DRY_RUN_INCLUDE_PLUGINS_DEFAULT_VALUE = "";
 
   /**
    * @since 3.4
+   * @deprecated in 4.0 replaced by {@link CoreProperties#PREVIEW_EXCLUDE_PLUGINS}
    */
   String DRY_RUN_EXCLUDE_PLUGINS = "sonar.dryRun.excludePlugins";
+  /**
+   * @since 3.4
+   * @deprecated in 4.0 replaced by {@link CoreProperties#PREVIEW_EXCLUDE_PLUGINS_DEFAULT_VALUE}
+   */
   String DRY_RUN_EXCLUDE_PLUGINS_DEFAULT_VALUE = "devcockpit,pdfreport,report,scmactivity,views,jira";
 
   /**
@@ -435,6 +445,7 @@ public interface CoreProperties {
 
   /**
    * @since 3.4
+   * @deprecated in 4.0 replaced by {@link CoreProperties#ANALYSIS_MODE}
    */
   String DRY_RUN = "sonar.dryRun";
 
@@ -462,9 +473,15 @@ public interface CoreProperties {
 
   /**
    * @since 3.7
+   * @deprecated in 4.0 replaced by {@link CoreProperties#PREVIEW_READ_TIMEOUT_SEC}
    */
   String DRY_RUN_READ_TIMEOUT_SEC = "sonar.dryRun.readTimeout";
 
+  /**
+   * @since 4.0
+   */
+  String PREVIEW_READ_TIMEOUT_SEC = "sonar.preview.readTimeout";
+
   /**
    * @since 4.0
    */
@@ -473,5 +490,32 @@ public interface CoreProperties {
   /**
    * @since 4.0
    */
-  String INCREMENTAL_PREVIEW = "sonar.incrementalPreview";
+  String ANALYSIS_MODE = "sonar.analysis.mode";
+
+  /**
+   * @since 4.0
+   */
+  String ANALYSIS_MODE_ANALYSIS = "analysis";
+
+  /**
+   * @since 4.0
+   */
+  String ANALYSIS_MODE_PREVIEW = "preview";
+
+  /**
+   * @since 4.0
+   */
+  String ANALYSIS_MODE_INCREMENTAL = "incremental";
+
+  /**
+   * @since 4.0
+   */
+  String PREVIEW_INCLUDE_PLUGINS = "sonar.preview.includePlugins";
+  String PREVIEW_INCLUDE_PLUGINS_DEFAULT_VALUE = "";
+
+  /**
+   * @since 4.0
+   */
+  String PREVIEW_EXCLUDE_PLUGINS = "sonar.preview.excludePlugins";
+  String PREVIEW_EXCLUDE_PLUGINS_DEFAULT_VALUE = "devcockpit,pdfreport,report,scmactivity,views,jira";
 }
index 1af960ed22651d34defc0ebd350b9e7ef08ab257..d2f86058b0fd6026ddee715d8c00a174299338ba 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.converters.basic.DateConverter;
 import com.thoughtworks.xstream.core.util.QuickWriter;
@@ -30,7 +32,6 @@ import org.apache.commons.lang.CharEncoding;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.database.DatabaseSession;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.persistence.DatabaseVersion;
 import org.sonar.server.platform.PersistentSettings;
 
@@ -55,7 +56,7 @@ public class Backup {
     backupables = new ArrayList<Backupable>();
   }
 
-  public Backup(DatabaseSession session, PersistentSettings persistentSettings, DryRunCache dryRunCache) {
+  public Backup(DatabaseSession session, PersistentSettings persistentSettings, PreviewCache dryRunCache) {
     this();
     this.session = session;
 
index 968a88dd4b55e5ca1a6af4db2608118714d8c638..c4291cd73ddee4e4490c60af006e0be5be18b216 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.MarshallingContext;
@@ -36,7 +38,6 @@ import org.sonar.api.rules.ActiveRuleParam;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleParam;
 import org.sonar.api.rules.RulePriority;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.jpa.dao.RulesDao;
 
 import java.util.ArrayList;
@@ -62,9 +63,9 @@ public class ProfilesBackup implements Backupable {
 
   private Collection<RulesProfile> profiles;
   private DatabaseSession session;
-  private DryRunCache dryRunCache;
+  private PreviewCache dryRunCache;
 
-  public ProfilesBackup(DatabaseSession session, DryRunCache dryRunCache) {
+  public ProfilesBackup(DatabaseSession session, PreviewCache dryRunCache) {
     this.session = session;
     this.dryRunCache = dryRunCache;
   }
index 11dde4538e21218be0eaef00d0f1d762a2a1306a..ea48a665e2f20136b62772e750a98fad20132979 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import com.google.common.collect.Lists;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
@@ -30,7 +32,6 @@ import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleParam;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.api.utils.ValidationMessages;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.jpa.dao.BaseDao;
 import org.sonar.jpa.dao.RulesDao;
 
@@ -39,9 +40,9 @@ import java.util.List;
 public class ProfilesManager extends BaseDao {
 
   private RulesDao rulesDao;
-  private DryRunCache dryRunCache;
+  private PreviewCache dryRunCache;
 
-  public ProfilesManager(DatabaseSession session, RulesDao rulesDao, DryRunCache dryRunCache) {
+  public ProfilesManager(DatabaseSession session, RulesDao rulesDao, PreviewCache dryRunCache) {
     super(session);
     this.rulesDao = rulesDao;
     this.dryRunCache = dryRunCache;
index 196af403ecb5bb0cd9a1cc34efbe6c23570c93c2..bd489b190e4edfb38d690075513192fdf700bf40 100644 (file)
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.thoughtworks.xstream.XStream;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.database.configuration.Property;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.properties.PropertyDto;
 import org.sonar.server.platform.PersistentSettings;
 
@@ -83,7 +84,7 @@ public class PropertiesBackup implements Backupable {
     // default permissions properties should not be exported as they reference permission_templates entries in the DB
     return !CoreProperties.SERVER_ID.equals(propertyKey)
       && !propertyKey.startsWith(PERMISSION_PROPERTIES_PREFIX)
-      && !DryRunCache.SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY.equals(propertyKey);
+      && !PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY.equals(propertyKey);
   }
 
   private boolean shouldNotBeErased(String propertyKey) {
index d978d5278c24c76fc293a7f27c34f2ab182ef421..887ac4ee8f4d76911863d336cbd8716694ebf13a 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.sonar.server.issue;
 
+import org.sonar.core.preview.PreviewCache;
+
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import org.slf4j.Logger;
@@ -30,7 +32,6 @@ import org.sonar.api.issue.IssueQueryResult;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.issue.internal.IssueChangeContext;
 import org.sonar.api.web.UserRole;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.db.IssueStorage;
 import org.sonar.server.exceptions.BadRequestException;
@@ -50,10 +51,10 @@ public class IssueBulkChangeService {
   private final DefaultIssueFinder issueFinder;
   private final IssueStorage issueStorage;
   private final IssueNotifications issueNotifications;
-  private final DryRunCache dryRunCache;
+  private final PreviewCache dryRunCache;
   private final List<Action> actions;
 
-  public IssueBulkChangeService(DefaultIssueFinder issueFinder, IssueStorage issueStorage, IssueNotifications issueNotifications, List<Action> actions, DryRunCache dryRunCache) {
+  public IssueBulkChangeService(DefaultIssueFinder issueFinder, IssueStorage issueStorage, IssueNotifications issueNotifications, List<Action> actions, PreviewCache dryRunCache) {
     this.issueFinder = issueFinder;
     this.issueStorage = issueStorage;
     this.issueNotifications = issueNotifications;
index 33016fbd782fe2faab8ad8c0417ed32190324bb3..40bd5885e2bd278259e061c1ed55d6112c98d3ee 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.issue;
 
+import org.sonar.core.preview.PreviewCache;
+
 import com.google.common.base.Strings;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.issue.ActionPlan;
@@ -32,7 +34,6 @@ import org.sonar.api.rules.RuleFinder;
 import org.sonar.api.user.User;
 import org.sonar.api.user.UserFinder;
 import org.sonar.api.web.UserRole;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.IssueUpdater;
 import org.sonar.core.issue.db.IssueStorage;
@@ -66,7 +67,7 @@ public class IssueService implements ServerComponent {
   private final ResourceDao resourceDao;
   private final AuthorizationDao authorizationDao;
   private final UserFinder userFinder;
-  private final DryRunCache dryRunCache;
+  private final PreviewCache dryRunCache;
 
   public IssueService(DefaultIssueFinder finder,
     IssueWorkflow workflow,
@@ -78,7 +79,7 @@ public class IssueService implements ServerComponent {
     ResourceDao resourceDao,
     AuthorizationDao authorizationDao,
     UserFinder userFinder,
-    DryRunCache dryRunCache) {
+    PreviewCache dryRunCache) {
     this.finder = finder;
     this.workflow = workflow;
     this.issueStorage = issueStorage;
index 9658cf0aaa826cd4b2b9b324e23f485cad5a1038..6c5f06364c75c591e84476220e35a867f0619ffd 100644 (file)
@@ -37,7 +37,6 @@ import org.sonar.api.utils.TimeProfiler;
 import org.sonar.api.utils.UriReader;
 import org.sonar.core.component.SnapshotPerspectives;
 import org.sonar.core.config.Logback;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.i18n.GwtI18n;
 import org.sonar.core.i18n.I18nManager;
 import org.sonar.core.i18n.RuleI18nManager;
@@ -52,7 +51,14 @@ import org.sonar.core.measure.MeasureFilterFactory;
 import org.sonar.core.metric.DefaultMetricFinder;
 import org.sonar.core.notification.DefaultNotificationManager;
 import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.*;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.PreviewDatabaseFactory;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
+import org.sonar.core.preview.PreviewCache;
 import org.sonar.core.purge.PurgeProfiler;
 import org.sonar.core.qualitymodel.DefaultModelFinder;
 import org.sonar.core.resource.DefaultResourcePermissions;
@@ -83,19 +89,63 @@ import org.sonar.server.db.EmbeddedDatabaseFactory;
 import org.sonar.server.db.migrations.DatabaseMigration;
 import org.sonar.server.db.migrations.DatabaseMigrations;
 import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.issue.*;
+import org.sonar.server.issue.ActionPlanService;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.AssignAction;
+import org.sonar.server.issue.CommentAction;
+import org.sonar.server.issue.DefaultIssueFinder;
+import org.sonar.server.issue.InternalRubyIssueService;
+import org.sonar.server.issue.IssueBulkChangeService;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueCommentService;
+import org.sonar.server.issue.IssueFilterService;
+import org.sonar.server.issue.IssueService;
+import org.sonar.server.issue.IssueStatsFinder;
+import org.sonar.server.issue.PlanAction;
+import org.sonar.server.issue.PublicRubyIssueService;
+import org.sonar.server.issue.ServerIssueStorage;
+import org.sonar.server.issue.SetSeverityAction;
+import org.sonar.server.issue.TransitionAction;
 import org.sonar.server.notifications.NotificationCenter;
 import org.sonar.server.notifications.NotificationService;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.InternalPermissionTemplateService;
-import org.sonar.server.plugins.*;
+import org.sonar.server.plugins.ApplicationDeployer;
+import org.sonar.server.plugins.DefaultServerPluginRepository;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
+import org.sonar.server.plugins.PluginDeployer;
+import org.sonar.server.plugins.PluginDownloader;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.UpdateCenterClient;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
 import org.sonar.server.rule.RubyRuleService;
 import org.sonar.server.rules.ProfilesConsole;
 import org.sonar.server.rules.RulesConsole;
-import org.sonar.server.startup.*;
+import org.sonar.server.startup.CleanDryRunCache;
+import org.sonar.server.startup.DeleteDeprecatedMeasures;
+import org.sonar.server.startup.GenerateBootstrapIndex;
+import org.sonar.server.startup.GeneratePluginIndex;
+import org.sonar.server.startup.GwtPublisher;
+import org.sonar.server.startup.JdbcDriverDeployer;
+import org.sonar.server.startup.LogServerId;
+import org.sonar.server.startup.RegisterMetrics;
+import org.sonar.server.startup.RegisterNewDashboards;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
+import org.sonar.server.startup.RegisterNewProfiles;
+import org.sonar.server.startup.RegisterPermissionTemplates;
+import org.sonar.server.startup.RegisterRules;
+import org.sonar.server.startup.RegisterServletFilters;
+import org.sonar.server.startup.RegisterTechnicalDebtModel;
+import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.ServerMetadataPersister;
+import org.sonar.server.startup.VerifyNoQualityModelsAreDefined;
 import org.sonar.server.text.MacroInterpreter;
 import org.sonar.server.text.RubyTextService;
-import org.sonar.server.ui.*;
+import org.sonar.server.ui.CodeColorizers;
+import org.sonar.server.ui.JRubyI18n;
+import org.sonar.server.ui.PageDecorations;
+import org.sonar.server.ui.SecurityRealmFactory;
+import org.sonar.server.ui.Views;
 import org.sonar.server.user.DefaultUserService;
 import org.sonar.server.user.NewUserNotifier;
 
@@ -186,7 +236,7 @@ public final class Platform {
     rootContainer.addSingleton(I18nManager.class);
     rootContainer.addSingleton(RuleI18nManager.class);
     rootContainer.addSingleton(GwtI18n.class);
-    rootContainer.addSingleton(DryRunDatabaseFactory.class);
+    rootContainer.addSingleton(PreviewDatabaseFactory.class);
     rootContainer.addSingleton(SemaphoreUpdater.class);
     rootContainer.addSingleton(SemaphoresImpl.class);
     rootContainer.startComponents();
@@ -249,8 +299,7 @@ public final class Platform {
     servicesContainer.addSingleton(MeasureFilterFactory.class);
     servicesContainer.addSingleton(MeasureFilterExecutor.class);
     servicesContainer.addSingleton(MeasureFilterEngine.class);
-    servicesContainer.addSingleton(DryRunDatabaseFactory.class);
-    servicesContainer.addSingleton(DryRunCache.class);
+    servicesContainer.addSingleton(PreviewCache.class);
     servicesContainer.addSingleton(DefaultResourcePermissions.class);
     servicesContainer.addSingleton(Periods.class);
 
index b662f2bff3ce5230266bef1a3a224a61fca7052d..c52ed7ccaf24460943d9e757121bfc520da54853 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.sonar.server.rules;
 
+import org.sonar.core.preview.PreviewCache;
+
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.ServerComponent;
@@ -32,7 +34,6 @@ import org.sonar.api.profiles.XMLProfileSerializer;
 import org.sonar.api.rules.ActiveRule;
 import org.sonar.api.rules.ActiveRuleParam;
 import org.sonar.api.utils.ValidationMessages;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.jpa.session.DatabaseSessionFactory;
 
 import java.io.StringReader;
@@ -51,9 +52,9 @@ public final class ProfilesConsole implements ServerComponent {
   private XMLProfileSerializer xmlProfileSerializer;
   private List<ProfileExporter> exporters = newArrayList();
   private List<ProfileImporter> importers = newArrayList();
-  private DryRunCache dryRunCache;
+  private PreviewCache dryRunCache;
 
-  public ProfilesConsole(DatabaseSessionFactory sessionFactory, XMLProfileParser xmlProfileParser, XMLProfileSerializer xmlProfileSerializer, DryRunCache dryRunCache) {
+  public ProfilesConsole(DatabaseSessionFactory sessionFactory, XMLProfileParser xmlProfileParser, XMLProfileSerializer xmlProfileSerializer, PreviewCache dryRunCache) {
     this.sessionFactory = sessionFactory;
     this.xmlProfileParser = xmlProfileParser;
     this.xmlProfileSerializer = xmlProfileSerializer;
@@ -64,7 +65,7 @@ public final class ProfilesConsole implements ServerComponent {
 
   public ProfilesConsole(DatabaseSessionFactory sessionFactory, XMLProfileParser xmlProfileParser, XMLProfileSerializer xmlProfileSerializer,
     ProfileExporter[] exporters,
-    ProfileImporter[] importers, DryRunCache dryRunCache) {
+    ProfileImporter[] importers, PreviewCache dryRunCache) {
     this(sessionFactory, xmlProfileParser, xmlProfileSerializer, dryRunCache);
     this.exporters.addAll(Arrays.asList(exporters));
     this.importers.addAll(Arrays.asList(importers));
index d08ccb32e586b19b2a6085870133cff30490ca54..d70003ecf7f41f9e151ba2340894fec2964ec1c0 100644 (file)
  */
 package org.sonar.server.startup;
 
-import org.sonar.core.dryrun.DryRunCache;
+import org.sonar.core.preview.PreviewCache;
 
 /**
  * @since 4.0
  */
 public class CleanDryRunCache {
 
-  private DryRunCache dryRunCache;
+  private PreviewCache dryRunCache;
 
-  public CleanDryRunCache(DryRunCache dryRunCache) {
+  public CleanDryRunCache(PreviewCache dryRunCache) {
     this.dryRunCache = dryRunCache;
   }
 
index 807cb564be7c689bd34f4eadd3fca95c802c43a9..e23333868452e5cceb8a549816059a3455501280 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.ui;
 
+import org.sonar.core.preview.PreviewCache;
+
 import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.License;
@@ -46,7 +48,6 @@ import org.sonar.api.web.Page;
 import org.sonar.api.web.RubyRailsWebservice;
 import org.sonar.api.web.Widget;
 import org.sonar.core.component.SnapshotPerspectives;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.i18n.RuleI18nManager;
 import org.sonar.core.measure.MeasureFilterEngine;
 import org.sonar.core.measure.MeasureFilterResult;
@@ -496,8 +497,8 @@ public final class JRubyFacade {
     }
   }
 
-  public byte[] createDatabaseForDryRun(@Nullable Long projectId) {
-    return get(DryRunCache.class).getDatabaseForDryRun(projectId);
+  public byte[] createDatabaseForPreview(@Nullable Long projectId) {
+    return get(PreviewCache.class).getDatabaseForPreview(projectId);
   }
 
   public String getPeriodLabel(int periodIndex) {
index a2b076d8abed76f8080045ae99a0f6cefa47aa93..04cc9b61d866e7e7d040748a81f7de58d179650a 100644 (file)
@@ -140,7 +140,7 @@ class AlertsController < ApplicationController
   private
 
   def reportGlobalModification
-    Property.set(Java::OrgSonarCoreDryrun::DryRunCache::SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY, java.lang.System.currentTimeMillis)
+    Property.set(Java::OrgSonarCorePreview::PreviewCache::SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY, java.lang.System.currentTimeMillis)
   end
 
 end
index d5ea35bd1582ecd24bd1a9b0509f901354ab7f04..f22ad21392348e4ed35eb889eee5f191e4973ceb 100644 (file)
@@ -30,7 +30,7 @@ class BatchBootstrapController < Api::ApiController
     return render_unauthorized("You're not authorized to execute a dry run analysis. Please contact your SonarQube administrator.") if !has_dryrun_role
     project = load_project()
     return render_unauthorized("You're not authorized to access to project '" + project.name + "', please contact your SonarQube administrator") if project && !has_role?(:user, project)
-    db_content = java_facade.createDatabaseForDryRun(project && project.id)
+    db_content = java_facade.createDatabaseForPreview(project && project.id)
 
     send_data String.from_java_bytes(db_content)
   end
@@ -44,7 +44,7 @@ class BatchBootstrapController < Api::ApiController
     return render_unauthorized("You're not authorized to access to project '" + project.name + "', please contact your SonarQube administrator") if project && !has_scan_role && !has_role?(:user, project)
 
     if project
-      Property.set(Java::OrgSonarCoreDryrun::DryRunCache::SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY, java.lang.System.currentTimeMillis, project.root_project.id)
+      Property.set(Java::OrgSonarCorePreview::PreviewCache::SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY, java.lang.System.currentTimeMillis, project.root_project.id)
       render_success('dryRun DB evicted')
     else
       render_bad_request('missing projectId')
index 2da67f5e802f64cd533890ff72f11a6c0ab84503..c2f9cca74b26ebc177e40f202242e15f3aea20a8 100644 (file)
@@ -160,7 +160,7 @@ class IssuesController < ApplicationController
 
   # GET /issues/bulk_change_form?[&criteria]
   def bulk_change_form
-    issues_query_params = params.clone.merge({'pageSize' => -1})
+    issues_query_params = criteria_params.clone.merge({'pageSize' => -1})
     # SONAR-4654 pagination parameters should be remove when loading issues for bulk change
     issues_query_params.delete('pageIndex')
     if params[:id]
index 5fc629a33e4f11d7df610cb7a9673e5d6fce866c..37d9d6e116424bfa72a3ec7f85a7538c07a8acf9 100644 (file)
@@ -402,7 +402,7 @@ class ProjectController < ApplicationController
   end
 
   def reportProjectModification(project_id)
-    Property.set(Java::OrgSonarCoreDryrun::DryRunCache::SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY, java.lang.System.currentTimeMillis, project_id)
+    Property.set(Java::OrgSonarCorePreview::PreviewCache::SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY, java.lang.System.currentTimeMillis, project_id)
   end
 
 end
index 9fadc4494dd96fa054ecdbc2eb81697665115815..b795678cbdc5d555d48c28a6c523e84a4ab2932f 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import com.google.common.collect.Lists;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.CharEncoding;
@@ -36,7 +38,6 @@ import org.sonar.api.rules.ActiveRuleParam;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleParam;
 import org.sonar.api.rules.RulePriority;
-import org.sonar.core.dryrun.DryRunCache;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -56,11 +57,11 @@ import static org.mockito.Mockito.verify;
 
 public class BackupTest {
 
-  private DryRunCache dryRunCache;
+  private PreviewCache dryRunCache;
 
   @Before
   public void prepare() {
-    this.dryRunCache = mock(DryRunCache.class);
+    this.dryRunCache = mock(PreviewCache.class);
   }
 
   @Test
index 63ceb7343c897b622d9541f333511a5e4f6ce471..b7f44d92b22f8d09e6ce647da0da971c34cab59b 100644 (file)
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.profiles.RulesProfile;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertThat;
@@ -35,7 +35,7 @@ public class InheritedProfilesTest extends AbstractDbUnitTestCase {
 
   @Before
   public void setUp() {
-    profilesManager = new ProfilesManager(getSession(), null, mock(DryRunCache.class));
+    profilesManager = new ProfilesManager(getSession(), null, mock(PreviewCache.class));
   }
 
   @Test
index c1231bda910e7861a403c487fb2b3403fd8b92b9..82aa83f3897de2ddcf66f1e505fda03f76f1c5ce 100644 (file)
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.profiles.RulesProfile;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 
@@ -34,7 +34,7 @@ public class ProfilesManagerTest extends AbstractDbUnitTestCase {
 
   @Before
   public void before() {
-    manager = new ProfilesManager(getSession(), null, mock(DryRunCache.class));
+    manager = new ProfilesManager(getSession(), null, mock(PreviewCache.class));
   }
 
   @Test
index dd10096e767769c908c89825a2f486c12f7639eb..e95f817d98a139f94fbef8f31013f6758715d141 100644 (file)
  */
 package org.sonar.server.configuration;
 
+import org.sonar.core.preview.PreviewCache;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.rules.ActiveRuleChange;
 import org.sonar.api.rules.ActiveRuleParamChange;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RulePriority;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 
@@ -36,7 +36,7 @@ public class RuleChangeTest extends AbstractDbUnitTestCase {
 
   @Before
   public void setUp() {
-    profilesManager = new ProfilesManager(getSession(), null, mock(DryRunCache.class));
+    profilesManager = new ProfilesManager(getSession(), null, mock(PreviewCache.class));
   }
 
   @Test
index 9461440a6ff652e624d852dce16091013377ae00..14e6ec6207556a8a3cb96b874304de6b2640859f 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.sonar.server.issue;
 
+import org.sonar.core.preview.PreviewCache;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -30,7 +32,6 @@ import org.sonar.api.issue.condition.Condition;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.issue.internal.IssueChangeContext;
 import org.sonar.api.web.UserRole;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.db.IssueStorage;
 import org.sonar.server.exceptions.BadRequestException;
@@ -79,7 +80,7 @@ public class IssueBulkChangeServiceTest {
 
     actions = newArrayList();
 
-    service = new IssueBulkChangeService(finder, issueStorage, issueNotifications, actions, mock(DryRunCache.class));
+    service = new IssueBulkChangeService(finder, issueStorage, issueNotifications, actions, mock(PreviewCache.class));
   }
 
   @Test
index dbb42117b2e56bfa6ebb58b141cb449f70310550..8ce062f1af20f2d8b3e0b50f2607b6e87cd7d281 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.sonar.server.issue;
 
+import org.sonar.core.preview.PreviewCache;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -35,7 +37,6 @@ import org.sonar.api.rules.RuleFinder;
 import org.sonar.api.user.User;
 import org.sonar.api.user.UserFinder;
 import org.sonar.api.web.UserRole;
-import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.DefaultActionPlan;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.IssueUpdater;
@@ -96,7 +97,7 @@ public class IssueServiceTest {
     when(issueQueryResult.first()).thenReturn(issue);
 
     issueService = new IssueService(finder, workflow, issueStorage, issueUpdater, issueNotifications, actionPlanService, ruleFinder, resourceDao, authorizationDao, userFinder,
-      mock(DryRunCache.class));
+      mock(PreviewCache.class));
   }
 
   @Test