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.ImmutableList;
023 import com.google.common.collect.Iterables;
024 import org.apache.commons.io.FileUtils;
025 import org.apache.maven.project.MavenProject;
026 import org.sonar.api.batch.FileFilter;
027 import org.sonar.api.batch.bootstrap.ProjectDefinition;
028 import org.sonar.api.resources.DefaultProjectFileSystem;
029 import org.sonar.api.resources.Languages;
030 import org.sonar.api.resources.Project;
031 import org.sonar.api.utils.SonarException;
032
033 import java.io.File;
034 import java.io.IOException;
035 import java.util.List;
036
037 /**
038 * Implementation of {@link org.sonar.api.resources.ProjectFileSystem} based on {@link ProjectDefinition} and {@link MavenProject}.
039 */
040 public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
041
042 private ProjectDefinition def;
043 private MavenProject pom;
044
045 public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, FileFilter[] fileFilters) {
046 super(project, languages, fileFilters);
047 this.def = def;
048 }
049
050 /**
051 * For Maven.
052 */
053 public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom, FileFilter[] fileFilters) {
054 this(project, languages, def, fileFilters);
055 this.pom = pom;
056 }
057
058 public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def) {
059 this(project, languages, def, new FileFilter[0]);
060 }
061
062 /**
063 * For Maven.
064 */
065 public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom) {
066 this(project, languages, def, pom, new FileFilter[0]);
067 }
068
069 @Override
070 public File getBasedir() {
071 return def.getBaseDir();
072 }
073
074 @Override
075 public File getBuildDir() {
076 if (pom != null) {
077 return resolvePath(pom.getBuild().getDirectory());
078 } else {
079 // TODO workaround
080 return new File(getSonarWorkingDirectory(), "target");
081 }
082 }
083
084 @Override
085 public File getBuildOutputDir() {
086 if (pom != null) {
087 return resolvePath(pom.getBuild().getOutputDirectory());
088 } else {
089 if (def.getBinaries().isEmpty()) {
090 // workaround for IndexOutOfBoundsException
091 return new File(getBuildDir(), "classes");
092 }
093 // TODO we assume that there is only one directory which contains compiled code
094 return resolvePath(def.getBinaries().get(0));
095 }
096 }
097
098 @Override
099 public List<File> getSourceDirs() {
100 List<File> unfiltered = resolvePaths(def.getSourceDirs());
101 return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS));
102 }
103
104 /**
105 * @deprecated since 2.6, because should be immutable
106 */
107 @Override
108 @Deprecated
109 public DefaultProjectFileSystem addSourceDir(File dir) {
110 if (dir == null) {
111 throw new IllegalArgumentException("Can not add null to project source dirs");
112 }
113 if (pom != null) {
114 pom.getCompileSourceRoots().add(0, dir.getAbsolutePath());
115 }
116 def.addSourceDirs(dir.getAbsolutePath());
117 return this;
118 }
119
120 /**
121 * Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
122 */
123 @Override
124 public List<File> getTestDirs() {
125 List<File> unfiltered = resolvePaths(def.getTestDirs());
126 return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS));
127 }
128
129 /**
130 * @deprecated since 2.6, because should be immutable
131 */
132 @Override
133 @Deprecated
134 public DefaultProjectFileSystem addTestDir(File dir) {
135 if (dir == null) {
136 throw new IllegalArgumentException("Can not add null to project test dirs");
137 }
138 if (pom != null) {
139 pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
140 }
141 def.addTestDirs(dir.getAbsolutePath());
142 return this;
143 }
144
145 /**
146 * TODO Godin: seems that used only by Cobertura and Clover
147 */
148 @Override
149 public File getReportOutputDir() {
150 if (pom != null) {
151 return resolvePath(pom.getReporting().getOutputDirectory());
152 } else {
153 return new File(getBuildDir(), "site");
154 }
155 }
156
157 @Override
158 public File getSonarWorkingDirectory() {
159 try {
160 FileUtils.forceMkdir(def.getWorkDir());
161 return def.getWorkDir();
162 } catch (IOException e) {
163 throw new SonarException("Unable to retrieve Sonar working directory.", e);
164 }
165 }
166
167 @Override
168 protected List<File> getInitialSourceFiles() {
169 return resolvePaths(def.getSourceFiles());
170 }
171
172 @Override
173 protected List<File> getInitialTestFiles() {
174 return resolvePaths(def.getTestFiles());
175 }
176 }