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