summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Mandrikov <mandrikov@gmail.com>2011-04-09 02:19:28 +0400
committerEvgeny Mandrikov <mandrikov@gmail.com>2011-04-26 13:00:11 +0400
commite174628696636f74808f61c76a44da994edcadc7 (patch)
tree06af7a9e94d17294cce72ddded48a84c8b2b3f1f
parent4eb630d0ff939898efdd9ef29330736ca4e50ebc (diff)
downloadsonarqube-e174628696636f74808f61c76a44da994edcadc7.tar.gz
sonarqube-e174628696636f74808f61c76a44da994edcadc7.zip
SONAR-2298 Add support for multi-modules for non-Maven projects
* Use ProjectDefinition in ProjectTree instead of MavenProject * Allow to specify extensions for project's container via ProjectDefinition, so MavenProject not passed directly to batch in mojos * ProjectDefinition should store all information in properties * Replace DefaultProjectFileSystem by DefaultProjectFileSystem2, which works not only for Maven projects * Add DefaultProjectClasspath, which works not only for Maven projects * Enable ProjectLinksSensor only for Maven
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/DefaultProjectClasspath.java61
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java166
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/InMemoryPomCreator.java120
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java62
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java85
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/MavenProjectFileSystem.java114
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/MavenReactor.java43
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java20
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java15
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java110
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java75
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java20
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/InMemoryPomCreatorTest.java137
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java63
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java19
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrapper/ProjectDefinitionTest.java71
-rw-r--r--sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java12
-rw-r--r--sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java12
-rw-r--r--sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java12
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java3
22 files changed, 683 insertions, 541 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java
index c9ef33368dc..5f0ace5847f 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java
@@ -26,9 +26,11 @@ import org.apache.maven.model.Scm;
import org.apache.maven.project.MavenProject;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.SupportedEnvironment;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.ProjectLink;
+@SupportedEnvironment("maven")
public class ProjectLinksSensor implements Sensor {
public static final String KEY_HOME = "homepage";
diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectClasspath.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectClasspath.java
new file mode 100644
index 00000000000..978acf4b5d5
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectClasspath.java
@@ -0,0 +1,61 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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;
+
+import com.google.common.collect.Lists;
+import org.apache.maven.project.MavenProject;
+import org.sonar.api.batch.ProjectClasspath;
+import org.sonar.api.resources.ProjectFileSystem;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+
+import java.io.File;
+import java.util.List;
+
+public class DefaultProjectClasspath extends ProjectClasspath {
+
+ private ProjectDefinition def;
+ private ProjectFileSystem projectFileSystem;
+
+ public DefaultProjectClasspath(ProjectDefinition def, ProjectFileSystem projectFileSystem) {
+ this(def, projectFileSystem, null);
+ }
+
+ public DefaultProjectClasspath(ProjectDefinition def, ProjectFileSystem projectFileSystem, MavenProject pom) {
+ super(pom);
+ this.def = def;
+ this.projectFileSystem = projectFileSystem;
+ }
+
+ @Override
+ protected List<File> createElements() {
+ if (pom != null) {
+ return super.createElements();
+ } else {
+ List<File> elements = Lists.newArrayList();
+ for (String path : def.getBinaries()) {
+ elements.add(projectFileSystem.resolvePath(path));
+ }
+ for (String path : def.getLibraries()) {
+ elements.add(projectFileSystem.resolvePath(path));
+ }
+ return elements;
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java
new file mode 100644
index 00000000000..82302af4973
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java
@@ -0,0 +1,166 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.project.MavenProject;
+import org.sonar.api.resources.DefaultProjectFileSystem;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.ProjectFileSystem;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Implementation of {@link ProjectFileSystem} based on {@link ProjectDefinition} and {@link MavenProject}.
+ */
+public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
+
+ private ProjectDefinition def;
+ private MavenProject pom;
+
+ public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def) {
+ super(project, languages);
+ this.def = def;
+ }
+
+ /**
+ * For Maven.
+ */
+ public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom) {
+ this(project, languages, def);
+ this.pom = pom;
+ }
+
+ public File getBasedir() {
+ if (pom != null) {
+ return pom.getBasedir();
+ } else {
+ return def.getBaseDir();
+ }
+ }
+
+ public File getBuildDir() {
+ if (pom != null) {
+ return resolvePath(pom.getBuild().getDirectory());
+ } else {
+ // TODO workaround
+ return new File(getSonarWorkingDirectory(), "target");
+ }
+ }
+
+ public File getBuildOutputDir() {
+ if (pom != null) {
+ return resolvePath(pom.getBuild().getOutputDirectory());
+ } else {
+ if (def.getBinaries().isEmpty()) {
+ // workaround for IndexOutOfBoundsException
+ return new File(getBuildDir(), "classes");
+ }
+ // TODO we assume that there is only one directory which contains compiled code
+ return resolvePath(def.getBinaries().get(0));
+ }
+ }
+
+ public List<File> getSourceDirs() {
+ if (pom != null) {
+ // Maven can modify source directories during Sonar execution - see MavenPhaseExecutor.
+ return resolvePaths(pom.getCompileSourceRoots());
+ } else {
+ return resolvePaths(def.getSourceDirs());
+ }
+ }
+
+ /**
+ * @deprecated since 2.6, because should be immutable
+ */
+ @Deprecated
+ public DefaultProjectFileSystem addSourceDir(File dir) {
+ if (dir == null) {
+ throw new IllegalArgumentException("Can not add null to project source dirs");
+ }
+ if (pom != null) {
+ pom.getCompileSourceRoots().add(0, dir.getAbsolutePath());
+ } else {
+ def.addSourceDir(dir.getAbsolutePath());
+ }
+ return this;
+ }
+
+ /**
+ * Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
+ */
+ public List<File> getTestDirs() {
+ if (pom != null) {
+ // Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
+ return resolvePaths(pom.getTestCompileSourceRoots());
+ } else {
+ return resolvePaths(def.getTestDirs());
+ }
+ }
+
+ /**
+ * @deprecated since 2.6, because should be immutable
+ */
+ @Deprecated
+ public DefaultProjectFileSystem addTestDir(File dir) {
+ if (dir == null) {
+ throw new IllegalArgumentException("Can not add null to project test dirs");
+ }
+ if (pom != null) {
+ pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
+ } else {
+ def.addTestDir(dir.getAbsolutePath());
+ }
+ return this;
+ }
+
+ /**
+ * TODO Godin: seems that used only by Cobertura and Clover
+ */
+ public File getReportOutputDir() {
+ if (pom != null) {
+ return resolvePath(pom.getReporting().getOutputDirectory());
+ } else {
+ return new File(getBuildDir(), "site");
+ }
+ }
+
+ @Override
+ public File getSonarWorkingDirectory() {
+ if (pom != null) {
+ try {
+ File dir = new File(getBuildDir(), "sonar");
+ FileUtils.forceMkdir(dir);
+ return dir;
+
+ } catch (IOException e) {
+ throw new SonarException("Unable to retrieve Sonar working directory.", e);
+ }
+ } else {
+ return def.getWorkDir();
+ }
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/InMemoryPomCreator.java b/sonar-batch/src/main/java/org/sonar/batch/InMemoryPomCreator.java
deleted file mode 100644
index 73c79ad8548..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/InMemoryPomCreator.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 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;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.artifact.DependencyResolutionRequiredException;
-import org.apache.maven.model.Reporting;
-import org.apache.maven.project.MavenProject;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.bootstrapper.ProjectDefinition;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * This is a dirty hack for for non-Maven environments,
- * which allows to create {@link MavenProject} based on {@link ProjectDefinition}.
- */
-public class InMemoryPomCreator {
-
- private ProjectDefinition project;
-
- public InMemoryPomCreator(ProjectDefinition project) {
- this.project = project;
- }
-
- public MavenProject create() {
- File workDir = project.getWorkDir();
- String buildDirectory = workDir.getAbsolutePath() + "/target";
- Properties properties = project.getProperties();
-
- if (project.getBinaries().size() == 0) {
- project.addBinaryDir(buildDirectory + "/classes");
- }
-
- final MavenProject pom = new MavenProject() {
- /**
- * This allows to specify base directory without specifying location of a pom.xml
- */
- @Override
- public File getBasedir() {
- return project.getBaseDir();
- };
-
- /**
- * This allows to specify project classpath (binaries + libraries).
- */
- @Override
- public List<String> getCompileClasspathElements() throws DependencyResolutionRequiredException {
- List<String> cp = new ArrayList<String>();
- cp.addAll(project.getBinaries());
- cp.addAll(project.getLibraries());
- return cp;
- }
- };
-
- String key = getPropertyOrDie(properties, CoreProperties.PROJECT_KEY_PROPERTY);
- String[] keys = key.split(":");
- pom.setGroupId(keys[0]);
- pom.setArtifactId(keys[1]);
- pom.setVersion(getPropertyOrDie(properties, CoreProperties.PROJECT_VERSION_PROPERTY));
-
- pom.setName(properties.getProperty(CoreProperties.PROJECT_NAME_PROPERTY, "Unnamed - " + key));
- pom.setDescription(properties.getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, ""));
-
- pom.getModel().setProperties(properties);
-
- pom.setArtifacts(Collections.EMPTY_SET);
-
- // Configure fake directories
- pom.getBuild().setDirectory(buildDirectory);
- pom.getBuild().setOutputDirectory(project.getBinaries().get(0));
- Reporting reporting = new Reporting();
- String reportingOutputDirectory = buildDirectory + "/site";
- reporting.setOutputDirectory(reportingOutputDirectory);
- pom.setReporting(reporting);
-
- // Configure source directories
- for (String dir : project.getSourceDirs()) {
- pom.addCompileSourceRoot(dir);
- }
-
- // Configure test directories
- for (String dir : project.getTestDirs()) {
- pom.addTestCompileSourceRoot(dir);
- }
-
- return pom;
- }
-
- private static String getPropertyOrDie(Properties properties, String key) {
- String value = properties.getProperty(key);
- if (StringUtils.isBlank(value)) {
- throw new SonarException("Property '" + key + "' must be specified");
- }
- return value;
- }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java
index 0086f1015c0..48bc41730b0 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java
@@ -19,14 +19,9 @@
*/
package org.sonar.batch;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
import org.apache.commons.configuration.*;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
-import org.apache.maven.project.MavenProject;
import org.sonar.api.CoreProperties;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.ResourceModel;
@@ -34,7 +29,14 @@ import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+// TODO Godin: rename to ProjectBuilder ?
public class MavenProjectBuilder {
private DatabaseSession databaseSession;
@@ -43,43 +45,55 @@ public class MavenProjectBuilder {
this.databaseSession = databaseSession;
}
- public Project create(MavenProject pom) {
- Configuration configuration = getStartupConfiguration(pom);
- return new Project(loadProjectKey(pom), loadProjectBranch(configuration), pom.getName())
- .setPom(pom)
- .setDescription(pom.getDescription())
- .setPackaging(pom.getPackaging());
+ public Project create(ProjectDefinition project) {
+ Configuration configuration = getStartupConfiguration(project);
+ return new Project(loadProjectKey(project), loadProjectBranch(configuration), loadProjectName(project))
+ .setDescription(project.getProperties().getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY))
+ .setPackaging("jar"); // FIXME http://jira.codehaus.org/browse/SONAR-2341
}
- Configuration getStartupConfiguration(MavenProject pom) {
+ Configuration getStartupConfiguration(ProjectDefinition project) {
CompositeConfiguration configuration = new CompositeConfiguration();
configuration.addConfiguration(new SystemConfiguration());
configuration.addConfiguration(new EnvironmentConfiguration());
- configuration.addConfiguration(new MapConfiguration(pom.getModel().getProperties()));
+ configuration.addConfiguration(new MapConfiguration(project.getProperties()));
return configuration;
}
- String loadProjectKey(MavenProject pom) {
- return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString();
+ private String getPropertyOrDie(ProjectDefinition project, String key) {
+ String value = project.getProperties().getProperty(key);
+ if (StringUtils.isBlank(value)) {
+ throw new SonarException("Property '" + key + "' must be specified");
+ }
+ return value;
+ }
+
+ String loadProjectKey(ProjectDefinition projectDefinition) {
+ return getPropertyOrDie(projectDefinition, CoreProperties.PROJECT_KEY_PROPERTY);
+ }
+
+ String loadProjectName(ProjectDefinition projectDefinition) {
+ return projectDefinition.getProperties().getProperty(
+ CoreProperties.PROJECT_NAME_PROPERTY,
+ "Unnamed - " + loadProjectKey(projectDefinition));
}
String loadProjectBranch(Configuration configuration) {
return configuration.getString(CoreProperties.PROJECT_BRANCH_PROPERTY, configuration.getString("branch" /* deprecated property */));
}
- public void configure(Project project) {
- ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project);
+ public void configure(Project project, ProjectDefinition def) {
+ ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project, def.getProperties());
configure(project, projectConfiguration);
}
void configure(Project project, Configuration projectConfiguration) {
Date analysisDate = loadAnalysisDate(projectConfiguration);
- MavenProject pom = project.getPom();
project.setConfiguration(projectConfiguration)
.setExclusionPatterns(loadExclusionPatterns(projectConfiguration))
.setAnalysisDate(analysisDate)
.setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate))
- .setAnalysisVersion(loadAnalysisVersion(projectConfiguration, pom))
+ .setAnalysisVersion(loadAnalysisVersion(projectConfiguration))
.setAnalysisType(loadAnalysisType(projectConfiguration))
.setLanguageKey(loadLanguageKey(projectConfiguration));
}
@@ -133,12 +147,8 @@ public class MavenProjectBuilder {
return Project.AnalysisType.STATIC;
}
- String loadAnalysisVersion(Configuration configuration, MavenProject pom) {
- String version = configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY);
- if (version == null && pom != null) {
- version = pom.getVersion();
- }
- return version;
+ String loadAnalysisVersion(Configuration configuration) {
+ return configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY);
}
String loadLanguageKey(Configuration configuration) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java
new file mode 100644
index 00000000000..450509870be
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java
@@ -0,0 +1,85 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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;
+
+import com.google.common.collect.Maps;
+import org.apache.maven.project.MavenProject;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+public class MavenProjectConverter {
+
+ private MavenProjectConverter() {
+ }
+
+ public static ProjectDefinition convert(List<MavenProject> poms) {
+ Map<String, MavenProject> paths = Maps.newHashMap(); // projects by canonical path
+ Map<MavenProject, ProjectDefinition> defs = Maps.newHashMap();
+
+ try {
+ for (MavenProject pom : poms) {
+ String basedir = pom.getBasedir().getCanonicalPath();
+ paths.put(basedir, pom);
+ defs.put(pom, convert(pom));
+ }
+
+ for (Map.Entry<String, MavenProject> entry : paths.entrySet()) {
+ MavenProject pom = entry.getValue();
+ for (Object moduleId : pom.getModules()) {
+ File modulePath = new File(pom.getBasedir(), (String) moduleId);
+ MavenProject module = paths.get(modulePath.getCanonicalPath());
+ defs.get(pom).addModule(defs.get(module));
+ }
+ }
+ } catch (IOException e) {
+ throw new SonarException(e);
+ }
+
+ return defs.get(poms.get(0));
+ }
+
+ public static ProjectDefinition convert(MavenProject pom) {
+ Properties properties = new Properties();
+
+ String key = new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString();
+ setProperty(properties, CoreProperties.PROJECT_KEY_PROPERTY, key);
+ setProperty(properties, CoreProperties.PROJECT_VERSION_PROPERTY, pom.getVersion());
+ setProperty(properties, CoreProperties.PROJECT_NAME_PROPERTY, pom.getName());
+ setProperty(properties, CoreProperties.PROJECT_DESCRIPTION_PROPERTY, pom.getDescription());
+ properties.putAll(pom.getModel().getProperties());
+
+ ProjectDefinition def = new ProjectDefinition(pom.getBasedir(), null, properties); // TODO work directory ?
+ def.addContainerExtension(pom);
+ return def;
+ }
+
+ private static void setProperty(Properties properties, String key, String value) {
+ if (value != null) {
+ properties.setProperty(key, value);
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectFileSystem.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectFileSystem.java
deleted file mode 100644
index 39ac4ad7c18..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectFileSystem.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 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;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.maven.project.MavenProject;
-import org.sonar.api.resources.DefaultProjectFileSystem;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.ProjectFileSystem;
-import org.sonar.api.utils.SonarException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Implementation of {@link ProjectFileSystem} based on {@link MavenProject}.
- */
-public class MavenProjectFileSystem extends DefaultProjectFileSystem {
-
- private MavenProject pom;
-
- public MavenProjectFileSystem(Project project, Languages languages) {
- super(project, languages);
- this.pom = project.getPom();
- }
-
- @Override
- public File getBasedir() {
- return pom.getBasedir();
- }
-
- @Override
- public File getBuildDir() {
- return resolvePath(pom.getBuild().getDirectory());
- }
-
- @Override
- public File getBuildOutputDir() {
- return resolvePath(pom.getBuild().getOutputDirectory());
- }
-
- /**
- * Maven can modify source directories during Sonar execution - see MavenPhaseExecutor.
- */
- @Override
- public List<File> getSourceDirs() {
- return resolvePaths(pom.getCompileSourceRoots());
- }
-
- @Override
- public DefaultProjectFileSystem addSourceDir(File dir) {
- if (dir == null) {
- throw new IllegalArgumentException("Can not add null to project source dirs");
- }
- pom.getCompileSourceRoots().add(0, dir.getAbsolutePath());
- return this;
- }
-
- /**
- * Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
- */
- @Override
- public List<File> getTestDirs() {
- return resolvePaths(pom.getTestCompileSourceRoots());
- }
-
- /**
- * @deprecated since 2.6, because should be immutable
- */
- @Override
- public DefaultProjectFileSystem addTestDir(File dir) {
- if (dir == null) {
- throw new IllegalArgumentException("Can not add null to project test dirs");
- }
- pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
- return this;
- }
-
- @Override
- public File getReportOutputDir() {
- return resolvePath(pom.getReporting().getOutputDirectory());
- }
-
- @Override
- public File getSonarWorkingDirectory() {
- try {
- File dir = new File(getBuildDir(), "sonar");
- FileUtils.forceMkdir(dir);
- return dir;
-
- } catch (IOException e) {
- throw new SonarException("Unable to retrieve Sonar working directory.", e);
- }
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenReactor.java b/sonar-batch/src/main/java/org/sonar/batch/MavenReactor.java
deleted file mode 100644
index fff85d35e34..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/MavenReactor.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 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;
-
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.project.MavenProject;
-
-import java.util.List;
-
-public class MavenReactor {
-
- private List<MavenProject> sortedProjects;
-
- public MavenReactor(MavenSession mavenSession) {
- this.sortedProjects = mavenSession.getSortedProjects();
- }
-
- public MavenReactor(List<MavenProject> sortedProjects) {
- this.sortedProjects = sortedProjects;
- }
-
- public List<MavenProject> getSortedProjects() {
- return sortedProjects;
- }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java
index 95355bc08ef..7a6ea61b454 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java
@@ -19,8 +19,8 @@
*/
package org.sonar.batch;
+import org.apache.maven.project.MavenProject;
import org.sonar.api.batch.BatchExtensionDictionnary;
-import org.sonar.api.batch.ProjectClasspath;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metrics;
@@ -32,6 +32,7 @@ import org.sonar.api.resources.ProjectFileSystem;
import org.sonar.api.rules.DefaultRulesManager;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.bootstrap.BatchPluginRepository;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
import org.sonar.batch.components.PastViolationsLoader;
import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.events.EventBus;
@@ -103,10 +104,21 @@ public class ProjectBatch {
@Override
protected void configure() {
+ ProjectDefinition projectDefinition = getComponent(ProjectTree.class).getProjectDefinition(project.getKey());
+ addComponent(projectDefinition);
+ for (Object component : projectDefinition.getContainerExtensions()) {
+ addComponent(component);
+ if (component instanceof MavenProject) {
+ // For backward compatibility we must set POM and actual packaging
+ MavenProject pom = (MavenProject) component;
+ project.setPom(pom);
+ project.setPackaging(pom.getPackaging());
+ }
+ }
+
addComponent(project);
- addComponent(project.getPom());
- addComponent(ProjectClasspath.class);
- addComponent(MavenProjectFileSystem.class);
+ addComponent(DefaultProjectClasspath.class);
+ addComponent(DefaultProjectFileSystem2.class);
addComponent(project.getConfiguration());
// need to be registered after the Configuration
diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java
index ddae656f1d8..f89e9d644fa 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java
@@ -20,20 +20,26 @@
package org.sonar.batch;
import org.apache.commons.configuration.*;
-import org.apache.maven.project.MavenProject;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.resources.Project;
+import java.util.Properties;
+
public class ProjectConfiguration extends CompositeConfiguration {
private PropertiesConfiguration runtimeConfiguration;
+ // FIXME remove
public ProjectConfiguration(DatabaseSession session, Project project) {
+ this(session, project, project.getPom().getProperties());
+ }
+
+ public ProjectConfiguration(DatabaseSession session, Project project, Properties properties) {
runtimeConfiguration = new PropertiesConfiguration();
addConfiguration(runtimeConfiguration);
loadSystemSettings();
loadProjectDatabaseSettings(session, project);
- loadMavenSettings(project.getPom());
+ addConfiguration(new MapConfiguration(properties));
loadGlobalDatabaseSettings(session);
}
@@ -56,13 +62,8 @@ public class ProjectConfiguration extends CompositeConfiguration {
addConfiguration(new EnvironmentConfiguration());
}
- private void loadMavenSettings(MavenProject pom) {
- addConfiguration(new MapConfiguration(pom.getModel().getProperties()));
- }
-
@Override
public void setProperty(String s, Object o) {
runtimeConfiguration.setProperty(s, o);
}
}
-
diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java
index 4a03586a2e8..ac2db745ec3 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java
@@ -21,42 +21,30 @@ package org.sonar.batch;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
import org.apache.maven.project.MavenProject;
import org.slf4j.LoggerFactory;
+import org.sonar.api.CoreProperties;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.resources.Project;
import org.sonar.batch.bootstrapper.ProjectDefinition;
import org.sonar.batch.bootstrapper.Reactor;
-import java.io.File;
import java.io.IOException;
import java.util.*;
public class ProjectTree {
private List<Project> projects;
- private List<MavenProject> poms;
private MavenProjectBuilder projectBuilder;
+ private List<ProjectDefinition> definitions;
- public ProjectTree(MavenReactor mavenReactor, DatabaseSession databaseSession) {
- this.poms = mavenReactor.getSortedProjects();
- this.projectBuilder = new MavenProjectBuilder(databaseSession);
- }
-
- /**
- * Hack for non-Maven environments.
- */
public ProjectTree(Reactor sonarReactor, DatabaseSession databaseSession) {
- this(createMavenReactor(sonarReactor), databaseSession);
- }
-
- private static MavenReactor createMavenReactor(Reactor sonarReactor) {
- List<ProjectDefinition> sonarProjects = sonarReactor.getSortedProjects();
- List<MavenProject> mavenProjects = Lists.newArrayList();
- for (ProjectDefinition project : sonarProjects) {
- mavenProjects.add(new InMemoryPomCreator(project).create());
+ this.projectBuilder = new MavenProjectBuilder(databaseSession);
+ definitions = Lists.newArrayList();
+ for (ProjectDefinition project : sonarReactor.getSortedProjects()) {
+ collectProjects(project, definitions);
}
- return new MavenReactor(mavenProjects);
}
/**
@@ -64,7 +52,8 @@ public class ProjectTree {
*/
protected ProjectTree(MavenProjectBuilder projectBuilder, List<MavenProject> poms) {
this.projectBuilder = projectBuilder;
- this.poms = poms;
+ definitions = Lists.newArrayList();
+ collectProjects(MavenProjectConverter.convert(poms), definitions);
}
/**
@@ -74,36 +63,40 @@ public class ProjectTree {
this.projects = new ArrayList<Project>(projects);
}
+ /**
+ * Populates list of projects from hierarchy.
+ */
+ private static void collectProjects(ProjectDefinition root, List<ProjectDefinition> collected) {
+ collected.add(root);
+ for (ProjectDefinition module : root.getModules()) {
+ collectProjects(module, collected);
+ }
+ }
+
public void start() throws IOException {
projects = Lists.newArrayList();
- Map<String, Project> paths = Maps.newHashMap(); // projects by canonical path
+ Map<ProjectDefinition, Project> map = Maps.newHashMap();
- for (MavenProject pom : poms) {
- Project project = projectBuilder.create(pom);
+ for (ProjectDefinition def : definitions) {
+ Project project = projectBuilder.create(def);
+ map.put(def, project);
projects.add(project);
- paths.put(pom.getBasedir().getCanonicalPath(), project);
}
- for (Map.Entry<String, Project> entry : paths.entrySet()) {
+ for (Map.Entry<ProjectDefinition, Project> entry : map.entrySet()) {
+ ProjectDefinition def = entry.getKey();
Project project = entry.getValue();
- MavenProject pom = project.getPom();
- for (Object moduleId : pom.getModules()) {
- File modulePath = new File(pom.getBasedir(), (String) moduleId);
- Project module = paths.get(modulePath.getCanonicalPath());
- if (module != null) {
- module.setParent(project);
- }
+ for (ProjectDefinition module : def.getModules()) {
+ map.get(module).setParent(project);
}
}
- configureProjects();
- applyModuleExclusions();
- }
-
- private void configureProjects() {
- for (Project project : projects) {
- projectBuilder.configure(project);
+ // Configure
+ for (Map.Entry<ProjectDefinition, Project> entry : map.entrySet()) {
+ projectBuilder.configure(entry.getValue(), entry.getKey());
}
+
+ applyModuleExclusions();
}
void applyModuleExclusions() {
@@ -125,7 +118,7 @@ public class ProjectTree {
if (!includedModulesIdSet.isEmpty()) {
for (Project currentProject : projects) {
- if (!includedModulesIdSet.contains(currentProject.getPom().getArtifactId())) {
+ if (!includedModulesIdSet.contains(getArtifactId(currentProject))) {
exclude(currentProject);
}
}
@@ -160,9 +153,19 @@ public class ProjectTree {
return projects;
}
+ private String getArtifactId(Project project) {
+ String key = project.getKey();
+ if (StringUtils.isNotBlank(project.getBranch())) {
+ // remove branch part
+ key = StringUtils.removeEnd(project.getKey(), ":" + project.getBranch());
+ }
+ return StringUtils.substringAfterLast(key, ":");
+ }
+
public Project getProjectByArtifactId(String artifactId) {
for (Project project : projects) {
- if (project.getPom().getArtifactId().equals(artifactId)) {
+ // TODO see http://jira.codehaus.org/browse/SONAR-2324
+ if (StringUtils.equals(getArtifactId(project), artifactId)) {
return project;
}
}
@@ -177,4 +180,27 @@ public class ProjectTree {
}
throw new IllegalStateException("Can not find the root project from the list of Maven modules");
}
-} \ No newline at end of file
+
+ private String getProjectKey(ProjectDefinition def) {
+ String key = def.getProperties().getProperty(CoreProperties.PROJECT_KEY_PROPERTY);
+ String branch = def.getProperties().getProperty(CoreProperties.PROJECT_BRANCH_PROPERTY);
+ if (StringUtils.isNotBlank(branch)) {
+ return key + ":" + branch;
+ } else {
+ return key;
+ }
+ }
+
+ public ProjectDefinition getProjectDefinition(String key) {
+ for (ProjectDefinition def : definitions) {
+ if (StringUtils.equals(key, getProjectKey(def))) {
+ return def;
+ }
+ }
+ return null;
+ }
+
+ public List<Object> getProjectExtensions(String key) {
+ return getProjectDefinition(key).getContainerExtensions();
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java
index b632feb60ac..907f30940ac 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java
@@ -19,12 +19,14 @@
*/
package org.sonar.batch.bootstrapper;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+
import java.io.File;
+import java.util.Arrays;
import java.util.List;
import java.util.Properties;
-import com.google.common.collect.Lists;
-
/**
* Describes project in a form suitable to bootstrap Sonar batch.
* We assume that project is just a set of configuration properties and directories.
@@ -33,13 +35,19 @@ import com.google.common.collect.Lists;
*/
public class ProjectDefinition {
+ private static final String PROJECT_SOURCES_PROPERTY = "sonar.sources";
+ private static final String PROJECT_TESTS_PROPERTY = "sonar.tests";
+ private static final String PROJECT_BINARIES_PROPERTY = "sonar.binaries";
+ private static final String PROJECT_LIBRARIES_PROPERTY = "sonar.libraries";
+
+ private static final char SEPARATOR = ',';
+
private File baseDir;
private File workDir;
private Properties properties;
- private List<String> sourceDirs = Lists.newArrayList();
- private List<String> testDirs = Lists.newArrayList();
- private List<String> binaries = Lists.newArrayList();
- private List<String> libraries = Lists.newArrayList();
+ private List<ProjectDefinition> modules = Lists.newArrayList();
+
+ private List<Object> containerExtensions = Lists.newArrayList();
/**
* @param baseDir project base directory
@@ -63,8 +71,14 @@ public class ProjectDefinition {
return properties;
}
+ private void appendProperty(String key, String value) {
+ String newValue = properties.getProperty(key, "") + SEPARATOR + value;
+ properties.put(key, newValue);
+ }
+
public List<String> getSourceDirs() {
- return sourceDirs;
+ String sources = properties.getProperty(PROJECT_SOURCES_PROPERTY, "");
+ return Arrays.asList(StringUtils.split(sources, SEPARATOR));
}
/**
@@ -72,11 +86,12 @@ public class ProjectDefinition {
* It can be absolute or relative to project directory.
*/
public void addSourceDir(String path) {
- sourceDirs.add(path);
+ appendProperty(PROJECT_SOURCES_PROPERTY, path);
}
public List<String> getTestDirs() {
- return testDirs;
+ String sources = properties.getProperty(PROJECT_TESTS_PROPERTY, "");
+ return Arrays.asList(StringUtils.split(sources, SEPARATOR));
}
/**
@@ -84,11 +99,12 @@ public class ProjectDefinition {
* It can be absolute or relative to project directory.
*/
public void addTestDir(String path) {
- testDirs.add(path);
+ appendProperty(PROJECT_TESTS_PROPERTY, path);
}
public List<String> getBinaries() {
- return binaries;
+ String sources = properties.getProperty(PROJECT_BINARIES_PROPERTY, "");
+ return Arrays.asList(StringUtils.split(sources, SEPARATOR));
}
/**
@@ -97,11 +113,12 @@ public class ProjectDefinition {
* @TODO currently Sonar supports only one such directory due to dependency on MavenProject
*/
public void addBinaryDir(String path) {
- binaries.add(path);
+ appendProperty(PROJECT_BINARIES_PROPERTY, path);
}
public List<String> getLibraries() {
- return libraries;
+ String sources = properties.getProperty(PROJECT_LIBRARIES_PROPERTY, "");
+ return Arrays.asList(StringUtils.split(sources, SEPARATOR));
}
/**
@@ -109,6 +126,36 @@ public class ProjectDefinition {
* It can be absolute or relative to project directory.
*/
public void addLibrary(String path) {
- libraries.add(path);
+ appendProperty(PROJECT_LIBRARIES_PROPERTY, path);
+ }
+
+ /**
+ * Adds an extension, which would be available in PicoContainer during analysis of this project.
+ *
+ * @since 2.8
+ */
+ public void addContainerExtension(Object extension) {
+ containerExtensions.add(extension);
+ }
+
+ /**
+ * @since 2.8
+ */
+ public List<Object> getContainerExtensions() {
+ return containerExtensions;
+ }
+
+ /**
+ * @since 2.8
+ */
+ public void addModule(ProjectDefinition projectDefinition) {
+ modules.add(projectDefinition);
+ }
+
+ /**
+ * @since 2.8
+ */
+ public List<ProjectDefinition> getModules() {
+ return modules;
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java b/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java
index 49560b6126e..ab6c9915123 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java
@@ -60,16 +60,18 @@ public class MavenPluginsConfigurator implements BatchComponent {
protected void savePom(Project project) {
MavenProject pom = project.getPom();
- File targetPom = new File(project.getFileSystem().getSonarWorkingDirectory(), "sonar-pom.xml");
- FileWriter fileWriter = null;
- try {
- fileWriter = new FileWriter(targetPom, false);
- pom.writeModel(fileWriter);
+ if (pom != null) {
+ File targetPom = new File(project.getFileSystem().getSonarWorkingDirectory(), "sonar-pom.xml");
+ FileWriter fileWriter = null;
+ try {
+ fileWriter = new FileWriter(targetPom, false);
+ pom.writeModel(fileWriter);
- } catch (IOException e) {
- throw new SonarException("Can not save pom to " + targetPom, e);
- } finally {
- IOUtils.closeQuietly(fileWriter);
+ } catch (IOException e) {
+ throw new SonarException("Can not save pom to " + targetPom, e);
+ } finally {
+ IOUtils.closeQuietly(fileWriter);
+ }
}
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/InMemoryPomCreatorTest.java b/sonar-batch/src/test/java/org/sonar/batch/InMemoryPomCreatorTest.java
deleted file mode 100644
index e7787f5e05b..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/InMemoryPomCreatorTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 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;
-
-import org.apache.maven.project.MavenProject;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.bootstrapper.ProjectDefinition;
-
-import java.io.File;
-import java.util.List;
-import java.util.Properties;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-public class InMemoryPomCreatorTest {
-
- private Properties properties;
- private ProjectDefinition project;
-
- @Before
- public void setUp() {
- properties = new Properties();
- File baseDir = new File(".");
- File workDir = new File(baseDir, "sonar");
- project = new ProjectDefinition(baseDir, workDir, properties);
- }
-
- @Test
- public void minimal() {
- createRequiredProperties();
-
- MavenProject pom = create();
-
- assertThat(pom.getBasedir(), is(project.getBaseDir()));
- assertThat(pom.getGroupId(), is("org.example"));
- assertThat(pom.getArtifactId(), is("example"));
- assertThat(pom.getName(), is("Unnamed - org.example:example"));
- assertThat(pom.getDescription(), is(""));
- assertThat(pom.getProperties(), is(project.getProperties()));
- assertThat(pom.getBasedir(), is(project.getBaseDir()));
- String buildDirectory = project.getWorkDir().getAbsolutePath() + "/target";
- assertThat(pom.getBuild().getDirectory(), is(buildDirectory));
- assertThat(pom.getBuild().getOutputDirectory(), is(buildDirectory + "/classes"));
- assertThat(pom.getReporting().getOutputDirectory(), is(buildDirectory + "/site"));
- }
-
- @Test
- public void nameAndDescription() {
- createRequiredProperties();
-
- properties.setProperty(CoreProperties.PROJECT_NAME_PROPERTY, "Foo");
- properties.setProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, "Bar");
-
- MavenProject pom = create();
-
- assertThat(pom.getName(), is("Foo"));
- assertThat(pom.getDescription(), is("Bar"));
- }
-
- @Test
- public void sourceDirectories() {
- createRequiredProperties();
- project.addSourceDir("src");
- project.addTestDir("test");
-
- MavenProject pom = create();
-
- assertThat(pom.getCompileSourceRoots().size(), is(1));
- assertThat((String) pom.getCompileSourceRoots().get(0), is("src"));
-
- assertThat(pom.getTestCompileSourceRoots().size(), is(1));
- assertThat((String) pom.getTestCompileSourceRoots().get(0), is("test"));
- }
-
- @Test
- public void classpath() throws Exception {
- createRequiredProperties();
- project.addBinaryDir("/classes");
- project.addLibrary("junit.jar");
-
- MavenProject pom = create();
-
- List<String> cp = pom.getCompileClasspathElements();
- assertThat(cp.size(), is(2));
- assertThat(cp.get(0), is("/classes"));
- assertThat(cp.get(1), is("junit.jar"));
- }
-
- @Test
- public void shouldNotFailIfNoBinaries() throws Exception {
- createRequiredProperties();
-
- MavenProject pom = create();
- assertThat(pom.getCompileClasspathElements().size(), is(1));
- }
-
- private void createRequiredProperties() {
- properties.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "org.example:example");
- properties.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0-SNAPSHOT");
- }
-
- @Test(expected = SonarException.class)
- public void shouldFailWhenKeyNotSpecified() {
- create();
- }
-
- @Test(expected = SonarException.class)
- public void shouldFailWhenVersionNotSpecified() {
- properties.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "org.example:example");
- create();
- }
-
- private MavenProject create() {
- return new InMemoryPomCreator(project).create();
- }
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java
new file mode 100644
index 00000000000..c9a2c4124fb
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java
@@ -0,0 +1,63 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.apache.maven.project.MavenProject;
+import org.junit.Test;
+import org.sonar.api.CoreProperties;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Properties;
+
+public class MavenProjectConverterTest {
+ @Test
+ public void test2() {
+ MavenProject root = new MavenProject();
+ root.setFile(new File("/foo/pom.xml"));
+ root.getModules().add("module");
+ MavenProject module = new MavenProject();
+ module.setFile(new File("/foo/module/pom.xml"));
+ ProjectDefinition project = MavenProjectConverter.convert(Arrays.asList(root, module));
+
+ assertThat(project.getModules().size(), is(1));
+ }
+
+ @Test
+ public void test() {
+ MavenProject pom = new MavenProject();
+ pom.setGroupId("foo");
+ pom.setArtifactId("bar");
+ pom.setVersion("1.0.1");
+ pom.setName("Test");
+ pom.setDescription("just test");
+ ProjectDefinition project = MavenProjectConverter.convert(pom);
+
+ Properties properties = project.getProperties();
+ assertThat(properties.getProperty(CoreProperties.PROJECT_KEY_PROPERTY), is("foo:bar"));
+ assertThat(properties.getProperty(CoreProperties.PROJECT_VERSION_PROPERTY), is("1.0.1"));
+ assertThat(properties.getProperty(CoreProperties.PROJECT_NAME_PROPERTY), is("Test"));
+ assertThat(properties.getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY), is("just test"));
+ }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java
index ef3b087ffac..c494dfb02bc 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java
@@ -19,6 +19,11 @@
*/
package org.sonar.batch;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
+
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.io.FileUtils;
import org.apache.maven.model.Model;
@@ -26,8 +31,8 @@ import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
import org.sonar.api.resources.Project;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
import java.io.File;
import java.io.IOException;
@@ -35,12 +40,6 @@ import java.io.StringReader;
import java.net.URISyntaxException;
import java.util.Arrays;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertNull;
-import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
-
-
public class ProjectTreeTest extends AbstractDbUnitTestCase {
@Test
@@ -71,7 +70,6 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
ProjectTree tree = new ProjectTree(newProjectBuilder(), Arrays.asList(parent, module1, module2));
tree.start();
-
Project root = tree.getRootProject();
assertThat(root.getModules().size(), is(2));
assertThat(root.getKey(), is("org.test:parent"));
@@ -105,7 +103,6 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
assertThat(tree.getRootProject().getName(), is("Project BRANCH-1.X"));
}
-
@Test
public void keyIncludesDeprecatedBranch() throws IOException, XmlPullParserException, URISyntaxException {
MavenProject pom = loadProject("/org/sonar/batch/ProjectTreeTest/keyIncludesDeprecatedBranch/pom.xml", true);
@@ -130,7 +127,7 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
}
@Test
- public void skipModule() {
+ public void skipModule() throws IOException {
Project root = newProjectWithArtifactId("root");
root.getConfiguration().setProperty("sonar.skippedModules", "sub1");
Project sub1 = newProjectWithArtifactId("sub1");
@@ -191,7 +188,7 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
private Project newProjectWithArtifactId(String artifactId) {
MavenProject pom = new MavenProject();
pom.setArtifactId(artifactId);
- return new Project(artifactId).setPom(pom).setConfiguration(new PropertiesConfiguration());
+ return new Project("org.example:" + artifactId).setPom(pom).setConfiguration(new PropertiesConfiguration());
}
private MavenProject loadProject(String pomPath, boolean isRoot) throws URISyntaxException, IOException, XmlPullParserException {
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/ProjectDefinitionTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/ProjectDefinitionTest.java
new file mode 100644
index 00000000000..df584f312b6
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/ProjectDefinitionTest.java
@@ -0,0 +1,71 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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.bootstrapper;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+public class ProjectDefinitionTest {
+ private ProjectDefinition def;
+
+ @Before
+ public void setUp() {
+ def = new ProjectDefinition(new File("."), new File("."), new Properties());
+ }
+
+ @Test
+ public void defaultValues() {
+ assertThat(def.getSourceDirs().size(), is(0));
+ assertThat(def.getTestDirs().size(), is(0));
+ assertThat(def.getBinaries().size(), is(0));
+ assertThat(def.getLibraries().size(), is(0));
+ }
+
+ @Test
+ public void shouldAddDirectories() {
+ def.addSourceDir("src/main/java");
+ def.addSourceDir("src/main/java2");
+ def.addTestDir("src/test/java");
+ def.addTestDir("src/test/java2");
+ def.addBinaryDir("target/classes");
+ def.addBinaryDir("target/classes2");
+ def.addLibrary("junit.jar");
+ def.addLibrary("mockito.jar");
+
+ assertDirs(def.getSourceDirs(), "src/main/java", "src/main/java2");
+ assertDirs(def.getTestDirs(), "src/test/java", "src/test/java2");
+ assertDirs(def.getBinaries(), "target/classes", "target/classes2");
+ assertDirs(def.getLibraries(), "junit.jar", "mockito.jar");
+ }
+
+ private static void assertDirs(List<String> dirs, String... values) {
+ assertThat(dirs.size(), is(values.length));
+ for (int i = 0; i < values.length; i++) {
+ assertThat(dirs.get(i), is(values[i]));
+ }
+ }
+}
diff --git a/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java b/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java
index 075dfe9110a..f979a24944d 100644
--- a/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java
+++ b/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java
@@ -19,8 +19,6 @@
*/
package org.sonar.maven2;
-import java.io.InputStream;
-
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -42,8 +40,12 @@ import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
import org.slf4j.LoggerFactory;
import org.sonar.batch.Batch;
-import org.sonar.batch.MavenReactor;
+import org.sonar.batch.MavenProjectConverter;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+import org.sonar.batch.bootstrapper.Reactor;
+
+import java.io.InputStream;
/**
* @goal internal
@@ -143,7 +145,9 @@ public final class BatchMojo extends AbstractMojo {
}
private void executeBatch() throws MojoExecutionException {
- MavenReactor reactor = new MavenReactor(session);
+ ProjectDefinition def = MavenProjectConverter.convert(session.getSortedProjects());
+ Reactor reactor = new Reactor(def);
+
Batch batch = new Batch(getInitialConfiguration(), reactor, session, project,
getLog(), lifecycleExecutor, pluginManager, artifactFactory,
localRepository, artifactMetadataSource, artifactCollector,
diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
index ab0123210f5..eb57053ba8a 100644
--- a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
+++ b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
@@ -19,8 +19,6 @@
*/
package org.sonar.maven;
-import java.io.InputStream;
-
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -42,8 +40,12 @@ import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
import org.slf4j.LoggerFactory;
import org.sonar.batch.Batch;
-import org.sonar.batch.MavenReactor;
+import org.sonar.batch.MavenProjectConverter;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+import org.sonar.batch.bootstrapper.Reactor;
+
+import java.io.InputStream;
/**
* @goal sonar
@@ -143,7 +145,9 @@ public final class SonarMojo extends AbstractMojo {
}
private void executeBatch() throws MojoExecutionException {
- MavenReactor reactor = new MavenReactor(session);
+ ProjectDefinition def = MavenProjectConverter.convert(session.getSortedProjects());
+ Reactor reactor = new Reactor(def);
+
Batch batch = new Batch(getInitialConfiguration(),
reactor, session, project, getLog(), lifecycleExecutor, pluginManager, artifactFactory,
localRepository, artifactMetadataSource, artifactCollector, dependencyTreeBuilder,
diff --git a/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java b/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java
index baca606b874..7bb5e3e5f69 100644
--- a/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java
+++ b/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java
@@ -19,8 +19,6 @@
*/
package org.sonar.maven3;
-import java.io.InputStream;
-
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -41,8 +39,12 @@ import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
import org.slf4j.LoggerFactory;
import org.sonar.batch.Batch;
-import org.sonar.batch.MavenReactor;
+import org.sonar.batch.MavenProjectConverter;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
+import org.sonar.batch.bootstrapper.ProjectDefinition;
+import org.sonar.batch.bootstrapper.Reactor;
+
+import java.io.InputStream;
/**
* @goal sonar
@@ -136,7 +138,9 @@ public final class SonarMojo extends AbstractMojo {
}
private void executeBatch() throws MojoExecutionException {
- MavenReactor reactor = new MavenReactor(session);
+ ProjectDefinition def = MavenProjectConverter.convert(session.getSortedProjects());
+ Reactor reactor = new Reactor(def);
+
Batch batch = new Batch(getInitialConfiguration(),
reactor, session, project, getLog(), lifecycleExecutor, artifactFactory,
localRepository, artifactMetadataSource, artifactCollector, dependencyTreeBuilder,
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java
index 9fffa244dbf..130ad3c29fe 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java
@@ -36,7 +36,7 @@ import java.util.List;
*/
public class ProjectClasspath implements BatchComponent {
- private MavenProject pom;
+ protected MavenProject pom;
private List<File> elements;
private URLClassLoader classloader;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java
index 9670a437af9..6b3737ac39d 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java
@@ -43,8 +43,9 @@ import java.util.List;
* For internal use only.
*
* @since 1.10
- * @TODO in fact this class should not be located in sonar-plugin-api
+ * @deprecated in 2.8. In fact this class should not be located in sonar-plugin-api and most of the methods were overridden by a component in sonar-batch.
*/
+@Deprecated
public class DefaultProjectFileSystem implements ProjectFileSystem {
private Project project;