]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4069 Refactoring to fix issues with ProjectBuilder
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 16 Jan 2013 10:36:24 +0000 (11:36 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 16 Jan 2013 10:38:00 +0000 (11:38 +0100)
19 files changed:
sonar-batch/src/main/java/org/sonar/batch/bootstrap/AbstractTaskModule.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalyseProjectModule.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/MetricProvider.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/Module.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectTaskModule.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskBootstrapModule.java
sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskDefinition.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskExecutor.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionModule.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionTaskDefinition.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionTaskExecutor.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/AbstractTaskModuleTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalyseProjectModuleTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/InspectionModuleTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectBuilder.java

index e01292dc88f351fc9f0df95fe0ec187eb799ee2e..685623774497f0fcf9d1e8340d2d28acaf6002d1 100644 (file)
@@ -109,6 +109,7 @@ public abstract class AbstractTaskModule extends Module {
     container.addSingleton(DefaultUserFinder.class);
     container.addSingleton(ResourceTypes.class);
     container.addSingleton(SemaphoresImpl.class);
+    container.addSingleton(MetricProvider.class);
   }
 
   private void registerDatabaseComponents() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalyseProjectModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalyseProjectModule.java
deleted file mode 100644 (file)
index 8257522..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.bootstrap;
-
-import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.resources.Project;
-
-public class AnalyseProjectModule extends Module {
-
-  private Project rootProject;
-
-  public AnalyseProjectModule(Project rootProject) {
-    this.rootProject = rootProject;
-  }
-
-  @Override
-  protected void configure() {
-    container.addSingleton(MetricProvider.class);
-
-    registerPerBatchExtensions();
-  }
-
-  private void registerPerBatchExtensions() {
-    ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
-    installer.installBatchExtensions(container, InstantiationStrategy.PER_BATCH);
-  }
-
-  /**
-   * Analyze project
-   */
-  @Override
-  protected void doStart() {
-    analyze(rootProject);
-  }
-
-  private void analyze(Project project) {
-    for (Project subProject : project.getModules()) {
-      analyze(subProject);
-    }
-
-    ProjectModule projectModule = new ProjectModule(project);
-    try {
-      installChild(projectModule);
-      projectModule.start();
-    } finally {
-      projectModule.stop();
-      uninstallChild();
-    }
-  }
-}
index 396a60841d313d266a8305d5bfe6732dc0ab9d68..f34fe6276b7bb90a1e13a6267b3617795e230aed 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.batch.bootstrap;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchComponent;
@@ -99,6 +100,7 @@ public class ExtensionInstaller implements BatchComponent {
   }
 
   public void installTaskExtensions(ComponentContainer container, boolean projectPresent) {
+    boolean dryRun = settings.getBoolean(CoreProperties.DRY_RUN);
     for (Map.Entry<PluginMetadata, Plugin> entry : pluginRepository.getPluginsByMetadata().entrySet()) {
       PluginMetadata metadata = entry.getKey();
       Plugin plugin = entry.getValue();
@@ -106,12 +108,18 @@ public class ExtensionInstaller implements BatchComponent {
       container.addExtension(metadata, plugin);
       for (Object extension : plugin.getExtensions()) {
         installTaskExtension(container, metadata, extension, projectPresent);
+        if (projectPresent) {
+          installBatchExtension(container, metadata, extension, dryRun, InstantiationStrategy.PER_BATCH);
+        }
       }
     }
 
     List<ExtensionProvider> providers = container.getComponentsByType(ExtensionProvider.class);
     for (ExtensionProvider provider : providers) {
       executeTaskExtensionProvider(container, provider, projectPresent);
+      if (projectPresent) {
+        executeBatchExtensionProvider(container, InstantiationStrategy.PER_BATCH, dryRun, provider);
+      }
     }
   }
 
@@ -146,7 +154,12 @@ public class ExtensionInstaller implements BatchComponent {
     return installed;
   }
 
-  public void installBatchExtensions(ComponentContainer container, String instantiationStrategy) {
+  public void installInspectionExtensions(ComponentContainer container) {
+    installBatchExtensions(container, InstantiationStrategy.PER_PROJECT);
+  }
+
+  @VisibleForTesting
+  void installBatchExtensions(ComponentContainer container, String instantiationStrategy) {
     boolean dryRun = settings.getBoolean(CoreProperties.DRY_RUN);
     for (Map.Entry<PluginMetadata, Plugin> entry : pluginRepository.getPluginsByMetadata().entrySet()) {
       PluginMetadata metadata = entry.getKey();
index 9df02c8955957538f86bca0527593ced57755800..0cf3af16bc283515ca3ec45923b5142d18c0a177 100644 (file)
@@ -21,17 +21,15 @@ package org.sonar.batch.bootstrap;
 
 import com.google.common.collect.Lists;
 import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchExtension;
 import org.sonar.api.ExtensionProvider;
-import org.sonar.api.batch.InstantiationStrategy;
+import org.sonar.api.TaskExtension;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.Metrics;
 
 import java.util.List;
 
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class MetricProvider extends ExtensionProvider implements BatchExtension {
+public class MetricProvider extends ExtensionProvider implements TaskExtension {
 
   private Metrics[] factories;
 
index 0b3bfb9c2d32e73915150f981c7440b85dfcf6de..39398129bddec78e741ea76c27d88a931f4eb425 100644 (file)
@@ -28,7 +28,7 @@ import org.sonar.api.platform.ComponentContainer;
  */
 public abstract class Module {
 
-  ComponentContainer container;
+  protected ComponentContainer container;
 
   /**
    * @return this
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java
deleted file mode 100644 (file)
index a966646..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.bootstrap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.BatchExtensionDictionnary;
-import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.api.tests.ProjectTestsImpl;
-import org.sonar.batch.DefaultProfileLoader;
-import org.sonar.batch.DefaultProjectClasspath;
-import org.sonar.batch.DefaultProjectFileSystem2;
-import org.sonar.batch.DefaultSensorContext;
-import org.sonar.batch.DefaultTimeMachine;
-import org.sonar.batch.ProfileProvider;
-import org.sonar.batch.ProjectTree;
-import org.sonar.batch.ResourceFilters;
-import org.sonar.batch.ViolationFilters;
-import org.sonar.batch.components.TimeMachineConfiguration;
-import org.sonar.batch.events.EventBus;
-import org.sonar.batch.index.DefaultIndex;
-import org.sonar.batch.index.ResourcePersister;
-import org.sonar.batch.local.DryRunExporter;
-import org.sonar.batch.phases.Phases;
-import org.sonar.batch.phases.PhasesTimeProfiler;
-import org.sonar.core.qualitymodel.DefaultModelFinder;
-import org.sonar.jpa.dao.ProfilesDao;
-import org.sonar.jpa.dao.RulesDao;
-
-public class ProjectModule extends Module {
-  private static final Logger LOG = LoggerFactory.getLogger(ProjectModule.class);
-  private Project project;
-
-  public ProjectModule(Project project) {
-    this.project = project;
-  }
-
-  @Override
-  protected void configure() {
-    logSettings();
-    addCoreComponents();
-    addPluginExtensions();
-  }
-
-  private void addCoreComponents() {
-    ProjectDefinition projectDefinition = container.getComponentByType(ProjectTree.class).getProjectDefinition(project);
-    container.addSingleton(projectDefinition);
-    container.addSingleton(project.getConfiguration());
-    container.addSingleton(project);
-    container.addSingleton(ProjectSettings.class);
-
-    // hack to initialize commons-configuration before ExtensionProviders
-    container.getComponentByType(ProjectSettings.class);
-
-    container.addSingleton(EventBus.class);
-    container.addSingleton(Phases.class);
-    container.addSingleton(PhasesTimeProfiler.class);
-    for (Class clazz : Phases.getPhaseClasses()) {
-      container.addSingleton(clazz);
-    }
-    container.addSingleton(UnsupportedProperties.class);
-
-    for (Object component : projectDefinition.getContainerExtensions()) {
-      container.addSingleton(component);
-    }
-    container.addSingleton(Languages.class);
-    container.addSingleton(DefaultProjectClasspath.class);
-    container.addSingleton(DefaultProjectFileSystem2.class);
-    container.addSingleton(RulesDao.class);
-
-    // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
-    container.addSingleton(container.getComponentByType(ResourcePersister.class).getSnapshot(project));
-
-    container.addSingleton(TimeMachineConfiguration.class);
-    container.addSingleton(org.sonar.api.database.daos.MeasuresDao.class);
-    container.addSingleton(ProfilesDao.class);
-    container.addSingleton(DefaultSensorContext.class);
-    container.addSingleton(BatchExtensionDictionnary.class);
-    container.addSingleton(DefaultTimeMachine.class);
-    container.addSingleton(ViolationFilters.class);
-    container.addSingleton(ResourceFilters.class);
-    container.addSingleton(DefaultModelFinder.class);
-    container.addSingleton(DefaultProfileLoader.class);
-    container.addSingleton(DryRunExporter.class);
-    container.addSingleton(ProjectTestsImpl.class);
-    container.addPicoAdapter(new ProfileProvider());
-  }
-
-  private void addPluginExtensions() {
-    ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
-    installer.installBatchExtensions(container, InstantiationStrategy.PER_PROJECT);
-  }
-
-  private void logSettings() {
-    // TODO move these logs in a dedicated component
-    LOG.info("-------------  Analyzing {}", project.getName());
-  }
-
-  /**
-   * Analyze project
-   */
-  @Override
-  protected void doStart() {
-    DefaultIndex index = container.getComponentByType(DefaultIndex.class);
-    index.setCurrentProject(project,
-        container.getComponentByType(ResourceFilters.class),
-        container.getComponentByType(ViolationFilters.class),
-        container.getComponentByType(RulesProfile.class));
-
-    container.getComponentByType(Phases.class).execute(project);
-  }
-}
index 124ac8b70bdc224e68a035fd5548b1e3f71817b8..ab727f40fc812378f2278852b6861e33428ad0d4 100644 (file)
@@ -48,4 +48,5 @@ public class ProjectTaskModule extends AbstractTaskModule {
 
     container.addSingleton(DryRunDatabase.class);
   }
+
 }
index 57393008adf8ba351d05b61b72cc49edad7aa165..d4489222d3e9a418343ed237139416c98a9301bb 100644 (file)
@@ -23,7 +23,7 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.api.batch.TaskDefinition;
 import org.sonar.api.batch.bootstrap.ProjectReactor;
 import org.sonar.api.utils.SonarException;
-import org.sonar.batch.tasks.AnalyseProjectTaskDefinition;
+import org.sonar.batch.tasks.InspectionTaskDefinition;
 import org.sonar.batch.tasks.ListTaskDefinition;
 import org.sonar.batch.tasks.TaskManager;
 
@@ -46,7 +46,7 @@ public class TaskBootstrapModule extends Module {
   }
 
   private void registerCoreTaskDefinitions() {
-    container.addSingleton(AnalyseProjectTaskDefinition.class);
+    container.addSingleton(InspectionTaskDefinition.class);
     container.addSingleton(ListTaskDefinition.class);
   }
 
@@ -57,7 +57,7 @@ public class TaskBootstrapModule extends Module {
 
   @Override
   protected void doStart() {
-    String command = StringUtils.isNotBlank(taskCommand) ? taskCommand : AnalyseProjectTaskDefinition.COMMAND;
+    String command = StringUtils.isNotBlank(taskCommand) ? taskCommand : InspectionTaskDefinition.COMMAND;
     TaskManager manager = container.getComponentByType(TaskManager.class);
     executeTask(manager.getTask(command));
   }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskDefinition.java b/sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskDefinition.java
deleted file mode 100644 (file)
index ba8b98d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.tasks;
-
-import org.sonar.api.batch.TaskDefinition;
-import org.sonar.api.batch.TaskDescriptor;
-import org.sonar.api.batch.TaskExecutor;
-
-public class AnalyseProjectTaskDefinition implements TaskDefinition {
-
-  public static final String COMMAND = "analyse-project";
-
-  public TaskDescriptor getTaskDescriptor() {
-    return TaskDescriptor.create()
-        .setDescription("Start a Sonar analysis of a project")
-        .setName("Sonar project analysis")
-        .setCommand(COMMAND)
-        .setRequiresProject(true);
-  }
-
-  public Class<? extends TaskExecutor> getExecutor() {
-    return AnalyseProjectTaskExecutor.class;
-  }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskExecutor.java
deleted file mode 100644 (file)
index fa8936a..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.tasks;
-
-import org.sonar.api.batch.RequiresProject;
-import org.sonar.api.batch.TaskExecutor;
-import org.sonar.api.platform.ComponentContainer;
-import org.sonar.batch.ProjectTree;
-import org.sonar.batch.bootstrap.AnalyseProjectModule;
-
-@RequiresProject
-public class AnalyseProjectTaskExecutor implements TaskExecutor {
-
-  private final ComponentContainer container;
-  private final ProjectTree projectTree;
-
-  public AnalyseProjectTaskExecutor(ProjectTree projectTree, ComponentContainer container) {
-    this.container = container;
-    this.projectTree = projectTree;
-  }
-
-  public void execute() {
-    AnalyseProjectModule analyseProjectModule = new AnalyseProjectModule(projectTree.getRootProject());
-    try {
-      ComponentContainer childContainer = container.createChild();
-      analyseProjectModule.init(childContainer);
-      analyseProjectModule.start();
-    } finally {
-      analyseProjectModule.stop();
-      container.removeChild();
-    }
-  }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionModule.java b/sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionModule.java
new file mode 100644 (file)
index 0000000..116db16
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.tasks;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.BatchExtensionDictionnary;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.Project;
+import org.sonar.api.tests.ProjectTestsImpl;
+import org.sonar.batch.DefaultProfileLoader;
+import org.sonar.batch.DefaultProjectClasspath;
+import org.sonar.batch.DefaultProjectFileSystem2;
+import org.sonar.batch.DefaultSensorContext;
+import org.sonar.batch.DefaultTimeMachine;
+import org.sonar.batch.ProfileProvider;
+import org.sonar.batch.ProjectTree;
+import org.sonar.batch.ResourceFilters;
+import org.sonar.batch.ViolationFilters;
+import org.sonar.batch.bootstrap.ExtensionInstaller;
+import org.sonar.batch.bootstrap.Module;
+import org.sonar.batch.bootstrap.ProjectSettings;
+import org.sonar.batch.bootstrap.UnsupportedProperties;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.events.EventBus;
+import org.sonar.batch.index.DefaultIndex;
+import org.sonar.batch.index.ResourcePersister;
+import org.sonar.batch.local.DryRunExporter;
+import org.sonar.batch.phases.Phases;
+import org.sonar.batch.phases.PhasesTimeProfiler;
+import org.sonar.core.qualitymodel.DefaultModelFinder;
+import org.sonar.jpa.dao.ProfilesDao;
+import org.sonar.jpa.dao.RulesDao;
+
+public class InspectionModule extends Module {
+  private static final Logger LOG = LoggerFactory.getLogger(InspectionModule.class);
+  private Project project;
+
+  public InspectionModule(Project project) {
+    this.project = project;
+  }
+
+  @Override
+  protected void configure() {
+    logSettings();
+    addCoreComponents();
+    addPluginExtensions();
+  }
+
+  private void addCoreComponents() {
+    ProjectDefinition projectDefinition = container.getComponentByType(ProjectTree.class).getProjectDefinition(project);
+    container.addSingleton(projectDefinition);
+    container.addSingleton(project.getConfiguration());
+    container.addSingleton(project);
+    container.addSingleton(ProjectSettings.class);
+
+    // hack to initialize commons-configuration before ExtensionProviders
+    container.getComponentByType(ProjectSettings.class);
+
+    container.addSingleton(EventBus.class);
+    container.addSingleton(Phases.class);
+    container.addSingleton(PhasesTimeProfiler.class);
+    for (Class clazz : Phases.getPhaseClasses()) {
+      container.addSingleton(clazz);
+    }
+    container.addSingleton(UnsupportedProperties.class);
+
+    for (Object component : projectDefinition.getContainerExtensions()) {
+      container.addSingleton(component);
+    }
+    container.addSingleton(Languages.class);
+    container.addSingleton(DefaultProjectClasspath.class);
+    container.addSingleton(DefaultProjectFileSystem2.class);
+    container.addSingleton(RulesDao.class);
+
+    // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
+    container.addSingleton(container.getComponentByType(ResourcePersister.class).getSnapshot(project));
+
+    container.addSingleton(TimeMachineConfiguration.class);
+    container.addSingleton(org.sonar.api.database.daos.MeasuresDao.class);
+    container.addSingleton(ProfilesDao.class);
+    container.addSingleton(DefaultSensorContext.class);
+    container.addSingleton(BatchExtensionDictionnary.class);
+    container.addSingleton(DefaultTimeMachine.class);
+    container.addSingleton(ViolationFilters.class);
+    container.addSingleton(ResourceFilters.class);
+    container.addSingleton(DefaultModelFinder.class);
+    container.addSingleton(DefaultProfileLoader.class);
+    container.addSingleton(DryRunExporter.class);
+    container.addSingleton(ProjectTestsImpl.class);
+    container.addPicoAdapter(new ProfileProvider());
+  }
+
+  private void addPluginExtensions() {
+    ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
+    installer.installInspectionExtensions(container);
+  }
+
+  private void logSettings() {
+    LOG.info("-------------  Inspecting {}", project.getName());
+  }
+
+  /**
+   * Analyze project
+   */
+  @Override
+  protected void doStart() {
+    DefaultIndex index = container.getComponentByType(DefaultIndex.class);
+    index.setCurrentProject(project,
+        container.getComponentByType(ResourceFilters.class),
+        container.getComponentByType(ViolationFilters.class),
+        container.getComponentByType(RulesProfile.class));
+
+    container.getComponentByType(Phases.class).execute(project);
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionTaskDefinition.java b/sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionTaskDefinition.java
new file mode 100644 (file)
index 0000000..0978565
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.tasks;
+
+import org.sonar.api.batch.TaskDefinition;
+import org.sonar.api.batch.TaskDescriptor;
+import org.sonar.api.batch.TaskExecutor;
+
+public class InspectionTaskDefinition implements TaskDefinition {
+
+  public static final String COMMAND = "analyse-project";
+
+  public TaskDescriptor getTaskDescriptor() {
+    return TaskDescriptor.create()
+        .setDescription("Start a Sonar analysis of a project")
+        .setName("Sonar project analysis")
+        .setCommand(COMMAND)
+        .setRequiresProject(true);
+  }
+
+  public Class<? extends TaskExecutor> getExecutor() {
+    return InspectionTaskExecutor.class;
+  }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionTaskExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/tasks/InspectionTaskExecutor.java
new file mode 100644 (file)
index 0000000..9fcb221
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.tasks;
+
+import org.sonar.api.batch.RequiresProject;
+import org.sonar.api.batch.TaskExecutor;
+import org.sonar.api.platform.ComponentContainer;
+import org.sonar.api.resources.Project;
+import org.sonar.batch.ProjectTree;
+
+@RequiresProject
+public class InspectionTaskExecutor implements TaskExecutor {
+
+  private final ComponentContainer container;
+  private final ProjectTree projectTree;
+
+  public InspectionTaskExecutor(ProjectTree projectTree, ComponentContainer container) {
+    this.container = container;
+    this.projectTree = projectTree;
+  }
+
+  public void execute() {
+    analyze(projectTree.getRootProject());
+  }
+
+  private void analyze(Project project) {
+    for (Project subProject : project.getModules()) {
+      analyze(subProject);
+    }
+
+    InspectionModule projectModule = new InspectionModule(project);
+    try {
+      ComponentContainer childContainer = container.createChild();
+      projectModule.init(childContainer);
+      projectModule.start();
+    } finally {
+      projectModule.stop();
+      container.removeChild();
+    }
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AbstractTaskModuleTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AbstractTaskModuleTest.java
new file mode 100644 (file)
index 0000000..6569ce9
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.bootstrap;
+
+import org.junit.Test;
+import org.sonar.api.platform.ComponentContainer;
+import org.sonar.batch.tasks.ListTaskDefinition;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class AbstractTaskModuleTest {
+  @Test
+  public void should_register_task_extensions_when_project_present() {
+    final ExtensionInstaller extensionInstaller = mock(ExtensionInstaller.class);
+    Module bootstrapModule = new Module() {
+      @Override
+      protected void configure() {
+        // used to install project extensions
+        container.addSingleton(extensionInstaller);
+      }
+    };
+    bootstrapModule.init();
+    ProjectTaskModule module = new ProjectTaskModule(new ListTaskDefinition());
+    bootstrapModule.installChild(module);
+
+    verify(extensionInstaller).installTaskExtensions(any(ComponentContainer.class), eq(true));
+  }
+
+  @Test
+  public void should_register_task_extensions_when_no_project() {
+    final ExtensionInstaller extensionInstaller = mock(ExtensionInstaller.class);
+    Module bootstrapModule = new Module() {
+      @Override
+      protected void configure() {
+        // used to install project extensions
+        container.addSingleton(extensionInstaller);
+      }
+    };
+    bootstrapModule.init();
+    ProjectLessTaskModule module = new ProjectLessTaskModule(new ListTaskDefinition());
+    bootstrapModule.installChild(module);
+
+    verify(extensionInstaller).installTaskExtensions(any(ComponentContainer.class), eq(false));
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalyseProjectModuleTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalyseProjectModuleTest.java
deleted file mode 100644 (file)
index 2b47d83..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.bootstrap;
-
-import org.junit.Test;
-import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.platform.ComponentContainer;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class AnalyseProjectModuleTest {
-  @Test
-  public void should_register_batch_extensions() {
-    final ExtensionInstaller extensionInstaller = mock(ExtensionInstaller.class);
-    Module bootstrapModule = new Module() {
-      @Override
-      protected void configure() {
-        // used to install project extensions
-        container.addSingleton(extensionInstaller);
-      }
-    };
-    bootstrapModule.init();
-    AnalyseProjectModule module = new AnalyseProjectModule(null);
-    bootstrapModule.installChild(module);
-
-    verify(extensionInstaller).installBatchExtensions(any(ComponentContainer.class), eq(InstantiationStrategy.PER_BATCH));
-  }
-}
index b8d2a1d9cfff3289dc427513772d5667d593ca3d..deba92ae7fd7e629aa42dd0cfeb20ea9bdfca274 100644 (file)
@@ -94,7 +94,7 @@ public class ExtensionInstallerTest {
     ComponentContainer container = new ComponentContainer();
     ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
 
-    installer.installBatchExtensions(container, InstantiationStrategy.PER_PROJECT);
+    installer.installInspectionExtensions(container);
 
     assertThat(container.getComponentByType(MavenService.class)).isNull();
     assertThat(container.getComponentByType(BuildToolService.class)).isNotNull();
@@ -111,7 +111,7 @@ public class ExtensionInstallerTest {
     container.addSingleton(project);
     ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("maven", "2.2.1"), new Settings());
 
-    installer.installBatchExtensions(container, InstantiationStrategy.PER_PROJECT);
+    installer.installInspectionExtensions(container);
 
     assertThat(container.getComponentByType(MavenService.class)).isNull();
   }
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/InspectionModuleTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/InspectionModuleTest.java
new file mode 100644 (file)
index 0000000..1bc61c5
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.bootstrap;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.platform.ComponentContainer;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.batch.ProjectTree;
+import org.sonar.batch.index.ResourcePersister;
+import org.sonar.batch.tasks.InspectionModule;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class InspectionModuleTest {
+  @Test
+  public void should_register_project_extensions() {
+    // components injected in the parent container
+    final Project project = new Project("foo");
+    project.setConfiguration(new PropertiesConfiguration());
+    final ProjectTree projectTree = mock(ProjectTree.class);
+    when(projectTree.getProjectDefinition(project)).thenReturn(ProjectDefinition.create());
+    final ResourcePersister resourcePersister = mock(ResourcePersister.class);
+    when(resourcePersister.getSnapshot(Matchers.<Resource> any())).thenReturn(new Snapshot());
+
+    final ExtensionInstaller extensionInstaller = mock(ExtensionInstaller.class);
+    Module batchModule = new Module() {
+      @Override
+      protected void configure() {
+        container.addSingleton(extensionInstaller);
+        container.addSingleton(projectTree);
+        container.addSingleton(resourcePersister);
+        container.addSingleton(new BatchSettings());
+      }
+    };
+
+    batchModule.init();
+    InspectionModule projectModule = new InspectionModule(project);
+    batchModule.installChild(projectModule);
+
+    verify(extensionInstaller).installInspectionExtensions(any(ComponentContainer.class));
+    assertThat(projectModule.container.getComponentByType(ProjectSettings.class)).isNotNull();
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java
deleted file mode 100644 (file)
index 6d26b49..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.bootstrap;
-
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.platform.ComponentContainer;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.batch.ProjectTree;
-import org.sonar.batch.index.ResourcePersister;
-
-import static org.fest.assertions.Assertions.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.when;
-
-public class ProjectModuleTest {
-  @Test
-  public void should_register_project_extensions() {
-    // components injected in the parent container
-    final Project project = new Project("foo");
-    project.setConfiguration(new PropertiesConfiguration());
-    final ProjectTree projectTree = mock(ProjectTree.class);
-    when(projectTree.getProjectDefinition(project)).thenReturn(ProjectDefinition.create());
-    final ResourcePersister resourcePersister = mock(ResourcePersister.class);
-    when(resourcePersister.getSnapshot(Matchers.<Resource>any())).thenReturn(new Snapshot());
-
-    final ExtensionInstaller extensionInstaller = mock(ExtensionInstaller.class);
-    Module batchModule = new Module() {
-      @Override
-      protected void configure() {
-        container.addSingleton(extensionInstaller);
-        container.addSingleton(projectTree);
-        container.addSingleton(resourcePersister);
-        container.addSingleton(new BatchSettings());
-      }
-    };
-
-    batchModule.init();
-    ProjectModule projectModule = new ProjectModule(project);
-    batchModule.installChild(projectModule);
-
-    verify(extensionInstaller).installBatchExtensions(any(ComponentContainer.class), eq(InstantiationStrategy.PER_PROJECT));
-    assertThat(projectModule.container.getComponentByType(ProjectSettings.class)).isNotNull();
-  }
-}
index 35a5b10898369e4cc9301f8cf4c804052264d96a..073c47cbec2bc5a1a673d0146a40470e80097b39 100644 (file)
@@ -19,8 +19,8 @@
  */
 package org.sonar.api.batch.bootstrap;
 
-import org.sonar.api.TaskExtension;
-import org.sonar.api.batch.RequiresProject;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.batch.InstantiationStrategy;
 
 /**
  * This extension point allows to change project structure at runtime. It is executed once during task startup.
@@ -34,8 +34,8 @@ import org.sonar.api.batch.RequiresProject;
  *
  * @since 2.9
  */
-@RequiresProject
-public abstract class ProjectBuilder implements TaskExtension {
+@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
+public abstract class ProjectBuilder implements BatchExtension {
 
   private ProjectReactor reactor;