aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-maven-plugin
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2014-09-08 22:12:13 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2014-09-10 09:05:35 +0200
commit2e36b19261bc24648ce3cc6688b1ffcd89fa6d99 (patch)
treecd5385f19d185bf402d41687a0dff45e53b372fe /sonar-maven-plugin
parentef2ed846de640619a7b00106d45e71573ce4c91a (diff)
downloadsonarqube-2e36b19261bc24648ce3cc6688b1ffcd89fa6d99.tar.gz
sonarqube-2e36b19261bc24648ce3cc6688b1ffcd89fa6d99.zip
SONAR-5604 Design plugin should no more rely on Maven APIs
Diffstat (limited to 'sonar-maven-plugin')
-rw-r--r--sonar-maven-plugin/pom.xml4
-rw-r--r--sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java138
2 files changed, 141 insertions, 1 deletions
diff --git a/sonar-maven-plugin/pom.xml b/sonar-maven-plugin/pom.xml
index d59510fd17b..5a93cf227ad 100644
--- a/sonar-maven-plugin/pom.xml
+++ b/sonar-maven-plugin/pom.xml
@@ -20,6 +20,10 @@
<artifactId>sonar-runner-api</artifactId>
</dependency>
<dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<scope>provided</scope>
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 dfc313844a2..b3bbc9bb70b 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
@@ -31,19 +31,34 @@ import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.shared.dependency.tree.DependencyNode;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
+import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
+import org.apache.maven.shared.dependency.tree.filter.AncestorOrSelfDependencyNodeFilter;
+import org.apache.maven.shared.dependency.tree.filter.DependencyNodeFilter;
+import org.apache.maven.shared.dependency.tree.filter.StateDependencyNodeFilter;
+import org.apache.maven.shared.dependency.tree.traversal.BuildingDependencyNodeVisitor;
+import org.apache.maven.shared.dependency.tree.traversal.CollectingDependencyNodeVisitor;
+import org.apache.maven.shared.dependency.tree.traversal.DependencyNodeVisitor;
+import org.apache.maven.shared.dependency.tree.traversal.FilteringDependencyNodeVisitor;
import org.sonar.runner.api.EmbeddedRunner;
import org.sonar.runner.api.RunnerProperties;
import org.sonar.runner.api.ScanProperties;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
/**
* @goal sonar
* @aggregator
* @requiresDependencyResolution test
+ * @deprecated Only kept for backward compatibility with old version of SQ Maven plugin
*/
+@Deprecated
public final class SonarMojo extends AbstractMojo {
/**
@@ -151,7 +166,8 @@ public final class SonarMojo extends AbstractMojo {
.setProperty(ScanProperties.PROJECT_VERSION, toString(project.getVersion()))
.setProperty(ScanProperties.PROJECT_NAME, toString(project.getName()))
.setProperty(ScanProperties.PROJECT_DESCRIPTION, toString(project.getDescription()))
- .setProperty(ScanProperties.PROJECT_SOURCE_DIRS, ".");
+ .setProperty(ScanProperties.PROJECT_SOURCE_DIRS, ".")
+ .setProperty("sonar.maven.projectDependencies", dependenciesToJson(collectProjectDependencies()));
// Exclude log implementation to not conflict with Maven 3.1 logging impl
runner.mask("org.slf4j.LoggerFactory")
// Include slf4j Logger that is exposed by some Sonar components
@@ -176,6 +192,126 @@ public final class SonarMojo extends AbstractMojo {
}
}
+ private static class Dependency {
+
+ private final String key;
+ private final String version;
+ private String scope;
+ List<Dependency> dependencies = new ArrayList<SonarMojo.Dependency>();
+
+ public Dependency(String key, String version) {
+ this.key = key;
+ this.version = version;
+ }
+
+ public String key() {
+ return key;
+ }
+
+ public String version() {
+ return version;
+ }
+
+ public String scope() {
+ return scope;
+ }
+
+ public Dependency setScope(String scope) {
+ this.scope = scope;
+ return this;
+ }
+
+ public List<Dependency> dependencies() {
+ return dependencies;
+ }
+ }
+
+ private List<Dependency> collectProjectDependencies() {
+ final List<Dependency> result = new ArrayList<SonarMojo.Dependency>();
+ try {
+ DependencyNode root = dependencyTreeBuilder.buildDependencyTree(project, localRepository, artifactFactory, artifactMetadataSource, null, artifactCollector);
+
+ DependencyNodeVisitor visitor = new BuildingDependencyNodeVisitor(new DependencyNodeVisitor() {
+
+ private Stack<Dependency> stack = new Stack<SonarMojo.Dependency>();
+
+ public boolean visit(DependencyNode node) {
+ if (node.getParent() != null && node.getParent() != node) {
+ Dependency dependency = toDependency(node);
+ if (stack.isEmpty()) {
+ result.add(dependency);
+ }
+ else {
+ stack.peek().dependencies().add(dependency);
+ }
+ stack.push(dependency);
+ }
+ return true;
+ }
+
+ public boolean endVisit(DependencyNode node) {
+ if (!stack.isEmpty()) {
+ stack.pop();
+ }
+ return true;
+ }
+ });
+
+ // mode verbose OFF : do not show the same lib many times
+ DependencyNodeFilter filter = StateDependencyNodeFilter.INCLUDED;
+
+ CollectingDependencyNodeVisitor collectingVisitor = new CollectingDependencyNodeVisitor();
+ DependencyNodeVisitor firstPassVisitor = new FilteringDependencyNodeVisitor(collectingVisitor, filter);
+ root.accept(firstPassVisitor);
+
+ DependencyNodeFilter secondPassFilter = new AncestorOrSelfDependencyNodeFilter(collectingVisitor.getNodes());
+ visitor = new FilteringDependencyNodeVisitor(visitor, secondPassFilter);
+
+ root.accept(visitor);
+
+ } catch (DependencyTreeBuilderException e) {
+ throw new IllegalStateException("Can not load the graph of dependencies of the project " + getSonarKey(project), e);
+ }
+ return result;
+ }
+
+ private Dependency toDependency(DependencyNode node) {
+ String key = String.format("%s:%s", node.getArtifact().getGroupId(), node.getArtifact().getArtifactId());
+ String version = node.getArtifact().getBaseVersion();
+ return new Dependency(key, version).setScope(node.getArtifact().getScope());
+ }
+
+ private String dependenciesToJson(List<Dependency> deps) {
+ StringBuilder json = new StringBuilder();
+ json.append('[');
+ serializeDeps(json, deps);
+ json.append(']');
+ return json.toString();
+ }
+
+ private void serializeDeps(StringBuilder json, List<Dependency> deps) {
+ for (Iterator<Dependency> dependencyIt = deps.iterator(); dependencyIt.hasNext();) {
+ serializeDep(json, dependencyIt.next());
+ if (dependencyIt.hasNext()) {
+ json.append(',');
+ }
+ }
+ }
+
+ private void serializeDep(StringBuilder json, Dependency dependency) {
+ json.append("{");
+ json.append("\"k\":");
+ json.append(dependency.key());
+ json.append(",\"v\":\"");
+ json.append(dependency.version());
+ json.append("\",\"s\":\"");
+ json.append(dependency.scope());
+ json.append("\",\"d\":[");
+ serializeDeps(json, dependency.dependencies());
+ json.append("]");
+ json.append("}");
+ }
+
private ArtifactVersion getMavenVersion() {
return runtimeInformation.getApplicationVersion();
}