aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/AbstractTaskModule.java (renamed from sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java)65
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalyseProjectModule.java65
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java19
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java44
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java18
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java15
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java121
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java14
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalBatchProperties.java48
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/Module.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectExclusions.java14
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLessTaskModule.java35
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java3
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectTaskModule.java51
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskBootstrapModule.java84
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java29
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java12
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskDefinition.java42
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskExecutor.java49
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/tasks/HelloWorldTask.java48
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/tasks/TaskManager.java42
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalyseProjectModuleTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchModuleTest.java)8
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java24
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java21
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java44
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/TaskDefinitionExtension.java28
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/TaskExtension.java28
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDefinition.java34
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDescriptor.java77
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskExecutor.java32
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb4
34 files changed, 982 insertions, 152 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AbstractTaskModule.java
index bedc8578223..86199c7780d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AbstractTaskModule.java
@@ -19,14 +19,12 @@
*/
package org.sonar.batch.bootstrap;
-import org.sonar.api.batch.InstantiationStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.TaskDefinition;
import org.sonar.api.config.EmailSettings;
-import org.sonar.api.resources.Project;
import org.sonar.api.resources.ResourceTypes;
-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;
@@ -34,7 +32,6 @@ 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;
@@ -48,9 +45,9 @@ 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.SemaphoresImpl;
import org.sonar.core.persistence.DatabaseVersion;
import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.CacheRuleFinder;
import org.sonar.core.user.DefaultUserFinder;
@@ -59,33 +56,39 @@ import org.sonar.jpa.session.DefaultDatabaseConnector;
import org.sonar.jpa.session.JpaDatabaseSession;
/**
- * Level-2 components. Connected to database.
+ * Level-3 components. Task-level components that don't depends on project.
*/
-public class BatchModule extends Module {
+public abstract class AbstractTaskModule extends Module {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractTaskModule.class);
+
+ private TaskDefinition task;
+
+ public AbstractTaskModule(TaskDefinition task) {
+ this.task = task;
+ }
@Override
protected void configure() {
+ logSettings();
+ container.addSingleton(task.getExecutor());
registerCoreComponents();
registerDatabaseComponents();
- registerBatchExtensions();
+ registerTaskExtensions();
}
private void registerCoreComponents() {
container.addSingleton(EmailSettings.class);
container.addSingleton(I18nManager.class);
container.addSingleton(RuleI18nManager.class);
- container.addSingleton(ProjectExclusions.class);
- container.addSingleton(ProjectReactorReady.class);
- container.addSingleton(ProjectTree.class);
- container.addSingleton(ProjectConfigurator.class);
container.addSingleton(DefaultResourceCreationLock.class);
- container.addSingleton(DefaultIndex.class);
- container.addSingleton(DefaultFileLinesContextFactory.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);
@@ -105,12 +108,10 @@ public class BatchModule extends Module {
container.addSingleton(ResourceTypes.class);
container.addSingleton(MetricProvider.class);
container.addSingleton(SemaphoresImpl.class);
- container.addSingleton(ProjectLock.class);
}
private void registerDatabaseComponents() {
container.addSingleton(JdbcDriverHolder.class);
- container.addSingleton(DryRunDatabase.class);
container.addSingleton(BatchDatabase.class);
container.addSingleton(MyBatis.class);
container.addSingleton(DatabaseVersion.class);
@@ -125,29 +126,21 @@ public class BatchModule extends Module {
container.addSingleton(BatchDatabaseSessionFactory.class);
}
- private void registerBatchExtensions() {
+ private void registerTaskExtensions() {
ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
- installer.install(container, InstantiationStrategy.PER_BATCH);
+ installer.installTaskExtensions(container);
+ }
+
+ private void logSettings() {
+ LOG.info("------------- Executing {}", task.getTaskDescriptor().getName());
}
+ /**
+ * Execute task
+ */
@Override
protected void doStart() {
- ProjectTree projectTree = container.getComponentByType(ProjectTree.class);
- analyze(projectTree.getRootProject());
+ container.getComponentByType(task.getExecutor()).execute();
}
- 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();
- }
- }
}
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
new file mode 100644
index 00000000000..7752404cc09
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalyseProjectModule.java
@@ -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.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() {
+ registerBatchExtensions();
+ }
+
+ private void registerBatchExtensions() {
+ 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(rootProject);
+ try {
+ installChild(projectModule);
+ projectModule.start();
+ } finally {
+ projectModule.stop();
+ uninstallChild();
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java
index 4d64d5523c6..351d1564fac 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java
@@ -30,13 +30,20 @@ import java.util.Properties;
public class BatchDatabase extends DefaultDatabase {
public BatchDatabase(Settings settings,
- // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver
- // has been downloaded and injected into classloader
- JdbcDriverHolder jdbcDriverHolder,
+ // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver
+ // has been downloaded and injected into classloader
+ JdbcDriverHolder jdbcDriverHolder,
- // The dependency on DryRunDatabase is required to be sure that the dryRun mode
- // changed settings
- DryRunDatabase dryRun) {
+ // The dependency on DryRunDatabase is required to be sure that the dryRun mode
+ // changed settings
+ DryRunDatabase dryRun) {
+ super(settings);
+ }
+
+ public BatchDatabase(Settings settings,
+ // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver
+ // has been downloaded and injected into classloader
+ JdbcDriverHolder jdbcDriverHolder) {
super(settings);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java
index 811a1f71248..0987d020216 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java
@@ -42,36 +42,56 @@ public class BatchSettings extends Settings {
// module key -> <key,val>
private Map<String, Map<String, String>> moduleProperties = Maps.newHashMap();
+ public BatchSettings(BootstrapSettings bootstrapSettings, PropertyDefinitions propertyDefinitions,
+ ServerClient client, Configuration deprecatedConfiguration, GlobalBatchProperties globalProperties) {
+ this(bootstrapSettings, propertyDefinitions, null, client, deprecatedConfiguration, globalProperties);
+ }
+
public BatchSettings(BootstrapSettings bootstrapSettings, PropertyDefinitions propertyDefinitions, ProjectReactor reactor,
- ServerClient client, Configuration deprecatedConfiguration) {
+ ServerClient client, Configuration deprecatedConfiguration, GlobalBatchProperties globalProperties) {
super(propertyDefinitions);
this.deprecatedConfiguration = deprecatedConfiguration;
- init(bootstrapSettings, reactor, client);
+ init(bootstrapSettings, reactor, client, globalProperties);
}
@VisibleForTesting
BatchSettings() {
}
- private void init(BootstrapSettings bootstrapSettings, ProjectReactor reactor, ServerClient client) {
- LoggerFactory.getLogger(BatchSettings.class).info("Load project settings");
+ private void init(BootstrapSettings bootstrapSettings, ProjectReactor reactor, ServerClient client,
+ GlobalBatchProperties globalProperties) {
+ LoggerFactory.getLogger(BatchSettings.class).info("Load batch settings");
- String branch = bootstrapSettings.getProperty(CoreProperties.PROJECT_BRANCH_PROPERTY);
- String projectKey = reactor.getRoot().getKey();
- if (StringUtils.isNotBlank(branch)) {
- projectKey = String.format("%s:%s", projectKey, branch);
+ if (reactor != null) {
+ String branch = bootstrapSettings.getProperty(CoreProperties.PROJECT_BRANCH_PROPERTY);
+ String projectKey = reactor.getRoot().getKey();
+ if (StringUtils.isNotBlank(branch)) {
+ projectKey = String.format("%s:%s", projectKey, branch);
+ }
+ downloadSettings(client, projectKey);
+ }
+ else {
+ downloadSettings(client, null);
}
- downloadSettings(client, projectKey);
-
// order is important -> bottom-up. The last one overrides all the others.
- addProperties(reactor.getRoot().getProperties());
+ addProperties(globalProperties.getProperties());
+ if (reactor != null) {
+ addProperties(reactor.getRoot().getProperties());
+ }
addEnvironmentVariables();
addSystemProperties();
}
private void downloadSettings(ServerClient client, String projectKey) {
- String jsonText = client.request("/batch_bootstrap/properties?project=" + projectKey);
+ String url;
+ if (StringUtils.isNotBlank(projectKey)) {
+ url = "/batch_bootstrap/properties?project=" + projectKey;
+ }
+ else {
+ url = "/batch_bootstrap/properties";
+ }
+ String jsonText = client.request(url);
List<Map<String, String>> json = (List<Map<String, String>>) JSONValue.parse(jsonText);
for (Map<String, String> jsonProperty : json) {
String key = jsonProperty.get("k");
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
index ee8b60c2058..6e2d80571c6 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
@@ -34,15 +34,27 @@ public class BootstrapModule extends Module {
private Object[] boostrapperComponents;
private ProjectReactor reactor;
+ private GlobalBatchProperties globalProperties;
+ private String taskCommand;
public BootstrapModule(ProjectReactor reactor, Object... boostrapperComponents) {
+ this(new GlobalBatchProperties(), null, reactor, boostrapperComponents);
+ }
+
+ public BootstrapModule(GlobalBatchProperties globalProperties, String taskCommand, ProjectReactor reactor,
+ Object... boostrapperComponents) {
+ this.globalProperties = globalProperties;
+ this.taskCommand = taskCommand;
this.reactor = reactor;
this.boostrapperComponents = boostrapperComponents;
}
@Override
protected void configure() {
- container.addSingleton(reactor);
+ container.addSingleton(globalProperties);
+ if (reactor != null) {
+ container.addSingleton(reactor);
+ }
container.addSingleton(new PropertiesConfiguration());
container.addSingleton(BootstrapSettings.class);
container.addSingleton(ServerClient.class);
@@ -79,7 +91,7 @@ public class BootstrapModule extends Module {
@Override
protected void doStart() {
- Module batchComponents = installChild(new BatchModule());
- batchComponents.start();
+ Module taskBootstrap = installChild(new TaskBootstrapModule(taskCommand));
+ taskBootstrap.start();
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java
index b09b33bddca..616219730ff 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java
@@ -32,15 +32,22 @@ import java.util.Properties;
public class BootstrapSettings {
private Map<String, String> properties;
- public BootstrapSettings(ProjectReactor reactor) {
- init(reactor);
+ public BootstrapSettings(GlobalBatchProperties globalProperties) {
+ init(null, globalProperties);
}
- private void init(ProjectReactor reactor) {
+ public BootstrapSettings(ProjectReactor reactor, GlobalBatchProperties globalProperties) {
+ init(reactor, globalProperties);
+ }
+
+ private void init(ProjectReactor reactor, GlobalBatchProperties globalProperties) {
properties = Maps.newHashMap();
// order is important -> bottom-up. The last one overrides all the others.
- addProperties(reactor.getRoot().getProperties());
+ properties.putAll(globalProperties.getProperties());
+ if (reactor != null) {
+ addProperties(reactor.getRoot().getProperties());
+ }
properties.putAll(System.getenv());
addProperties(System.getProperties());
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java
index b480a2447c7..068a2b69730 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java
@@ -19,6 +19,8 @@
*/
package org.sonar.batch.bootstrap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
import org.sonar.api.CoreProperties;
import org.sonar.api.ExtensionProvider;
@@ -37,6 +39,8 @@ import java.util.Map;
public class ExtensionInstaller implements BatchComponent {
+ private static final Logger LOG = LoggerFactory.getLogger(ExtensionInstaller.class);
+
private BatchPluginRepository pluginRepository;
private EnvironmentInformation environment;
private Settings settings;
@@ -47,7 +51,101 @@ public class ExtensionInstaller implements BatchComponent {
this.settings = settings;
}
- public void install(ComponentContainer container, String instantiationStrategy) {
+ public void installTaskDefinitionExtensions(ComponentContainer container) {
+ for (Map.Entry<PluginMetadata, Plugin> entry : pluginRepository.getPluginsByMetadata().entrySet()) {
+ PluginMetadata metadata = entry.getKey();
+ Plugin plugin = entry.getValue();
+
+ container.addExtension(metadata, plugin);
+ for (Object extension : plugin.getExtensions()) {
+ installTaskDefinition(container, metadata, extension);
+ }
+ }
+
+ List<ExtensionProvider> providers = container.getComponentsByType(ExtensionProvider.class);
+ for (ExtensionProvider provider : providers) {
+ executeTaskDefinitionExtensionProvider(container, provider);
+ }
+ }
+
+ private void executeTaskDefinitionExtensionProvider(ComponentContainer container, ExtensionProvider provider) {
+ Object obj = provider.provide();
+ if (obj instanceof Iterable) {
+ for (Object extension : (Iterable) obj) {
+ installTaskDefinition(container, null, extension);
+ }
+ } else {
+ installTaskDefinition(container, null, obj);
+ }
+ }
+
+ boolean installTaskDefinition(ComponentContainer container, @Nullable PluginMetadata plugin, Object extension) {
+ boolean installed;
+ if (ExtensionUtils.isTaskDefinitionExtension(extension) &&
+ ExtensionUtils.supportsEnvironment(extension, environment)) {
+ if (plugin != null) {
+ LOG.debug("Installing task definition extension {} from plugin {}", extension.toString(), plugin.getKey());
+ }
+ else {
+ LOG.debug("Installing task definition extension {}", extension.toString());
+ }
+ container.addExtension(plugin, extension);
+ installed = true;
+ } else {
+ container.declareExtension(plugin, extension);
+ installed = false;
+ }
+ return installed;
+ }
+
+ public void installTaskExtensions(ComponentContainer container) {
+ for (Map.Entry<PluginMetadata, Plugin> entry : pluginRepository.getPluginsByMetadata().entrySet()) {
+ PluginMetadata metadata = entry.getKey();
+ Plugin plugin = entry.getValue();
+
+ container.addExtension(metadata, plugin);
+ for (Object extension : plugin.getExtensions()) {
+ installTaskExtension(container, metadata, extension);
+ }
+ }
+
+ List<ExtensionProvider> providers = container.getComponentsByType(ExtensionProvider.class);
+ for (ExtensionProvider provider : providers) {
+ executeTaskExtensionProvider(container, provider);
+ }
+ }
+
+ private void executeTaskExtensionProvider(ComponentContainer container, ExtensionProvider provider) {
+ Object obj = provider.provide();
+ if (obj instanceof Iterable) {
+ for (Object extension : (Iterable) obj) {
+ installTaskExtension(container, null, extension);
+ }
+ } else {
+ installTaskExtension(container, null, obj);
+ }
+ }
+
+ boolean installTaskExtension(ComponentContainer container, @Nullable PluginMetadata plugin, Object extension) {
+ boolean installed;
+ if (ExtensionUtils.isTaskExtension(extension) &&
+ ExtensionUtils.supportsEnvironment(extension, environment)) {
+ if (plugin != null) {
+ LOG.debug("Installing task extension {} from plugin {}", extension.toString(), plugin.getKey());
+ }
+ else {
+ LOG.debug("Installing task extension {}", extension.toString());
+ }
+ container.addExtension(plugin, extension);
+ installed = true;
+ } else {
+ container.declareExtension(plugin, extension);
+ installed = false;
+ }
+ return installed;
+ }
+
+ public 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();
@@ -55,35 +153,40 @@ public class ExtensionInstaller implements BatchComponent {
container.addExtension(metadata, plugin);
for (Object extension : plugin.getExtensions()) {
- installExtension(container, metadata, extension, dryRun, instantiationStrategy);
+ installBatchExtension(container, metadata, extension, dryRun, instantiationStrategy);
}
}
List<ExtensionProvider> providers = container.getComponentsByType(ExtensionProvider.class);
for (ExtensionProvider provider : providers) {
- executeProvider(container, instantiationStrategy, dryRun, provider);
+ executeBatchExtensionProvider(container, instantiationStrategy, dryRun, provider);
}
}
- private void executeProvider(ComponentContainer container, String instantiationStrategy, boolean dryRun, ExtensionProvider provider) {
+ private void executeBatchExtensionProvider(ComponentContainer container, String instantiationStrategy, boolean dryRun, ExtensionProvider provider) {
Object obj = provider.provide();
if (obj instanceof Iterable) {
for (Object extension : (Iterable) obj) {
- installExtension(container, null, extension, dryRun, instantiationStrategy);
+ installBatchExtension(container, null, extension, dryRun, instantiationStrategy);
}
} else {
- installExtension(container, null, obj, dryRun, instantiationStrategy);
+ installBatchExtension(container, null, obj, dryRun, instantiationStrategy);
}
}
- boolean installExtension(ComponentContainer container, @Nullable PluginMetadata plugin, Object extension, boolean dryRun, String instantiationStrategy) {
+ boolean installBatchExtension(ComponentContainer container, @Nullable PluginMetadata plugin, Object extension, boolean dryRun, String instantiationStrategy) {
boolean installed;
if (ExtensionUtils.isBatchExtension(extension) &&
ExtensionUtils.supportsEnvironment(extension, environment) &&
(!dryRun || ExtensionUtils.supportsDryRun(extension)) &&
ExtensionUtils.isInstantiationStrategy(extension, instantiationStrategy) &&
!isMavenExtensionOnEmulatedMavenProject(extension, instantiationStrategy, container)) {
-
+ if (plugin != null) {
+ LOG.debug("Installing batch extension {} from plugin {}", extension.toString(), plugin.getKey());
+ }
+ else {
+ LOG.debug("Installing batch extension {}", extension.toString());
+ }
container.addExtension(plugin, extension);
installed = true;
} else {
@@ -101,7 +204,7 @@ public class ExtensionInstaller implements BatchComponent {
static boolean isMavenExtensionOnEmulatedMavenProject(Object extension, String instantiationStrategy, ComponentContainer container) {
if (InstantiationStrategy.PER_PROJECT.equals(instantiationStrategy) && ExtensionUtils.isMavenExtensionOnly(extension)) {
Project project = container.getComponentByType(Project.class);
- return project!=null && project.getPom()==null;
+ return project != null && project.getPom() == null;
}
return false;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java
index 65d50ae8c41..fd6a1ba2252 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java
@@ -22,11 +22,13 @@ package org.sonar.batch.bootstrap;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.BatchExtension;
import org.sonar.api.Extension;
-import org.sonar.core.DryRunIncompatible;
+import org.sonar.api.TaskDefinitionExtension;
+import org.sonar.api.TaskExtension;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.SupportedEnvironment;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
+import org.sonar.core.DryRunIncompatible;
final class ExtensionUtils {
@@ -42,6 +44,14 @@ final class ExtensionUtils {
return InstantiationStrategy.PER_PROJECT.equals(strategy);
}
+ static boolean isTaskDefinitionExtension(Object extension) {
+ return isType(extension, TaskDefinitionExtension.class);
+ }
+
+ static boolean isTaskExtension(Object extension) {
+ return isType(extension, TaskExtension.class);
+ }
+
static boolean isBatchExtension(Object extension) {
return isType(extension, BatchExtension.class);
}
@@ -65,7 +75,7 @@ final class ExtensionUtils {
static boolean isMavenExtensionOnly(Object extension) {
SupportedEnvironment env = AnnotationUtils.getAnnotation(extension, SupportedEnvironment.class);
- return env!=null && env.value().length==1 && StringUtils.equalsIgnoreCase("maven", env.value()[0]);
+ return env != null && env.value().length == 1 && StringUtils.equalsIgnoreCase("maven", env.value()[0]);
}
static boolean isType(Object extension, Class<? extends Extension> extensionClass) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalBatchProperties.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalBatchProperties.java
new file mode 100644
index 00000000000..2eade47658a
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalBatchProperties.java
@@ -0,0 +1,48 @@
+/*
+ * 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 com.google.common.collect.Maps;
+
+import java.util.Map;
+
+/**
+ * Batch properties that are not specific to a project (for example
+ * coming from global configuration file of sonar-runner).
+ * @author Julien HENRY
+ *
+ */
+public class GlobalBatchProperties {
+
+ protected final Map<String, String> properties;
+
+ public GlobalBatchProperties() {
+ this.properties = Maps.newHashMap();
+ }
+
+ public GlobalBatchProperties(Map<String, String> properties) {
+ this.properties = Maps.newHashMap(properties);
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/Module.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/Module.java
index 80567137eff..0b3bfb9c2d3 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/Module.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/Module.java
@@ -40,7 +40,7 @@ public abstract class Module {
/**
* @return this
*/
- private void init(ComponentContainer container) {
+ public final void init(ComponentContainer container) {
this.container = container;
configure();
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectExclusions.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectExclusions.java
index 26f6893c2dd..e2c9c53db01 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectExclusions.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectExclusions.java
@@ -43,8 +43,8 @@ public class ProjectExclusions implements BatchComponent {
private ProjectReactor reactor;
public ProjectExclusions(Settings settings, ProjectReactor reactor,
- // exclusions are applied when the project is completely defined by extensions
- ProjectBuilder[] projectBuilders) {
+ // exclusions are applied when the project is completely defined by extensions
+ ProjectBuilder[] projectBuilders) {
this.settings = settings;
this.reactor = reactor;
}
@@ -54,10 +54,12 @@ public class ProjectExclusions implements BatchComponent {
}
public void start() {
- LOG.info("Apply project exclusions");
- for (ProjectDefinition project : reactor.getProjects()) {
- if (isExcluded(key(project), project == reactor.getRoot())) {
- exclude(project);
+ if (reactor.getProjects().size() > 0 && StringUtils.isNotBlank(reactor.getProjects().get(0).getKey())) {
+ LOG.info("Apply project exclusions");
+ for (ProjectDefinition project : reactor.getProjects()) {
+ if (isExcluded(key(project), project == reactor.getRoot())) {
+ exclude(project);
+ }
}
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLessTaskModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLessTaskModule.java
new file mode 100644
index 00000000000..75f932deeb1
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLessTaskModule.java
@@ -0,0 +1,35 @@
+/*
+ * 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.TaskDefinition;
+
+public class ProjectLessTaskModule extends AbstractTaskModule {
+
+ public ProjectLessTaskModule(TaskDefinition task) {
+ super(task);
+ }
+
+ @Override
+ protected void configure() {
+ super.configure();
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java
index 33a4620a4fc..b0bd127b6d7 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java
@@ -19,6 +19,7 @@
*/
package org.sonar.batch.bootstrap;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
@@ -43,7 +44,7 @@ public class ProjectLock {
}
public void start() {
- if (!isInDryRunMode()) {
+ if (!isInDryRunMode() && StringUtils.isNotBlank(getProject().getKey())) {
Semaphores.Semaphore semaphore = acquire();
if (!semaphore.isLocked()) {
LOG.error(getErrorMessage(semaphore));
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
index 3f58c74ccdf..bb7df9a5ed0 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java
@@ -107,7 +107,7 @@ public class ProjectModule extends Module {
private void addPluginExtensions() {
ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
- installer.install(container, InstantiationStrategy.PER_PROJECT);
+ installer.installBatchExtensions(container, InstantiationStrategy.PER_PROJECT);
}
private void logSettings() {
@@ -122,9 +122,9 @@ public class ProjectModule extends Module {
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));
container.getComponentByType(Phases.class).execute(project);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectTaskModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectTaskModule.java
new file mode 100644
index 00000000000..a7c7d3b97ee
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectTaskModule.java
@@ -0,0 +1,51 @@
+/*
+ * 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.TaskDefinition;
+import org.sonar.batch.DefaultFileLinesContextFactory;
+import org.sonar.batch.ProjectConfigurator;
+import org.sonar.batch.ProjectTree;
+import org.sonar.batch.index.DefaultIndex;
+
+public class ProjectTaskModule extends AbstractTaskModule {
+
+ public ProjectTaskModule(TaskDefinition task) {
+ super(task);
+ }
+
+ @Override
+ protected void configure() {
+ super.configure();
+ registerCoreComponentsRequiringProject();
+ }
+
+ private void registerCoreComponentsRequiringProject() {
+ 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);
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskBootstrapModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskBootstrapModule.java
new file mode 100644
index 00000000000..398ae8ba86e
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskBootstrapModule.java
@@ -0,0 +1,84 @@
+/*
+ * 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.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.HelloWorldTask;
+import org.sonar.batch.tasks.TaskManager;
+
+/**
+ * Level-2 components. Collect tasks definitions.
+ */
+public class TaskBootstrapModule extends Module {
+
+ private String taskCommand;
+
+ public TaskBootstrapModule(String taskCommand) {
+ this.taskCommand = taskCommand;
+ }
+
+ @Override
+ protected void configure() {
+ registerCoreTaskDefinitions();
+ registerTaskDefinitionExtensions();
+ container.addSingleton(TaskManager.class);
+ }
+
+ private void registerCoreTaskDefinitions() {
+ container.addSingleton(AnalyseProjectTaskDefinition.class);
+ container.addSingleton(HelloWorldTask.class);
+ }
+
+ private void registerTaskDefinitionExtensions() {
+ ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class);
+ installer.installTaskDefinitionExtensions(container);
+ }
+
+ @Override
+ protected void doStart() {
+ String command = StringUtils.isNotBlank(taskCommand) ? taskCommand : AnalyseProjectTaskDefinition.COMMAND;
+ TaskManager manager = container.getComponentByType(TaskManager.class);
+ executeTask(manager.getTask(command));
+ }
+
+ private void executeTask(TaskDefinition task) {
+ if (task.getTaskDescriptor().isRequiresProject() && container.getComponentByType(ProjectReactor.class) == null) {
+ throw new SonarException("Task " + task.getTaskDescriptor().getName() + " requires to be run on a project");
+ }
+ Module childModule;
+ if (task.getTaskDescriptor().isRequiresProject()) {
+ childModule = new ProjectTaskModule(task);
+ }
+ else {
+ childModule = new ProjectLessTaskModule(task);
+ }
+ try {
+ installChild(childModule);
+ childModule.start();
+ } finally {
+ childModule.stop();
+ uninstallChild();
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
index 0970bd5bc55..b890f440824 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
@@ -24,11 +24,13 @@ import com.google.common.collect.Maps;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.batch.bootstrap.BootstrapModule;
+import org.sonar.batch.bootstrap.GlobalBatchProperties;
import org.sonar.batch.bootstrap.Module;
import org.sonar.core.PicoUtils;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
/**
* Entry point for batch bootstrappers.
@@ -39,12 +41,18 @@ public final class Batch {
private LoggingConfiguration logging;
private List<Object> components;
+ private Map<String, String> globalProperties = Maps.newHashMap();
+ private String taskCommand;
private ProjectReactor projectReactor;
private Batch(Builder builder) {
components = Lists.newArrayList();
components.addAll(builder.components);
components.add(builder.environment);
+ if (builder.globalProperties != null) {
+ globalProperties.putAll(builder.globalProperties);
+ }
+ this.taskCommand = builder.taskCommand;
projectReactor = builder.projectReactor;
if (builder.isEnableLoggingConfiguration()) {
logging = LoggingConfiguration.create().setProperties(Maps.fromProperties(projectReactor.getRoot().getProperties()));
@@ -70,7 +78,8 @@ public final class Batch {
private void startBatch() {
Module bootstrapModule = null;
try {
- bootstrapModule = new BootstrapModule(projectReactor, components.toArray(new Object[components.size()]));
+ bootstrapModule = new BootstrapModule(new GlobalBatchProperties(globalProperties), taskCommand,
+ projectReactor, components.toArray(new Object[components.size()]));
bootstrapModule.init();
bootstrapModule.start();
} catch (RuntimeException e) {
@@ -87,12 +96,13 @@ public final class Batch {
}
}
-
public static Builder builder() {
return new Builder();
}
public static final class Builder {
+ private Map<String, String> globalProperties;
+ private String taskCommand;
private ProjectReactor projectReactor;
private EnvironmentInformation environment;
private List<Object> components = Lists.newArrayList();
@@ -116,6 +126,16 @@ public final class Batch {
return this;
}
+ public Builder setGlobalProperties(Map<String, String> globalProperties) {
+ this.globalProperties = globalProperties;
+ return this;
+ }
+
+ public Builder setTaskCommand(String taskCommand) {
+ this.taskCommand = taskCommand;
+ return this;
+ }
+
public Builder addComponents(Object... components) {
Collections.addAll(this.components, components);
return this;
@@ -140,9 +160,6 @@ public final class Batch {
}
public Batch build() {
- if (projectReactor == null) {
- throw new IllegalStateException("ProjectReactor is not set");
- }
if (environment == null) {
throw new IllegalStateException("EnvironmentInfo is not set");
}
@@ -152,4 +169,4 @@ public final class Batch {
return new Batch(this);
}
}
-} \ No newline at end of file
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
index 79e4e2db95d..fee88556e8b 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
@@ -89,7 +89,9 @@ public class DefaultIndex extends SonarIndex {
public void start() {
Project rootProject = projectTree.getRootProject();
- doStart(rootProject);
+ if (StringUtils.isNotBlank(rootProject.getKey())) {
+ doStart(rootProject);
+ }
}
void doStart(Project rootProject) {
@@ -463,10 +465,10 @@ public class DefaultIndex extends SonarIndex {
if (!StringUtils.equals(Scopes.PROJECT, resource.getScope())) {
// not a project nor a library
uid = new StringBuilder(ResourceModel.KEY_SIZE)
- .append(project.getKey())
- .append(':')
- .append(resource.getKey())
- .toString();
+ .append(project.getKey())
+ .append(':')
+ .append(resource.getKey())
+ .toString();
}
return uid;
}
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
new file mode 100644
index 00000000000..a1284efe54e
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskDefinition.java
@@ -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 AnalyseProjectTaskDefinition implements TaskDefinition {
+
+ public static final String COMMAND = "analyse-project";
+
+ public TaskDescriptor getTaskDescriptor() {
+ return TaskDescriptor.create()
+ .setDescription("Analysis")
+ .setName("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
new file mode 100644
index 00000000000..4f76e5f72c3
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/tasks/AnalyseProjectTaskExecutor.java
@@ -0,0 +1,49 @@
+/*
+ * 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.TaskExecutor;
+import org.sonar.api.platform.ComponentContainer;
+import org.sonar.batch.ProjectTree;
+import org.sonar.batch.bootstrap.AnalyseProjectModule;
+
+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/HelloWorldTask.java b/sonar-batch/src/main/java/org/sonar/batch/tasks/HelloWorldTask.java
new file mode 100644
index 00000000000..79ec7fbb48f
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/tasks/HelloWorldTask.java
@@ -0,0 +1,48 @@
+/*
+ * 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 HelloWorldTask implements TaskExecutor, TaskDefinition {
+
+ public static final String COMMAND = "hello-world";
+
+ public HelloWorldTask() {
+ }
+
+ public void execute() {
+ System.out.println("HELLO WORLD");
+ }
+
+ public TaskDescriptor getTaskDescriptor() {
+ return TaskDescriptor.create()
+ .setDescription("Hello World")
+ .setName("Hello")
+ .setCommand(COMMAND);
+ }
+
+ public Class<? extends TaskExecutor> getExecutor() {
+ return HelloWorldTask.class;
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/tasks/TaskManager.java b/sonar-batch/src/main/java/org/sonar/batch/tasks/TaskManager.java
new file mode 100644
index 00000000000..c518d2fde96
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/tasks/TaskManager.java
@@ -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.utils.SonarException;
+
+public class TaskManager {
+
+ private final TaskDefinition[] tasks;
+
+ public TaskManager(TaskDefinition[] tasks) {
+ this.tasks = tasks;
+ }
+
+ public TaskDefinition getTask(String command) {
+ for (TaskDefinition task : tasks) {
+ if (command.equals(task.getTaskDescriptor().getCommand())) {
+ return task;
+ }
+ }
+ throw new SonarException("No task found for command: " + command);
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchModuleTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalyseProjectModuleTest.java
index 670c558bd00..2b47d832dea 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchModuleTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalyseProjectModuleTest.java
@@ -23,13 +23,12 @@ import org.junit.Test;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.platform.ComponentContainer;
-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;
-public class BatchModuleTest {
+public class AnalyseProjectModuleTest {
@Test
public void should_register_batch_extensions() {
final ExtensionInstaller extensionInstaller = mock(ExtensionInstaller.class);
@@ -41,10 +40,9 @@ public class BatchModuleTest {
}
};
bootstrapModule.init();
- BatchModule module = new BatchModule();
+ AnalyseProjectModule module = new AnalyseProjectModule(null);
bootstrapModule.installChild(module);
- verify(extensionInstaller).install(any(ComponentContainer.class), eq(InstantiationStrategy.PER_BATCH));
- assertThat(module.container.getComponentByType(MetricProvider.class)).isNotNull();
+ verify(extensionInstaller).installBatchExtensions(any(ComponentContainer.class), eq(InstantiationStrategy.PER_BATCH));
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java
index 59b85e28bfa..8bc15a5756a 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java
@@ -49,42 +49,42 @@ public class BatchSettingsTest {
deprecatedConf = new BaseConfiguration();
client = mock(ServerClient.class);
when(client.request("/batch_bootstrap/properties?project=struts")).thenReturn(
- "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}," +
- "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"jacoco\",\"p\":\"struts\"}," +
- "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"cobertura\",\"p\":\"struts-core\"}]"
- );
- bootstrapSettings = new BootstrapSettings(reactor);
+ "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}," +
+ "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"jacoco\",\"p\":\"struts\"}," +
+ "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"cobertura\",\"p\":\"struts-core\"}]"
+ );
+ bootstrapSettings = new BootstrapSettings(reactor, new GlobalBatchProperties());
}
@Test
public void should_load_system_props() {
System.setProperty("BatchSettingsTest.testSystemProp", "system");
- BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf);
+ BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf, new GlobalBatchProperties());
assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system");
}
@Test
public void should_load_build_props() {
project.setProperty("build.prop", "build");
- BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf);
+ BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf, new GlobalBatchProperties());
assertThat(batchSettings.getString("build.prop")).isEqualTo("build");
}
@Test
public void should_load_global_settings() {
- BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf);
+ BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf, new GlobalBatchProperties());
assertThat(batchSettings.getBoolean("sonar.cpd.cross")).isTrue();
}
@Test
public void should_load_project_root_settings() {
- BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf);
+ BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf, new GlobalBatchProperties());
assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");
}
@Test
public void should_keep_module_settings_for_later() {
- BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf);
+ BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf, new GlobalBatchProperties());
Map<String, String> moduleSettings = batchSettings.getModuleProperties("struts-core");
assertThat(moduleSettings).hasSize(1);
assertThat(moduleSettings.get("sonar.java.coveragePlugin")).isEqualTo("cobertura");
@@ -94,13 +94,13 @@ public class BatchSettingsTest {
public void system_props_should_override_build_props() {
System.setProperty("BatchSettingsTest.testSystemProp", "system");
project.setProperty("BatchSettingsTest.testSystemProp", "build");
- BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf);
+ BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf, new GlobalBatchProperties());
assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system");
}
@Test
public void should_forward_to_deprecated_commons_configuration() {
- BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf);
+ BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), reactor, client, deprecatedConf, new GlobalBatchProperties());
assertThat(deprecatedConf.getString("sonar.cpd.cross")).isEqualTo("true");
assertThat(deprecatedConf.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java
index 9f2d807bff8..bc0af74b2a3 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java
@@ -34,7 +34,7 @@ public class BootstrapSettingsTest {
project.setProperty("foo", "bar");
ProjectReactor reactor = new ProjectReactor(project);
- BootstrapSettings settings = new BootstrapSettings(reactor);
+ BootstrapSettings settings = new BootstrapSettings(reactor, new GlobalBatchProperties());
assertThat(settings.getProperty("foo")).isEqualTo("bar");
}
@@ -46,7 +46,7 @@ public class BootstrapSettingsTest {
System.setProperty("BootstrapSettingsTest.testEnv", "env");
ProjectReactor reactor = new ProjectReactor(project);
- BootstrapSettings settings = new BootstrapSettings(reactor);
+ BootstrapSettings settings = new BootstrapSettings(reactor, new GlobalBatchProperties());
assertThat(settings.getProperty("BootstrapSettingsTest.testEnv")).isEqualTo("env");
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java
index 90f4981efdb..b8d2a1d9cff 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java
@@ -49,12 +49,12 @@ public class ExtensionInstallerTest {
private static Map<PluginMetadata, Plugin> newPlugin(final Class... classes) {
Map<PluginMetadata, Plugin> result = Maps.newHashMap();
result.put(METADATA,
- new SonarPlugin() {
- public List<Class> getExtensions() {
- return Arrays.asList(classes);
+ new SonarPlugin() {
+ public List<Class> getExtensions() {
+ return Arrays.asList(classes);
+ }
}
- }
- );
+ );
return result;
}
@@ -65,7 +65,7 @@ public class ExtensionInstallerTest {
ComponentContainer container = new ComponentContainer();
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
- installer.install(container, InstantiationStrategy.PER_BATCH);
+ installer.installBatchExtensions(container, InstantiationStrategy.PER_BATCH);
assertThat(container.getComponentByType(BatchService.class)).isNotNull();
assertThat(container.getComponentByType(ProjectService.class)).isNull();
@@ -79,14 +79,13 @@ public class ExtensionInstallerTest {
ComponentContainer container = new ComponentContainer();
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
- installer.install(container, InstantiationStrategy.PER_BATCH);
+ installer.installBatchExtensions(container, InstantiationStrategy.PER_BATCH);
assertThat(container.getComponentByType(BatchService.class)).isNotNull();
assertThat(container.getComponentByType(ProjectService.class)).isNull();
assertThat(container.getComponentByType(ServerService.class)).isNull();
}
-
@Test
public void shouldNotInstallPluginsOnNonSupportedEnvironment() {
BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class);
@@ -95,7 +94,7 @@ public class ExtensionInstallerTest {
ComponentContainer container = new ComponentContainer();
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings());
- installer.install(container, InstantiationStrategy.PER_PROJECT);
+ installer.installBatchExtensions(container, InstantiationStrategy.PER_PROJECT);
assertThat(container.getComponentByType(MavenService.class)).isNull();
assertThat(container.getComponentByType(BuildToolService.class)).isNotNull();
@@ -112,7 +111,7 @@ public class ExtensionInstallerTest {
container.addSingleton(project);
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("maven", "2.2.1"), new Settings());
- installer.install(container, InstantiationStrategy.PER_PROJECT);
+ installer.installBatchExtensions(container, InstantiationStrategy.PER_PROJECT);
assertThat(container.getComponentByType(MavenService.class)).isNull();
}
@@ -135,7 +134,7 @@ public class ExtensionInstallerTest {
@Override
public Object provide() {
- return Arrays.<Object>asList(BatchService.class, ServerService.class);
+ return Arrays.<Object> asList(BatchService.class, ServerService.class);
}
}
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
index bf108882e4c..6d26b4978a7 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java
@@ -64,7 +64,7 @@ public class ProjectModuleTest {
ProjectModule projectModule = new ProjectModule(project);
batchModule.installChild(projectModule);
- verify(extensionInstaller).install(any(ComponentContainer.class), eq(InstantiationStrategy.PER_PROJECT));
+ verify(extensionInstaller).installBatchExtensions(any(ComponentContainer.class), eq(InstantiationStrategy.PER_PROJECT));
assertThat(projectModule.container.getComponentByType(ProjectSettings.class)).isNotNull();
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java
index eeb52de2918..653d5f5ff1e 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java
@@ -20,12 +20,11 @@
package org.sonar.batch.bootstrapper;
import org.junit.Test;
-import org.sonar.api.batch.bootstrap.*;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-
public class BatchTest {
@Test
public void testBuilder() {
@@ -36,45 +35,44 @@ public class BatchTest {
private Batch newBatch() {
return Batch.builder()
- .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
- .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
- .addComponent("fake")
- .build();
+ .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
+ .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
+ .addComponent("fake")
+ .build();
}
@Test(expected = IllegalStateException.class)
public void shouldFailIfNoEnvironment() {
Batch.builder()
- .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
- .addComponent("fake")
- .build();
+ .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
+ .addComponent("fake")
+ .build();
}
- @Test(expected = IllegalStateException.class)
- public void shouldFailIfNoProjectReactor() {
+ public void shouldNotFailIfNoProjectReactor() {
Batch.builder()
- .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
- .addComponent("fake")
- .build();
+ .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
+ .addComponent("fake")
+ .build();
}
@Test(expected = IllegalStateException.class)
public void shouldFailIfNullComponents() {
Batch.builder()
- .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
- .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
- .setComponents(null)
- .build();
+ .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
+ .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
+ .setComponents(null)
+ .build();
}
@Test
public void shouldDisableLoggingConfiguration() {
Batch batch = Batch.builder()
- .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
- .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
- .addComponent("fake")
- .setEnableLoggingConfiguration(false)
- .build();
+ .setEnvironment(new EnvironmentInformation("Gradle", "1.0"))
+ .setProjectReactor(new ProjectReactor(org.sonar.api.batch.bootstrap.ProjectDefinition.create()))
+ .addComponent("fake")
+ .setEnableLoggingConfiguration(false)
+ .build();
assertNull(batch.getLoggingConfiguration());
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/TaskDefinitionExtension.java b/sonar-plugin-api/src/main/java/org/sonar/api/TaskDefinitionExtension.java
new file mode 100644
index 00000000000..a01ef69b509
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/TaskDefinitionExtension.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api;
+
+/**
+ * Task definition extension point.
+ *
+ * @since 3.5
+ */
+public interface TaskDefinitionExtension extends Extension {
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/TaskExtension.java b/sonar-plugin-api/src/main/java/org/sonar/api/TaskExtension.java
new file mode 100644
index 00000000000..147d7237d5e
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/TaskExtension.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api;
+
+/**
+ * Task extension point.
+ *
+ * @since 3.5
+ */
+public interface TaskExtension extends Extension {
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDefinition.java
new file mode 100644
index 00000000000..e442a60d45f
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDefinition.java
@@ -0,0 +1,34 @@
+/*
+ * 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.api.batch;
+
+import org.sonar.api.TaskDefinitionExtension;
+
+/**
+ * Implement this interface to provide a new task.
+ * @since 3.5
+ */
+public interface TaskDefinition extends TaskDefinitionExtension {
+
+ TaskDescriptor getTaskDescriptor();
+
+ Class<? extends TaskExecutor> getExecutor();
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDescriptor.java
new file mode 100644
index 00000000000..78cda168eda
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskDescriptor.java
@@ -0,0 +1,77 @@
+/*
+ * 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.api.batch;
+
+/**
+ * Provide description of a task.
+ * @since 3.5
+ */
+public class TaskDescriptor {
+
+ private String name;
+ private String decription;
+ private String command;
+ private boolean requiresProject = false;
+
+ private TaskDescriptor() {
+
+ }
+
+ public static TaskDescriptor create() {
+ return new TaskDescriptor();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public TaskDescriptor setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getDecription() {
+ return decription;
+ }
+
+ public TaskDescriptor setDescription(String decription) {
+ this.decription = decription;
+ return this;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public TaskDescriptor setCommand(String command) {
+ this.command = command;
+ return this;
+ }
+
+ public boolean isRequiresProject() {
+ return requiresProject;
+ }
+
+ public TaskDescriptor setRequiresProject(boolean requiresProject) {
+ this.requiresProject = requiresProject;
+ return this;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskExecutor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskExecutor.java
new file mode 100644
index 00000000000..cb6998b92f7
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/TaskExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * 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.api.batch;
+
+import org.sonar.api.TaskExtension;
+
+/**
+ * Implement this interface to provide the behavior of a task.
+ * @since 3.5
+ */
+public interface TaskExecutor extends TaskExtension {
+
+ void execute();
+
+}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb
index 45fd241e2f4..ebc5a53524f 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb
@@ -32,8 +32,6 @@ class BatchBootstrapController < Api::ApiController
# GET /batch_bootstrap/properties?project=<key or id>
def properties
- require_parameters :project
-
json_properties=Property.find(:all, :conditions => ['user_id is null and resource_id is null']).map { |property| to_json_property(property) }
root_project = load_project()
@@ -71,4 +69,4 @@ class BatchBootstrapController < Api::ApiController
true
end
end
-end \ No newline at end of file
+end