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.ImmutableList; 023import com.google.common.collect.Iterables; 024import org.apache.commons.io.FileUtils; 025import org.apache.maven.project.MavenProject; 026import org.sonar.api.batch.FileFilter; 027import org.sonar.api.batch.bootstrap.ProjectDefinition; 028import org.sonar.api.resources.DefaultProjectFileSystem; 029import org.sonar.api.resources.Languages; 030import org.sonar.api.resources.Project; 031import org.sonar.api.utils.SonarException; 032 033import java.io.File; 034import java.io.IOException; 035import java.util.List; 036 037/** 038 * Implementation of {@link org.sonar.api.resources.ProjectFileSystem} based on {@link ProjectDefinition} and {@link MavenProject}. 039 */ 040public 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}