import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.TimeMachine;
import org.sonar.api.batch.TimeMachineQuery;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
+import org.sonar.batch.index.DefaultIndex;
import javax.persistence.Query;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
public class DefaultTimeMachine implements TimeMachine {
private DatabaseSession session;
- private SonarIndex index;
+ private DefaultIndex index;
private MetricFinder metricFinder;
- public DefaultTimeMachine(DatabaseSession session, SonarIndex index, MetricFinder metricFinder) {
+ public DefaultTimeMachine(DatabaseSession session, DefaultIndex index, MetricFinder metricFinder) {
this.session = session;
this.index = index;
this.metricFinder = metricFinder;
return installed;
}
- public void installTaskExtensions(ComponentContainer container, boolean requiringProject) {
+ 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();
container.addExtension(metadata, plugin);
for (Object extension : plugin.getExtensions()) {
- installTaskExtension(container, metadata, extension, requiringProject);
- if (requiringProject) {
+ 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, requiringProject);
- if (requiringProject) {
+ executeTaskExtensionProvider(container, provider, projectPresent);
+ if (projectPresent) {
executeBatchExtensionProvider(container, InstantiationStrategy.PER_BATCH, dryRun, provider);
}
}
}
}
- boolean installTaskExtension(ComponentContainer container, @Nullable PluginMetadata plugin, Object extension, boolean requiringProject) {
+ boolean installTaskExtension(ComponentContainer container, @Nullable PluginMetadata plugin, Object extension, boolean projectPresent) {
boolean installed;
if (ExtensionUtils.isTaskExtension(extension) &&
- (requiringProject == ExtensionUtils.requiresProject(extension)) &&
+ (projectPresent || !ExtensionUtils.requiresProject(extension)) &&
ExtensionUtils.supportsEnvironment(extension, environment)) {
logInstallExtension("task", plugin, extension);
container.addExtension(plugin, extension);
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.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metrics;
-import org.sonar.api.task.TaskExtension;
import java.util.List;
-public class MetricProvider extends ExtensionProvider implements TaskExtension {
+@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
+public class MetricProvider extends ExtensionProvider implements BatchExtension {
private Metrics[] factories;
+++ /dev/null
-/*
- * 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.BatchExtensionDictionnary;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.database.model.Snapshot;
-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;
-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.local.DryRunExporter;
-import org.sonar.batch.phases.Phases;
-import org.sonar.batch.phases.PhasesTimeProfiler;
-import org.sonar.batch.scan.LastSnapshots;
-import org.sonar.batch.scan.filesystem.DeprecatedFileSystemAdapter;
-import org.sonar.batch.scan.filesystem.ExclusionFilters;
-import org.sonar.batch.scan.filesystem.FileSystemLogger;
-import org.sonar.batch.scan.filesystem.LanguageFilters;
-import org.sonar.batch.scan.filesystem.ModuleFileSystemProvider;
-import org.sonar.jpa.dao.ProfilesDao;
-import org.sonar.jpa.dao.RulesDao;
-
-public abstract class ModuleContainer extends Container {
-
- private Project project;
- private ProjectDefinition projectDefinition;
- private Snapshot snapshot;
-
- public ModuleContainer(Project project, ProjectDefinition projectDefinition, Snapshot snapshot) {
- this.project = project;
- this.projectDefinition = projectDefinition;
- this.snapshot = snapshot;
- }
-
- @Override
- protected void configure() {
- addCoreComponents();
- addPluginExtensions();
- }
-
- private void addCoreComponents() {
- container.addSingleton(projectDefinition);
- container.addSingleton(project.getConfiguration());
- container.addSingleton(project);
- for (Object component : projectDefinition.getContainerExtensions()) {
- container.addSingleton(component);
- }
- // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
- container.addSingleton(snapshot);
-
- 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);
-
- container.addSingleton(RulesDao.class);
- container.addSingleton(LastSnapshots.class);
- container.addSingleton(Languages.class);
-
- // file system
- container.addSingleton(PathResolver.class);
- container.addSingleton(FileExclusions.class);
- container.addSingleton(LanguageFilters.class);
- container.addSingleton(ExclusionFilters.class);
- container.addSingleton(DefaultProjectClasspath.class);
- container.addPicoAdapter(new ModuleFileSystemProvider());
- container.addSingleton(DeprecatedFileSystemAdapter.class);
- container.addSingleton(FileSystemLogger.class);
-
- 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(DefaultProfileLoader.class);
- container.addSingleton(DryRunExporter.class);
- }
-
- private void addPluginExtensions() {
- ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
- installer.installInspectionExtensions(container);
- }
-
-}
+++ /dev/null
-/*
- * 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.config.EmailSettings;
-import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.task.Task;
-import org.sonar.api.task.TaskDefinition;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.DefaultResourceCreationLock;
-import org.sonar.batch.ProjectConfigurator;
-import org.sonar.batch.components.PastMeasuresLoader;
-import org.sonar.batch.components.PastSnapshotFinder;
-import org.sonar.batch.components.PastSnapshotFinderByDate;
-import org.sonar.batch.components.PastSnapshotFinderByDays;
-import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis;
-import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion;
-import org.sonar.batch.components.PastSnapshotFinderByVersion;
-import org.sonar.batch.index.DefaultPersistenceManager;
-import org.sonar.batch.index.DefaultResourcePersister;
-import org.sonar.batch.index.DependencyPersister;
-import org.sonar.batch.index.EventPersister;
-import org.sonar.batch.index.LinkPersister;
-import org.sonar.batch.index.MeasurePersister;
-import org.sonar.batch.index.MemoryOptimizer;
-import org.sonar.batch.index.SourcePersister;
-import org.sonar.batch.tasks.ListTasksTask;
-import org.sonar.core.i18n.I18nManager;
-import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.core.metric.CacheMetricFinder;
-import org.sonar.core.notification.DefaultNotificationManager;
-import org.sonar.core.persistence.DaoUtils;
-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.qualitymodel.DefaultModelFinder;
-import org.sonar.core.resource.DefaultResourcePermissions;
-import org.sonar.core.rule.CacheRuleFinder;
-import org.sonar.core.user.DefaultUserFinder;
-import org.sonar.jpa.dao.MeasuresDao;
-import org.sonar.jpa.session.DefaultDatabaseConnector;
-import org.sonar.jpa.session.JpaDatabaseSession;
-
-/**
- * Level-3 components. Task-level components that don't depends on project.
- */
-public class ProjectLessTaskContainer extends Container {
-
- private static final Logger LOG = LoggerFactory.getLogger(ProjectLessTaskContainer.class);
-
- private TaskDefinition taskDefinition;
-
- private boolean projectPresent;
-
- public ProjectLessTaskContainer(TaskDefinition task, boolean projectPresent) {
- this.taskDefinition = task;
- this.projectPresent = projectPresent;
- }
-
- @Override
- protected void configure() {
- registerCoreComponents();
- registerDatabaseComponents();
- registerCoreProjectLessTasks();
- registerProjectLessTaskExtensions();
- if (projectPresent && ExtensionUtils.requiresProject(taskDefinition.getTask())) {
- container.addSingleton(ProjectExclusions.class);
- container.addSingleton(ProjectReactorReady.class);
- container.addSingleton(DryRunDatabase.class);
- }
- }
-
- private void registerCoreComponents() {
- container.addSingleton(EmailSettings.class);
- container.addSingleton(I18nManager.class);
- container.addSingleton(RuleI18nManager.class);
- container.addSingleton(MeasuresDao.class);
- container.addSingleton(CacheRuleFinder.class);
- container.addSingleton(CacheMetricFinder.class);
- container.addSingleton(DefaultUserFinder.class);
- container.addSingleton(ResourceTypes.class);
- container.addSingleton(SemaphoreUpdater.class);
- container.addSingleton(SemaphoresImpl.class);
- container.addSingleton(PastSnapshotFinderByDate.class);
- container.addSingleton(PastSnapshotFinderByDays.class);
- container.addSingleton(PastSnapshotFinderByPreviousAnalysis.class);
- container.addSingleton(PastSnapshotFinderByVersion.class);
- container.addSingleton(PastSnapshotFinderByPreviousVersion.class);
- container.addSingleton(PastMeasuresLoader.class);
- container.addSingleton(PastSnapshotFinder.class);
- container.addSingleton(DefaultModelFinder.class);
- container.addSingleton(MetricProvider.class);
- container.addSingleton(DefaultResourceCreationLock.class);
- container.addSingleton(DefaultPersistenceManager.class);
- container.addSingleton(DependencyPersister.class);
- container.addSingleton(EventPersister.class);
- container.addSingleton(LinkPersister.class);
- container.addSingleton(MeasurePersister.class);
- container.addSingleton(MemoryOptimizer.class);
- container.addSingleton(DefaultResourcePermissions.class);
- container.addSingleton(DefaultResourcePersister.class);
- container.addSingleton(SourcePersister.class);
- container.addSingleton(DefaultNotificationManager.class);
- container.addSingleton(ProjectConfigurator.class);
- }
-
- private void registerDatabaseComponents() {
- container.addSingleton(JdbcDriverHolder.class);
- container.addSingleton(BatchDatabase.class);
- container.addSingleton(MyBatis.class);
- container.addSingleton(DatabaseVersion.class);
- container.addSingleton(DatabaseCompatibility.class);
- for (Class daoClass : DaoUtils.getDaoClasses()) {
- container.addSingleton(daoClass);
- }
-
- // hibernate
- container.addSingleton(DefaultDatabaseConnector.class);
- container.addSingleton(JpaDatabaseSession.class);
- container.addSingleton(BatchDatabaseSessionFactory.class);
- }
-
- private void registerCoreProjectLessTasks() {
- container.addSingleton(ListTasksTask.class);
- }
-
- private void registerProjectLessTaskExtensions() {
- ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
- installer.installTaskExtensions(container, false);
- }
-
- private void logSettings() {
- LOG.info("------------- Executing {}", taskDefinition.getName());
- }
-
- /**
- * Execute task
- */
- @Override
- protected void doStart() {
- if (ExtensionUtils.requiresProject(taskDefinition.getTask())) {
- if (!projectPresent) {
- throw new SonarException("Task '" + taskDefinition.getName() + "' requires to be run on a project");
- }
- // Create a new child container to put project specific components
- Container childModule = new ProjectTaskContainer(taskDefinition);
- try {
- installChild(childModule);
- childModule.start();
- } finally {
- childModule.stop();
- uninstallChild();
- }
- }
- else {
- Task task = container.getComponentByType(taskDefinition.getTask());
- if (task != null) {
- logSettings();
- task.execute();
- } else {
- throw new SonarException("Extension " + taskDefinition.getTask() + " was not found in declared extensions.");
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * 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.task.Task;
-import org.sonar.api.task.TaskDefinition;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.DefaultFileLinesContextFactory;
-import org.sonar.batch.ProjectTree;
-import org.sonar.batch.index.DefaultIndex;
-import org.sonar.batch.scan.ScanTask;
-import org.sonar.core.component.ScanGraph;
-import org.sonar.core.component.ScanGraphStore;
-import org.sonar.core.component.ScanPerspectives;
-import org.sonar.core.test.TestPlanBuilder;
-import org.sonar.core.test.TestableBuilder;
-
-/**
- * Level-4 components. Task-level components that depends on project.
- */
-public class ProjectTaskContainer extends Container {
-
- private static final Logger LOG = LoggerFactory.getLogger(ProjectTaskContainer.class);
-
- private TaskDefinition taskDefinition;
-
- public ProjectTaskContainer(TaskDefinition task) {
- this.taskDefinition = task;
- }
-
- @Override
- protected void configure() {
- registerCoreProjectTasks();
- registerCoreComponentsRequiringProject();
- registerProjectTaskExtensions();
- registerOverrideAbleComponents();
- }
-
- private void registerCoreProjectTasks() {
- container.addSingleton(ScanTask.class);
- }
-
- private void registerProjectTaskExtensions() {
- ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
- installer.installTaskExtensions(container, true);
- }
-
- private void registerCoreComponentsRequiringProject() {
- container.addSingleton(ProjectTree.class);
- container.addSingleton(DefaultFileLinesContextFactory.class);
-
- // graphs
- container.addSingleton(ScanGraph.create());
- container.addSingleton(TestPlanBuilder.class);
- container.addSingleton(TestableBuilder.class);
- container.addSingleton(ScanPerspectives.class);
- container.addSingleton(ScanGraphStore.class);
- }
-
- /**
- * In order for instance for the plugin Views to override some components
- */
- protected void registerOverrideAbleComponents(){
- container.addSingleton(DefaultIndex.class);
- container.addSingleton(ProjectLock.class);
- }
-
- private void logSettings() {
- LOG.info("------------- Executing {}", taskDefinition.getName());
- }
-
- /**
- * Execute task
- */
- @Override
- protected void doStart() {
- Task task = container.getComponentByType(taskDefinition.getTask());
- if (task != null) {
- logSettings();
- task.execute();
- } else {
- throw new SonarException("Extension " + taskDefinition.getTask() + " was not found in declared extensions.");
- }
- }
-
-}
}
private void executeTask(TaskDefinition taskDefinition) {
- boolean projectPresent = (container.getComponentByType(ProjectReactor.class) != null);
+ boolean projectPresent = container.getComponentByType(ProjectReactor.class) != null;
if (ExtensionUtils.requiresProject(taskDefinition.getTask()) && !projectPresent) {
throw new SonarException("Task '" + taskDefinition.getName() + "' requires to be run on a project");
}
- Container childModule = new ProjectLessTaskContainer(taskDefinition, projectPresent);
+ Container childModule = new TaskContainer(taskDefinition, projectPresent);
try {
installChild(childModule);
childModule.start();
--- /dev/null
+/*
+ * 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.config.EmailSettings;
+import org.sonar.api.resources.ResourceTypes;
+import org.sonar.api.task.Task;
+import org.sonar.api.task.TaskDefinition;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.DefaultFileLinesContextFactory;
+import org.sonar.batch.DefaultResourceCreationLock;
+import org.sonar.batch.ProjectConfigurator;
+import org.sonar.batch.ProjectTree;
+import org.sonar.batch.components.PastMeasuresLoader;
+import org.sonar.batch.components.PastSnapshotFinder;
+import org.sonar.batch.components.PastSnapshotFinderByDate;
+import org.sonar.batch.components.PastSnapshotFinderByDays;
+import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis;
+import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion;
+import org.sonar.batch.components.PastSnapshotFinderByVersion;
+import org.sonar.batch.index.DefaultIndex;
+import org.sonar.batch.index.DefaultPersistenceManager;
+import org.sonar.batch.index.DefaultResourcePersister;
+import org.sonar.batch.index.DependencyPersister;
+import org.sonar.batch.index.EventPersister;
+import org.sonar.batch.index.LinkPersister;
+import org.sonar.batch.index.MeasurePersister;
+import org.sonar.batch.index.MemoryOptimizer;
+import org.sonar.batch.index.SourcePersister;
+import org.sonar.batch.scan.ScanTask;
+import org.sonar.batch.tasks.ListTasksTask;
+import org.sonar.core.component.ScanGraph;
+import org.sonar.core.component.ScanGraphStore;
+import org.sonar.core.component.ScanPerspectives;
+import org.sonar.core.i18n.I18nManager;
+import org.sonar.core.i18n.RuleI18nManager;
+import org.sonar.core.metric.CacheMetricFinder;
+import org.sonar.core.notification.DefaultNotificationManager;
+import org.sonar.core.persistence.DaoUtils;
+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.resource.DefaultResourcePermissions;
+import org.sonar.core.rule.CacheRuleFinder;
+import org.sonar.core.test.TestPlanBuilder;
+import org.sonar.core.test.TestableBuilder;
+import org.sonar.core.user.DefaultUserFinder;
+import org.sonar.jpa.dao.MeasuresDao;
+import org.sonar.jpa.session.DefaultDatabaseConnector;
+import org.sonar.jpa.session.JpaDatabaseSession;
+
+/**
+ * Level-3 components. Task-level components that don't depends on project.
+ */
+public class TaskContainer extends Container {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TaskContainer.class);
+
+ private TaskDefinition taskDefinition;
+ private boolean projectPresent;
+
+ public TaskContainer(TaskDefinition task, boolean projectPresent) {
+ this.taskDefinition = task;
+ this.projectPresent = projectPresent;
+ }
+
+ @Override
+ protected void configure() {
+ logSettings();
+ registerCoreComponents();
+ registerDatabaseComponents();
+ registerCoreTasks();
+ if (projectPresent) {
+ registerCoreComponentsRequiringProject();
+ }
+ registerTaskExtensions();
+ }
+
+ private void registerCoreComponents() {
+ container.addSingleton(EmailSettings.class);
+ container.addSingleton(I18nManager.class);
+ container.addSingleton(RuleI18nManager.class);
+ container.addSingleton(MeasuresDao.class);
+ container.addSingleton(CacheRuleFinder.class);
+ container.addSingleton(CacheMetricFinder.class);
+ container.addSingleton(DefaultUserFinder.class);
+ container.addSingleton(ResourceTypes.class);
+ container.addSingleton(SemaphoreUpdater.class);
+ container.addSingleton(SemaphoresImpl.class);
+ container.addSingleton(PastSnapshotFinderByDate.class);
+ container.addSingleton(PastSnapshotFinderByDays.class);
+ container.addSingleton(PastSnapshotFinderByPreviousAnalysis.class);
+ container.addSingleton(PastSnapshotFinderByVersion.class);
+ container.addSingleton(PastSnapshotFinderByPreviousVersion.class);
+ container.addSingleton(PastMeasuresLoader.class);
+ container.addSingleton(PastSnapshotFinder.class);
+ }
+
+ private void registerDatabaseComponents() {
+ container.addSingleton(JdbcDriverHolder.class);
+ container.addSingleton(BatchDatabase.class);
+ container.addSingleton(MyBatis.class);
+ container.addSingleton(DatabaseVersion.class);
+ container.addSingleton(DatabaseCompatibility.class);
+ for (Class daoClass : DaoUtils.getDaoClasses()) {
+ container.addSingleton(daoClass);
+ }
+
+ // hibernate
+ container.addSingleton(DefaultDatabaseConnector.class);
+ container.addSingleton(JpaDatabaseSession.class);
+ container.addSingleton(BatchDatabaseSessionFactory.class);
+ }
+
+ private void registerCoreTasks() {
+ container.addSingleton(ListTasksTask.class);
+ if (projectPresent) {
+ container.addSingleton(ScanTask.class);
+ }
+ }
+
+ private void registerTaskExtensions() {
+ ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
+ installer.installTaskExtensions(container, projectPresent);
+ }
+
+ private void registerCoreComponentsRequiringProject() {
+ container.addSingleton(DefaultResourceCreationLock.class);
+ container.addSingleton(DefaultPersistenceManager.class);
+ container.addSingleton(DependencyPersister.class);
+ container.addSingleton(EventPersister.class);
+ container.addSingleton(LinkPersister.class);
+ container.addSingleton(MeasurePersister.class);
+ container.addSingleton(MemoryOptimizer.class);
+ container.addSingleton(DefaultResourcePermissions.class);
+ container.addSingleton(DefaultResourcePersister.class);
+ container.addSingleton(SourcePersister.class);
+ container.addSingleton(DefaultNotificationManager.class);
+ container.addSingleton(MetricProvider.class);
+ container.addSingleton(ProjectExclusions.class);
+ container.addSingleton(ProjectReactorReady.class);
+ container.addSingleton(ProjectTree.class);
+ container.addSingleton(ProjectConfigurator.class);
+ container.addSingleton(DefaultIndex.class);
+ container.addSingleton(DefaultFileLinesContextFactory.class);
+ container.addSingleton(ProjectLock.class);
+ container.addSingleton(DryRunDatabase.class);
+
+ // graphs
+ container.addSingleton(ScanGraph.create());
+ container.addSingleton(TestPlanBuilder.class);
+ container.addSingleton(TestableBuilder.class);
+ container.addSingleton(ScanPerspectives.class);
+ container.addSingleton(ScanGraphStore.class);
+ }
+
+ private void logSettings() {
+ LOG.info("------------- Executing {}", taskDefinition.getName());
+ }
+
+ /**
+ * Execute task
+ */
+ @Override
+ protected void doStart() {
+ Task task = container.getComponentByType(taskDefinition.getTask());
+ if (task != null) {
+ task.execute();
+ } else {
+ throw new SonarException("Extension " + taskDefinition.getTask() + " was not found in declared extensions.");
+ }
+ }
+
+}
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.database.model.Snapshot;
import org.sonar.api.profiles.RulesProfile;
+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;
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.ModuleContainer;
+import org.sonar.batch.bootstrap.Container;
+import org.sonar.batch.bootstrap.ExtensionInstaller;
+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.batch.scan.filesystem.DeprecatedFileSystemAdapter;
+import org.sonar.batch.scan.filesystem.ExclusionFilters;
+import org.sonar.batch.scan.filesystem.FileSystemLogger;
+import org.sonar.batch.scan.filesystem.LanguageFilters;
+import org.sonar.batch.scan.filesystem.ModuleFileSystemProvider;
+import org.sonar.core.qualitymodel.DefaultModelFinder;
+import org.sonar.jpa.dao.ProfilesDao;
+import org.sonar.jpa.dao.RulesDao;
-public class ScanContainer extends ModuleContainer {
+public class ScanContainer extends Container {
private static final Logger LOG = LoggerFactory.getLogger(ScanContainer.class);
private Project project;
- public ScanContainer(Project project, ProjectDefinition projectDefinition, Snapshot snapshot) {
- super(project, projectDefinition, snapshot);
+ public ScanContainer(Project project) {
this.project = project;
}
@Override
protected void configure() {
- super.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(RulesDao.class);
+ container.addSingleton(LastSnapshots.class);
+
+ // file system
+ container.addSingleton(PathResolver.class);
+ container.addSingleton(FileExclusions.class);
+ container.addSingleton(LanguageFilters.class);
+ container.addSingleton(ExclusionFilters.class);
+ container.addSingleton(DefaultProjectClasspath.class);
+ container.addPicoAdapter(new ModuleFileSystemProvider());
+ container.addSingleton(DeprecatedFileSystemAdapter.class);
+ container.addSingleton(FileSystemLogger.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.addPicoAdapter(new ProfileProvider());
}
+ private void addPluginExtensions() {
+ ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
+ installer.installInspectionExtensions(container);
+ }
+
private void logSettings() {
LOG.info("------------- Inspecting {}", project.getName());
}
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(ResourceFilters.class),
+ container.getComponentByType(ViolationFilters.class),
+ container.getComponentByType(RulesProfile.class));
- logSettings();
container.getComponentByType(Phases.class).execute(project);
}
}
package org.sonar.batch.scan;
import com.google.common.annotations.VisibleForTesting;
-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.task.Task;
import org.sonar.api.task.TaskDefinition;
import org.sonar.batch.ProjectTree;
-import org.sonar.batch.index.ResourcePersister;
import org.sonar.batch.tasks.RequiresProject;
@RequiresProject
@VisibleForTesting
void scan(Project project) {
- ProjectDefinition projectDefinition = container.getComponentByType(ProjectTree.class).getProjectDefinition(project);
- Snapshot snapshot = container.getComponentByType(ResourcePersister.class).getSnapshot(project);
- ScanContainer projectModule = new ScanContainer(project, projectDefinition, snapshot);
+ ScanContainer projectModule = new ScanContainer(project);
try {
ComponentContainer childContainer = container.createChild();
projectModule.init(childContainer);
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.resources.Project;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import static org.fest.assertions.Assertions.assertThat;
+
public class BootstrapContainerTest {
private ProjectReactor reactor = new ProjectReactor(ProjectDefinition.create());
assertThat(module.container).isNotNull();
assertThat(module.container.getComponentByType(FakeComponent.class)).isNotNull();
+ assertThat(module.container.getComponentByType(ProjectReactor.class)).isSameAs(reactor);
}
@Test
module.init();
assertThat(module.container).isNotNull();
+ assertThat(module.container.getComponentByType(ProjectReactor.class)).isSameAs(reactor);
}
public static class FakeComponent {
public void execute(Project project, DefaultModuleFileSystem fs, String goal) {
}
- public MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) {
+ public MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) {
return handler;
}
}
}
@Test
- public void shouldInstallProjectTaskExtensions() {
+ public void shouldInstallTaskExtensions() {
BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class);
when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(SampleProjectTask.class, SampleTask.class, TaskProvider.class));
ComponentContainer container = new ComponentContainer();
installer.installTaskExtensions(container, true);
assertThat(container.getComponentByType(SampleProjectTask.class)).isNotNull();
- assertThat(container.getComponentByType(SampleTask.class)).isNull();
- assertThat(container.getComponentByType(AnotherTask.class)).isNull();
+ assertThat(container.getComponentByType(SampleTask.class)).isNotNull();
+ assertThat(container.getComponentByType(AnotherTask.class)).isNotNull();
}
@Test
- public void shouldInstallProjectLessTaskExtensions() {
+ public void shouldNotInstallProjectTaskExtensionsWhenNoProject() {
BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class);
- when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(SampleProjectTask.class, SampleTask.class, TaskProvider.class));
+ when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(SampleProjectTask.class, SampleTask.class));
ComponentContainer container = new ComponentContainer();
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
assertThat(container.getComponentByType(SampleProjectTask.class)).isNull();
assertThat(container.getComponentByType(SampleTask.class)).isNotNull();
- assertThat(container.getComponentByType(AnotherTask.class)).isNotNull();
}
@Test
}
};
bootstrapModule.init();
- ProjectTaskContainer module = new ProjectTaskContainer(TaskDefinition.create());
+ TaskContainer module = new TaskContainer(TaskDefinition.create(), true);
bootstrapModule.installChild(module);
verify(extensionInstaller).installTaskExtensions(any(ComponentContainer.class), eq(true));
}
};
bootstrapModule.init();
- ProjectLessTaskContainer module = new ProjectLessTaskContainer(TaskDefinition.create(), false);
+ TaskContainer module = new TaskContainer(TaskDefinition.create(), false);
bootstrapModule.installChild(module);
verify(extensionInstaller).installTaskExtensions(any(ComponentContainer.class), eq(false));
import org.apache.commons.configuration.PropertiesConfiguration;
import org.fest.assertions.Assertions;
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.bootstrap.BatchSettings;
import org.sonar.batch.bootstrap.Container;
import org.sonar.batch.bootstrap.ExtensionInstaller;
import org.sonar.batch.bootstrap.ProjectSettings;
+import org.sonar.batch.index.ResourcePersister;
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 ScanContainerTest {
@Test
// 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);
Container batchModule = new Container() {
@Override
protected void configure() {
container.addSingleton(extensionInstaller);
+ container.addSingleton(projectTree);
+ container.addSingleton(resourcePersister);
container.addSingleton(new BatchSettings());
}
};
batchModule.init();
- ScanContainer projectModule = new ScanContainer(project, ProjectDefinition.create(), new Snapshot());
+ ScanContainer projectModule = new ScanContainer(project);
batchModule.installChild(projectModule);
verify(extensionInstaller).installInspectionExtensions(any(ComponentContainer.class));
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
-import org.sonar.api.task.TaskExtension;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.api.utils.dag.DirectAcyclicGraph;
return handlers;
}
- private List<BatchExtension> getBatchExtensions() {
+ private List<BatchExtension> getExtensions() {
List<BatchExtension> extensions = Lists.newArrayList();
completeBatchExtensions(componentContainer, extensions);
return extensions;
}
}
- private List<TaskExtension> getTaskExtensions() {
- List<TaskExtension> extensions = Lists.newArrayList();
- completeTaskExtensions(componentContainer, extensions);
- return extensions;
- }
-
- private static void completeTaskExtensions(ComponentContainer container, List<TaskExtension> extensions) {
- if (container != null) {
- extensions.addAll(container.getComponentsByType(TaskExtension.class));
- completeTaskExtensions(container.getParent(), extensions);
- }
- }
-
private <T> List<T> getFilteredExtensions(Class<T> type, Project project) {
List<T> result = Lists.newArrayList();
- for (BatchExtension extension : getBatchExtensions()) {
- if (shouldKeep(type, extension, project)) {
- result.add((T) extension);
- }
- }
- for (TaskExtension extension : getTaskExtensions()) {
+ for (BatchExtension extension : getExtensions()) {
if (shouldKeep(type, extension, project)) {
result.add((T) extension);
}
}
}
+
protected List evaluateAnnotatedClasses(Object extension, Class<? extends Annotation> annotation) {
List<Object> results = Lists.newArrayList();
Class aClass = extension.getClass();
try {
Object result = method.invoke(extension);
if (result != null) {
- // TODO add arrays/collections of objects/classes
+ //TODO add arrays/collections of objects/classes
if (result instanceof Class<?>) {
results.addAll(componentContainer.getComponentsByType((Class<?>) result));
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.BatchExtension;
import org.sonar.api.ServerExtension;
-import org.sonar.api.task.TaskExtension;
+import org.sonar.api.batch.InstantiationStrategy;
import javax.persistence.Column;
import javax.persistence.Entity;
*/
@Table(name = "metrics")
@Entity(name = "Metric")
-public class Metric implements ServerExtension, TaskExtension {
+@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
+public class Metric implements ServerExtension, BatchExtension {
/**
* A metric bigger value means a degradation
*/
package org.sonar.api.measures;
+import org.sonar.api.BatchExtension;
import org.sonar.api.ServerExtension;
-import org.sonar.api.task.TaskExtension;
+import org.sonar.api.batch.InstantiationStrategy;
import java.util.List;
/**
* @since 1.10
*/
-public interface Metrics extends TaskExtension, ServerExtension {
+@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
+public interface Metrics extends BatchExtension, ServerExtension {
List<Metric> getMetrics();
}
*/
package org.sonar.api.qualitymodel;
+import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
-import org.sonar.api.task.TaskComponent;
/**
* @since 2.3
*/
-public interface ModelFinder extends TaskComponent, ServerComponent {
+public interface ModelFinder extends BatchComponent, ServerComponent {
/**
* @return null if the name is not found
/**
* A class to store the list of languages
- *
+ *
* @since 1.10
*/
public class Languages implements BatchComponent, ServerComponent {