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 */
020 package org.sonar.batch;
021
022 import com.google.common.collect.Lists;
023 import com.google.common.collect.Maps;
024 import org.apache.commons.lang.ObjectUtils;
025 import org.slf4j.LoggerFactory;
026 import org.sonar.api.batch.bootstrap.ProjectBuilder;
027 import org.sonar.api.batch.bootstrap.ProjectDefinition;
028 import org.sonar.api.batch.bootstrap.ProjectReactor;
029 import org.sonar.api.resources.Project;
030 import org.sonar.batch.bootstrap.ProjectFilter;
031
032 import java.util.Iterator;
033 import java.util.List;
034 import java.util.Map;
035
036 public 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 }