001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.batch;
021
022 import com.google.common.collect.Lists;
023 import com.google.common.collect.Maps;
024 import org.apache.maven.execution.MavenSession;
025 import org.apache.maven.project.MavenProject;
026 import org.slf4j.LoggerFactory;
027 import org.sonar.api.database.DatabaseSession;
028 import org.sonar.api.resources.Project;
029
030 import java.io.File;
031 import java.io.IOException;
032 import java.util.Iterator;
033 import java.util.List;
034 import java.util.Map;
035
036 public class ProjectTree {
037
038 private List<Project> projects;
039 private List<MavenProject> poms;
040 private ProjectBuilder projectBuilder;
041
042 public ProjectTree(MavenSession mavenSession, DatabaseSession databaseSession) {
043 this.poms = mavenSession.getSortedProjects();
044 this.projectBuilder = new ProjectBuilder(databaseSession);
045 }
046
047 protected ProjectTree(ProjectBuilder projectBuilder, List<MavenProject> poms) {
048 this.projectBuilder = projectBuilder;
049 this.poms = poms;
050 }
051
052 public void start() throws IOException {
053 projects = Lists.newArrayList();
054 Map<String, Project> paths = Maps.newHashMap(); // projects by canonical path
055
056 for (MavenProject pom : poms) {
057 Project project = projectBuilder.create(pom);
058 projects.add(project);
059 paths.put(pom.getBasedir().getCanonicalPath(), project);
060 }
061
062 for (Map.Entry<String, Project> entry : paths.entrySet()) {
063 Project project = entry.getValue();
064 MavenProject pom = project.getPom();
065 for (Object moduleId : pom.getModules()) {
066 File modulePath = new File(pom.getBasedir(), (String) moduleId);
067 Project module = paths.get(modulePath.getCanonicalPath());
068 if (module != null) {
069 module.setParent(project);
070 }
071 }
072 }
073
074 configureProjects();
075 applyModuleExclusions();
076 }
077
078 private void configureProjects() {
079 for (Project project : projects) {
080 projectBuilder.configure(project);
081 }
082 }
083
084 private void applyModuleExclusions() {
085 for (Project project : projects) {
086 String[] excludedArtifactIds = project.getConfiguration().getStringArray("sonar.skippedModules");
087 if (excludedArtifactIds != null) {
088 for (String excludedArtifactId : excludedArtifactIds) {
089 Project excludedProject = getProjectByArtifactId(excludedArtifactId);
090 exclude(excludedProject);
091 }
092 }
093 }
094
095 for (Iterator<Project> it = projects.iterator(); it.hasNext();) {
096 Project project = it.next();
097 if (project.isExcluded()) {
098 LoggerFactory.getLogger(getClass()).info("Module {} is excluded from analysis", project.getName());
099 project.removeFromParent();
100 it.remove();
101 }
102 }
103 }
104
105 private void exclude(Project project) {
106 if (project != null) {
107 project.setExcluded(true);
108 for (Project module : project.getModules()) {
109 exclude(module);
110 }
111 }
112 }
113
114 public List<Project> getProjects() {
115 return projects;
116 }
117
118 public Project getProjectByArtifactId(String artifactId) {
119 for (Project project : projects) {
120 if (project.getPom().getArtifactId().equals(artifactId)) {
121 return project;
122 }
123 }
124 return null;
125 }
126
127 public Project getRootProject() {
128 for (Project project : projects) {
129 if (project.getParent() == null) {
130 return project;
131 }
132 }
133 throw new IllegalStateException("Can not find the root project from the list of Maven modules");
134 }
135 }