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    }