001/* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 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 */ 020package org.sonar.batch; 021 022import com.google.common.collect.Lists; 023import com.google.common.collect.Maps; 024import org.apache.commons.lang.ObjectUtils; 025import org.slf4j.LoggerFactory; 026import org.sonar.api.batch.bootstrap.ProjectBuilder; 027import org.sonar.api.batch.bootstrap.ProjectDefinition; 028import org.sonar.api.batch.bootstrap.ProjectReactor; 029import org.sonar.api.resources.Project; 030import org.sonar.batch.bootstrap.ProjectFilter; 031 032import java.util.Iterator; 033import java.util.List; 034import java.util.Map; 035 036public class ProjectTree { 037 038 private final ProjectConfigurator configurator; 039 private ProjectReactor projectReactor; 040 041 private List<Project> projects; 042 private Map<ProjectDefinition, Project> projectsByDef; 043 private ProjectFilter projectFilter; 044 045 public ProjectTree(ProjectReactor projectReactor, // NOSONAR the unused parameter 'builders' is used for the startup order of components 046 ProjectConfigurator projectConfigurator, 047 ProjectFilter projectFilter, 048 /* Must be executed after ProjectBuilders */ProjectBuilder[] builders) { 049 this(projectReactor, projectConfigurator, projectFilter); 050 } 051 052 public ProjectTree(ProjectReactor projectReactor, // NOSONAR the unused parameter 'builders' is used for the startup order of components 053 ProjectConfigurator projectConfigurator, 054 ProjectFilter projectFilter) { 055 this.projectReactor = projectReactor; 056 this.configurator = projectConfigurator; 057 this.projectFilter = projectFilter; 058 } 059 060 ProjectTree(ProjectConfigurator configurator) { 061 this.configurator = configurator; 062 } 063 064 public void start() { 065 doStart(projectReactor.getProjects()); 066 } 067 068 void doStart(List<ProjectDefinition> definitions) { 069 projects = Lists.newArrayList(); 070 projectsByDef = Maps.newHashMap(); 071 072 for (ProjectDefinition def : definitions) { 073 Project project = configurator.create(def); 074 projectsByDef.put(def, project); 075 projects.add(project); 076 } 077 078 for (Map.Entry<ProjectDefinition, Project> entry : projectsByDef.entrySet()) { 079 ProjectDefinition def = entry.getKey(); 080 Project project = entry.getValue(); 081 for (ProjectDefinition module : def.getSubProjects()) { 082 projectsByDef.get(module).setParent(project); 083 } 084 } 085 086 // Configure 087 for (Project project : projects) { 088 configurator.configure(project); 089 } 090 091 applyExclusions(); 092 } 093 094 void applyExclusions() { 095 for (Iterator<Project> it = projects.iterator(); it.hasNext();) { 096 Project project = it.next(); 097 if (projectFilter.isExcluded(project)) { 098 project.setExcluded(true); 099 LoggerFactory.getLogger(getClass()).info("Project {} excluded", project.getName()); 100 project.removeFromParent(); 101 it.remove(); 102 } 103 } 104 } 105 106 public List<Project> getProjects() { 107 return projects; 108 } 109 110 public Project getRootProject() { 111 for (Project project : projects) { 112 if (project.getParent() == null) { 113 return project; 114 } 115 } 116 throw new IllegalStateException("Can not find the root project from the list of Maven modules"); 117 } 118 119 public ProjectDefinition getProjectDefinition(Project project) { 120 for (Map.Entry<ProjectDefinition, Project> entry : projectsByDef.entrySet()) { 121 if (ObjectUtils.equals(entry.getValue(), project)) { 122 return entry.getKey(); 123 } 124 } 125 throw new IllegalStateException("Can not find ProjectDefinition for " + project); 126 } 127}