]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4069 Refactoring to ease override of some components
authorJulien HENRY <julien.henry@sonarsource.com>
Tue, 19 Mar 2013 15:39:20 +0000 (16:39 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 19 Mar 2013 15:41:36 +0000 (16:41 +0100)
 * Don't fail when there is a fake profile with id=null
 * Don't fail when there is a fake language

14 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileEventsSensor.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileSensor.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileEventsSensorTest.java
sonar-batch/src/main/java/org/sonar/batch/DefaultProfileLoader.java
sonar-batch/src/main/java/org/sonar/batch/ProfileLoader.java
sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java
sonar-batch/src/main/java/org/sonar/batch/phases/ProjectInitializer.java
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/scan/ScanTask.java
sonar-batch/src/test/java/org/sonar/batch/DefaultProfileLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/ProfileProviderTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ScanTaskTest.java

index 5347109477c7e6d40f08cd477f1a0f8bf4b96d19..fd6a3a79a3db942d72431c96b1de809306796deb 100644 (file)
  */
 package org.sonar.plugins.core.sensors;
 
-import org.sonar.api.batch.*;
+import org.sonar.api.batch.Event;
+import org.sonar.api.batch.Sensor;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.TimeMachine;
+import org.sonar.api.batch.TimeMachineQuery;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.Metric;
@@ -39,14 +43,11 @@ public class ProfileEventsSensor implements Sensor {
   }
 
   public boolean shouldExecuteOnProject(Project project) {
-    return true;
+    // Views will define a fake profile with a null id
+    return profile.getId() != null;
   }
 
   public void analyse(Project project, SensorContext context) {
-    if (profile == null) {
-      return;
-    }
-
     Measure pastProfileMeasure = getPreviousMeasure(project, CoreMetrics.PROFILE);
     if (pastProfileMeasure == null) {
       // first analysis
index 17e09f2599c6dbdb331c25a7962150cc9dc73eef..d1c946d646373fbf13b261bd3204e8efee8da3c7 100644 (file)
@@ -38,22 +38,21 @@ public class ProfileSensor implements Sensor {
   }
 
   public boolean shouldExecuteOnProject(Project project) {
-    return true;
+    // Views will define a fake profile with a null id
+    return profile.getId() != null;
   }
 
   public void analyse(Project project, SensorContext context) {
-    if (profile != null) {
-      Measure measure = new Measure(CoreMetrics.PROFILE, profile.getName());
-      Measure measureVersion = new Measure(CoreMetrics.PROFILE_VERSION, Integer.valueOf(profile.getVersion()).doubleValue());
-      if (profile.getId() != null) {
-        measure.setValue(profile.getId().doubleValue());
-        
-        profile.setUsed(true);
-        session.merge(profile);
-      }
-      context.saveMeasure(measure);
-      context.saveMeasure(measureVersion);
+    Measure measure = new Measure(CoreMetrics.PROFILE, profile.getName());
+    Measure measureVersion = new Measure(CoreMetrics.PROFILE_VERSION, Integer.valueOf(profile.getVersion()).doubleValue());
+    if (profile.getId() != null) {
+      measure.setValue(profile.getId().doubleValue());
+
+      profile.setUsed(true);
+      session.merge(profile);
     }
+    context.saveMeasure(measure);
+    context.saveMeasure(measureVersion);
   }
 
   @Override
index 2eb7f73a0f8c25dfd1060187130939193615b306..8367653e800d17aa6df3714affc79a1ce7c4225c 100644 (file)
@@ -29,7 +29,6 @@ import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -38,11 +37,9 @@ import java.util.Date;
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
@@ -59,20 +56,23 @@ public class ProfileEventsSensorTest {
   }
 
   @Test
-  public void shouldExecute() {
-    ProfileEventsSensor sensor = new ProfileEventsSensor(null, null);
+  public void shouldExecuteWhenProfileWithId() {
+    RulesProfile profile = mock(RulesProfile.class);
+    when(profile.getId()).thenReturn(123);
+    ProfileEventsSensor sensor = new ProfileEventsSensor(profile, null);
 
     assertThat(sensor.shouldExecuteOnProject(project), is(true));
     verifyZeroInteractions(project);
   }
 
   @Test
-  public void shouldDoNothingIfNoProfile() {
-    ProfileEventsSensor sensor = new ProfileEventsSensor(null, null);
-
-    sensor.analyse(project, context);
+  public void shouldNotExecuteIfProfileWithoutId() {
+    RulesProfile profile = mock(RulesProfile.class);
+    when(profile.getId()).thenReturn(null);
+    ProfileEventsSensor sensor = new ProfileEventsSensor(profile, null);
 
-    verify(context, never()).createEvent(any(Resource.class), anyString(), anyString(), anyString(), any(Date.class));
+    assertThat(sensor.shouldExecuteOnProject(project), is(false));
+    verifyZeroInteractions(project);
   }
 
   @Test
index 751508ea40b57f6a58cf887783b5e8af71cab9a9..a76c1e076221e19623da8d4fc61d8a99adfce79a 100644 (file)
@@ -29,18 +29,16 @@ import org.sonar.jpa.dao.ProfilesDao;
 
 public class DefaultProfileLoader implements ProfileLoader {
   private ProfilesDao dao;
-  private Settings settings;
 
-  public DefaultProfileLoader(ProfilesDao dao, Settings settings) {
+  public DefaultProfileLoader(ProfilesDao dao) {
     this.dao = dao;
-    this.settings = settings;
   }
 
-  public RulesProfile load(Project project) {
+  public RulesProfile load(Project project, Settings settings) {
     String profileName = StringUtils.defaultIfBlank(
-      settings.getString("sonar.profile"),
-      settings.getString("sonar.profile." + project.getLanguageKey())
-    );
+        settings.getString("sonar.profile"),
+        settings.getString("sonar.profile." + project.getLanguageKey())
+        );
 
     if (StringUtils.isBlank(profileName)) {
       // This means that the current language is not supported by any installed plugin, otherwise at least a
index 73ebb8d9ef9d07cbf1d66bc0e8fee7d09f07c773..03d6ecce3101f694a3a0a87ebdad2782e0af3a54 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.batch;
 
+import org.sonar.api.config.Settings;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.resources.Project;
 
@@ -27,6 +28,6 @@ public interface ProfileLoader {
   /**
    * Loads quality profile for specified project.
    */
-  RulesProfile load(Project project);
+  RulesProfile load(Project project, Settings settings);
 
 }
index 22a8c030108a91a38cae1997d1627519fab48576..1889a8b8bb21400b44dd53b4b0999474dbe69289 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.batch;
 import org.picocontainer.injectors.ProviderAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.sonar.api.config.Settings;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.resources.Project;
 
@@ -31,9 +32,9 @@ public class ProfileProvider extends ProviderAdapter {
 
   private RulesProfile profile;
 
-  public RulesProfile provide(Project project, ProfileLoader profileLoader) {
+  public RulesProfile provide(Project project, ProfileLoader profileLoader, Settings settings) {
     if (profile == null) {
-      profile = profileLoader.load(project);
+      profile = profileLoader.load(project, settings);
       LOG.info("Quality profile : {}", profile);
     }
     return profile;
index da09f319a6dd128989903b2c9593bcf12194f72e..f898e874340f8a63a8fc4310c775a10b3507340a 100644 (file)
@@ -19,8 +19,6 @@
  */
 package org.sonar.batch.bootstrap;
 
-import org.sonar.core.resource.DefaultResourcePermissions;
-
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.ComponentContainer;
@@ -32,6 +30,7 @@ import org.sonar.api.utils.SonarException;
 import org.sonar.batch.scan.ScanTask;
 import org.sonar.batch.tasks.ListTask;
 import org.sonar.batch.tasks.Tasks;
+import org.sonar.core.resource.DefaultResourcePermissions;
 
 public class TaskContainer extends ComponentContainer {
 
@@ -48,9 +47,8 @@ public class TaskContainer extends ComponentContainer {
 
   private void installCoreTasks() {
     add(
-      ScanTask.DEFINITION, ScanTask.class,
-      ListTask.DEFINITION, ListTask.class
-    );
+        ScanTask.DEFINITION, ScanTask.class,
+        ListTask.DEFINITION, ListTask.class);
   }
 
   private void installTaskExtensions() {
index 38ea6b9ed943619704fcbc82afd3952b91599e77..94bc363e30fda3e472615ff346ef711951730f72 100644 (file)
@@ -41,7 +41,9 @@ public class ProjectInitializer implements BatchComponent {
   }
 
   public void execute(Project project) {
-    initLanguage(project);
+    if (project.getLanguage() == null) {
+      initLanguage(project);
+    }
   }
 
   private void initLanguage(Project project) {
index 8fdb47f966847b8c129043ab16936805d77afea6..550e9b5d234c1c80eb9eb11aedbf505170539499 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.api.resources.Languages;
 import org.sonar.api.resources.Project;
 import org.sonar.api.scan.filesystem.FileExclusions;
 import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.batch.DefaultProfileLoader;
 import org.sonar.batch.DefaultProjectClasspath;
 import org.sonar.batch.DefaultSensorContext;
 import org.sonar.batch.DefaultTimeMachine;
@@ -73,48 +72,47 @@ public class ModuleScanContainer extends ComponentContainer {
   private void addCoreComponents() {
     ProjectDefinition moduleDefinition = getComponentByType(ProjectTree.class).getProjectDefinition(module);
     add(
-      moduleDefinition,
-      module.getConfiguration(),
-      module,
-      ModuleSettings.class);
+        moduleDefinition,
+        module.getConfiguration(),
+        module,
+        ModuleSettings.class);
 
     // hack to initialize commons-configuration before ExtensionProviders
     getComponentByType(ModuleSettings.class);
 
     add(
-      EventBus.class,
-      PhaseExecutor.class,
-      PhasesTimeProfiler.class,
-      UnsupportedProperties.class,
-      PhaseExecutor.getPhaseClasses(),
-      moduleDefinition.getContainerExtensions(),
+        EventBus.class,
+        PhaseExecutor.class,
+        PhasesTimeProfiler.class,
+        UnsupportedProperties.class,
+        PhaseExecutor.getPhaseClasses(),
+        moduleDefinition.getContainerExtensions(),
 
-      // TODO move outside project, but not possible yet because of dependency of project settings (cf plsql)
-      Languages.class,
+        // TODO move outside project, but not possible yet because of dependency of project settings (cf plsql)
+        Languages.class,
 
-      // file system
-      PathResolver.class,
-      FileExclusions.class,
-      LanguageFilters.class,
-      ExclusionFilters.class,
-      DefaultProjectClasspath.class,
-      new ModuleFileSystemProvider(),
-      DeprecatedFileSystemAdapter.class,
-      FileSystemLogger.class,
+        // file system
+        PathResolver.class,
+        FileExclusions.class,
+        LanguageFilters.class,
+        ExclusionFilters.class,
+        DefaultProjectClasspath.class,
+        new ModuleFileSystemProvider(),
+        DeprecatedFileSystemAdapter.class,
+        FileSystemLogger.class,
 
-      // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
-      getComponentByType(ResourcePersister.class).getSnapshot(module),
+        // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
+        getComponentByType(ResourcePersister.class).getSnapshot(module),
 
-      TimeMachineConfiguration.class,
-      org.sonar.api.database.daos.MeasuresDao.class,
-      DefaultSensorContext.class,
-      BatchExtensionDictionnary.class,
-      DefaultTimeMachine.class,
-      ViolationFilters.class,
-      ResourceFilters.class,
-      DefaultProfileLoader.class,
-      DryRunExporter.class,
-      new ProfileProvider());
+        TimeMachineConfiguration.class,
+        org.sonar.api.database.daos.MeasuresDao.class,
+        DefaultSensorContext.class,
+        BatchExtensionDictionnary.class,
+        DefaultTimeMachine.class,
+        ViolationFilters.class,
+        ResourceFilters.class,
+        DryRunExporter.class,
+        new ProfileProvider());
   }
 
   private void addExtensions() {
@@ -136,9 +134,9 @@ public class ModuleScanContainer extends ComponentContainer {
   protected void doAfterStart() {
     DefaultIndex index = getComponentByType(DefaultIndex.class);
     index.setCurrentProject(module,
-      getComponentByType(ResourceFilters.class),
-      getComponentByType(ViolationFilters.class),
-      getComponentByType(RulesProfile.class));
+        getComponentByType(ResourceFilters.class),
+        getComponentByType(ViolationFilters.class),
+        getComponentByType(RulesProfile.class));
 
     getComponentByType(PhaseExecutor.class).execute(module);
   }
index c67e1e445f137feb1ef501a44e096f4c474ea803..610ac4070db3af0c802171001d18848e2f7599e8 100644 (file)
@@ -24,7 +24,6 @@ import org.sonar.api.batch.InstantiationStrategy;
 import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.resources.Project;
 import org.sonar.batch.DefaultFileLinesContextFactory;
-import org.sonar.batch.DefaultProjectTree;
 import org.sonar.batch.DefaultResourceCreationLock;
 import org.sonar.batch.ProjectConfigurator;
 import org.sonar.batch.ProjectTree;
@@ -57,40 +56,33 @@ public class ProjectScanContainer extends ComponentContainer {
   @Override
   protected void doBeforeStart() {
     addBatchComponents();
-    addProjectComponents();
     fixMavenExecutor();
     addBatchExtensions();
   }
 
-  protected void addProjectComponents() {
-    add(DefaultProjectTree.class);
-  }
-
   private void addBatchComponents() {
     add(
-      DefaultResourceCreationLock.class,
-      DefaultPersistenceManager.class,
-      DependencyPersister.class,
-      EventPersister.class,
-      LinkPersister.class,
-      MeasurePersister.class,
-      MemoryOptimizer.class,
-      DefaultResourcePersister.class,
-      SourcePersister.class,
-      DefaultNotificationManager.class,
-      MetricProvider.class,
-      ProjectExclusions.class,
-      ProjectReactorReady.class,
-      ProjectConfigurator.class,
-      DefaultIndex.class,
-      DefaultFileLinesContextFactory.class,
-      ProjectLock.class,
-      LastSnapshots.class,
-      ScanGraph.create(),
-      TestPlanBuilder.class,
-      TestableBuilder.class,
-      ScanPerspectives.class,
-      ScanGraphStore.class);
+        DefaultResourceCreationLock.class,
+        DefaultPersistenceManager.class,
+        DependencyPersister.class,
+        EventPersister.class,
+        LinkPersister.class,
+        MeasurePersister.class,
+        MemoryOptimizer.class,
+        DefaultResourcePersister.class,
+        SourcePersister.class,
+        DefaultNotificationManager.class,
+        MetricProvider.class,
+        ProjectConfigurator.class,
+        DefaultIndex.class,
+        DefaultFileLinesContextFactory.class,
+        ProjectLock.class,
+        LastSnapshots.class,
+        ScanGraph.create(),
+        TestPlanBuilder.class,
+        TestableBuilder.class,
+        ScanPerspectives.class,
+        ScanGraphStore.class);
   }
 
   private void fixMavenExecutor() {
index a6df4b096be79067811bc4ce0cd70a5786b6bfbf..760e5cd182a10cc2828447367d1ae37c0d751012 100644 (file)
@@ -23,15 +23,17 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.task.Task;
 import org.sonar.api.task.TaskDefinition;
+import org.sonar.batch.DefaultProfileLoader;
+import org.sonar.batch.DefaultProjectTree;
 import org.sonar.batch.bootstrap.TaskContainer;
 import org.sonar.batch.phases.Phases;
 
 public class ScanTask implements Task {
   public static final TaskDefinition DEFINITION = TaskDefinition.builder()
-    .description("Scan project")
-    .key(CoreProperties.SCAN_TASK)
-    .taskClass(ScanTask.class)
-    .build();
+      .description("Scan project")
+      .key(CoreProperties.SCAN_TASK)
+      .taskClass(ScanTask.class)
+      .build();
 
   private final ComponentContainer taskContainer;
 
@@ -43,8 +45,14 @@ public class ScanTask implements Task {
     scan(new ProjectScanContainer(taskContainer));
   }
 
+  // Add components specific to project scan (views will use different ones)
   void scan(ComponentContainer scanContainer) {
-    scanContainer.add(new Phases().enable(Phases.Phase.values()));
+    scanContainer.add(
+        new Phases().enable(Phases.Phase.values()),
+        DefaultProjectTree.class,
+        ProjectExclusions.class,
+        ProjectReactorReady.class,
+        DefaultProfileLoader.class);
     scanContainer.execute();
   }
 }
index 410e8032ac7e773b075e375bf2cc3a09624655e6..aea610fe0f7378ea5efa3a94cff92e79c44137ed 100644 (file)
@@ -54,7 +54,7 @@ public class DefaultProfileLoaderTest {
     settings.setProperty("sonar.profile.java", "legacy profile");
     when(dao.getProfile(Java.KEY, "legacy profile")).thenReturn(RulesProfile.create("legacy profile", "java"));
 
-    RulesProfile profile = new DefaultProfileLoader(dao, settings).load(javaProject);
+    RulesProfile profile = new DefaultProfileLoader(dao).load(javaProject, settings);
 
     assertThat(profile.getName()).isEqualTo("legacy profile");
   }
@@ -66,7 +66,7 @@ public class DefaultProfileLoaderTest {
 
     thrown.expect(SonarException.class);
     thrown.expectMessage("Quality profile not found : unknown, language java");
-    new DefaultProfileLoader(dao, settings).load(javaProject);
+    new DefaultProfileLoader(dao).load(javaProject, settings);
   }
 
   /**
@@ -78,7 +78,7 @@ public class DefaultProfileLoaderTest {
 
     thrown.expect(SonarException.class);
     thrown.expectMessage("You must install a plugin that supports the language 'cobol'");
-    new DefaultProfileLoader(dao, new Settings()).load(cobolProject);
+    new DefaultProfileLoader(dao).load(cobolProject, new Settings());
   }
 
   private Project newProject(String language) {
index 0168e8eada1cae976dad7b9d602b1eb6517a06c7..202f2dbc6b9347ecdf922ad7f68b5e5c530f59c7 100644 (file)
  */
 package org.sonar.batch;
 
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.Project;
+
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import org.junit.Test;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.Project;
-
 public class ProfileProviderTest {
   @Test
   public void shouldProvideProfile() {
@@ -37,11 +40,11 @@ public class ProfileProviderTest {
     ProfileLoader loader = mock(ProfileLoader.class);
     Project project = new Project("project");
     RulesProfile profile = RulesProfile.create();
-    when(loader.load(project)).thenReturn(profile);
+    when(loader.load(eq(project), any(Settings.class))).thenReturn(profile);
 
-    assertThat(provider.provide(project, loader), is(profile));
-    assertThat(provider.provide(project, loader), is(profile));
-    verify(loader).load(project);
+    assertThat(provider.provide(project, loader, new Settings()), is(profile));
+    assertThat(provider.provide(project, loader, new Settings()), is(profile));
+    verify(loader).load(eq(project), any(Settings.class));
     verifyNoMoreInteractions(loader);
   }
 }
index 7f5b71697f4512add55e6298bd48f765e02021fa..6e6579140b48832e606cbda2ed20ef9bb06385b3 100644 (file)
@@ -21,7 +21,10 @@ package org.sonar.batch.scan;
 
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.api.config.Settings;
 import org.sonar.api.platform.ComponentContainer;
+import org.sonar.batch.ProjectConfigurator;
 import org.sonar.batch.bootstrap.TaskContainer;
 import org.sonar.batch.phases.Phases;
 
@@ -39,6 +42,7 @@ public class ScanTaskTest {
   public void should_enable_all_phases() {
     ScanTask task = new ScanTask(mock(TaskContainer.class));
     ComponentContainer projectScanContainer = new ComponentContainer();
+    projectScanContainer.add(mock(ProjectConfigurator.class), mock(ProjectReactor.class), mock(Settings.class));
     task.scan(projectScanContainer);
 
     Phases phases = projectScanContainer.getComponentByType(Phases.class);