]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-1896 SONAR-3739 improve the API of scan file system
authorSimon Brandhof <simon.brandhof@gmail.com>
Tue, 12 Feb 2013 16:56:00 +0000 (17:56 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Tue, 12 Feb 2013 16:56:23 +0000 (17:56 +0100)
53 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ProjectFileSystemLogger.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java [deleted file]
pom.xml
sonar-batch/src/main/java/org/sonar/batch/AbstractMavenPluginExecutor.java
sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/FakeMavenPluginExecutor.java
sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java
sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/InspectionContainer.java
sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java
sonar-batch/src/main/java/org/sonar/batch/phases/InitializersExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/MavenPhaseExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/PostJobsExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/SensorsExecutor.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileSystemAdapter.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionFileFilter.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionPatterns.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageFileFilters.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProvider.java
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/AbstractMavenPluginExecutorTest.java
sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java
sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java
sonar-batch/src/test/java/org/sonar/batch/phases/MavenPhaseExecutorTest.java
sonar-batch/src/test/java/org/sonar/batch/phases/PostJobsExecutorTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFileFilterTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionPatternsTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProviderTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java [deleted file]
sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt [deleted file]
sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreUpdaterTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectFileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FailToCreateFileException.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleExclusions.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/PathResolver.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java
sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/JavaIoFileFilterTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/ModuleExclusionsTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/PathResolverTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/test/MavenTestUtils.java

index 44dea68056068ada73de462f7bf660f984a97998..0a136a4fcefb64e67d41e25e5b23477a20984ee0 100644 (file)
@@ -29,10 +29,8 @@ import org.sonar.api.checks.NoSonarFilter;
 import org.sonar.api.notifications.NotificationDispatcherMetadata;
 import org.sonar.api.resources.Java;
 import org.sonar.core.timemachine.Periods;
-import org.sonar.plugins.core.batch.ExcludedResourceFilter;
 import org.sonar.plugins.core.batch.IndexProjectPostJob;
 import org.sonar.plugins.core.batch.MavenInitializer;
-import org.sonar.plugins.core.batch.ProjectFileSystemLogger;
 import org.sonar.plugins.core.charts.DistributionAreaChart;
 import org.sonar.plugins.core.charts.DistributionBarChart;
 import org.sonar.plugins.core.charts.XradarChart;
@@ -413,7 +411,6 @@ public final class CorePlugin extends SonarPlugin {
     return ImmutableList.of(
       DefaultResourceTypes.class,
       UserManagedMetrics.class,
-      ProjectFileSystemLogger.class,
       Periods.class,
 
       // maven
@@ -495,7 +492,6 @@ public final class CorePlugin extends SonarPlugin {
       OverallCoverageDecorator.class,
       OverallBranchCoverageDecorator.class,
       ApplyProjectRolesDecorator.class,
-      ExcludedResourceFilter.class,
       CommentDensityDecorator.class,
       NoSonarFilter.class,
       DirectoriesDecorator.class,
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java
deleted file mode 100644 (file)
index 46516ff..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.core.batch;
-
-import org.sonar.api.batch.ResourceFilter;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-
-/**
- * @since 1.12
- */
-public class ExcludedResourceFilter implements ResourceFilter {
-  private final Project project;
-
-  public ExcludedResourceFilter(Project project) {
-    this.project = project;
-  }
-
-  public boolean isIgnored(Resource resource) {
-    String[] patterns = ResourceUtils.isUnitTestClass(resource) ? project.getTestExclusionPatterns() : project.getExclusionPatterns();
-    if (patterns == null) {
-      return false;
-    }
-
-    for (String pattern : patterns) {
-      if (resource.matchFilePattern(pattern)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ProjectFileSystemLogger.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ProjectFileSystemLogger.java
deleted file mode 100644 (file)
index 3364e99..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.core.batch;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.Initializer;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.ProjectFileSystem;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class ProjectFileSystemLogger extends Initializer {
-  private static final Logger LOG = LoggerFactory.getLogger(ProjectFileSystemLogger.class);
-
-  @Override
-  public void execute(Project project) {
-    logExclusionPatterns("Excluded sources: {}", project.getExclusionPatterns());
-    logExclusionPatterns("Excluded tests: {}", project.getTestExclusionPatterns());
-
-    ProjectFileSystem projectFileSystem = project.getFileSystem();
-    logDirectories("Source directories:", projectFileSystem.getSourceDirs());
-    logDirectories("Test directories:", projectFileSystem.getTestDirs());
-  }
-
-  private void logExclusionPatterns(String message, String[] exclusionPatterns) {
-    if (exclusionPatterns != null && exclusionPatterns.length > 0) {
-      LOG.info(message, Arrays.toString(exclusionPatterns));
-    }
-  }
-
-  private void logDirectories(String name, List<java.io.File> dirs) {
-    if (!dirs.isEmpty()) {
-      LOG.info(name);
-      for (java.io.File dir : dirs) {
-        LOG.info("  {}", dir);
-      }
-    }
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java
deleted file mode 100644 (file)
index 1b9612a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.core.batch;
-
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ExcludedResourceFilterTest {
-
-  @Test
-  public void doNotFailIfNoPatterns() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    Project project = new Project("foo").setConfiguration(conf);
-    ExcludedResourceFilter filter = new ExcludedResourceFilter(project);
-    assertThat(filter.isIgnored(mock(Resource.class)), is(false));
-  }
-
-  @Test
-  public void noPatternsMatch() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, new String[]{"**/foo/*.java", "**/bar/*"});
-    Project project = new Project("foo").setConfiguration(conf);
-    ExcludedResourceFilter filter = new ExcludedResourceFilter(project);
-    assertThat(filter.isIgnored(mock(Resource.class)), is(false));
-  }
-
-  @Test
-  public void ignoreResourceIfMatchesPattern() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, new String[]{"**/foo/*.java", "**/bar/*"});
-    Project project = new Project("foo").setConfiguration(conf);
-    ExcludedResourceFilter filter = new ExcludedResourceFilter(project);
-
-    Resource resource = mock(Resource.class);
-    when(resource.matchFilePattern("**/bar/*")).thenReturn(true);
-
-    assertThat(filter.isIgnored(resource), is(true));
-  }
-
-  @Test
-  public void ignoreTestIfMatchesPattern() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, new String[]{"**/foo/*.java", "**/bar/*"});
-    Project project = new Project("foo").setConfiguration(conf);
-    ExcludedResourceFilter filter = new ExcludedResourceFilter(project);
-
-    Resource resource = mock(Resource.class);
-    when(resource.getQualifier()).thenReturn(Qualifiers.UNIT_TEST_FILE);
-    when(resource.matchFilePattern("**/bar/*")).thenReturn(true);
-
-    assertThat(filter.isIgnored(resource), is(true));
-  }
-
-  /**
-   * See SONAR-1115 Source exclusion patterns do not apply to unit tests.
-   */
-  @Test
-  public void doNotExcludeUnitTestFiles() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, new String[]{"**/foo/*.java", "**/bar/*"});
-    Project project = new Project("foo").setConfiguration(conf);
-    ExcludedResourceFilter filter = new ExcludedResourceFilter(project);
-
-    Resource unitTest = mock(Resource.class);
-    when(unitTest.getQualifier()).thenReturn(Qualifiers.UNIT_TEST_FILE);
-
-    // match exclusion pattern
-    when(unitTest.matchFilePattern("**/bar/*")).thenReturn(true);
-
-    assertThat(filter.isIgnored(unitTest), is(false));
-  }
-}
diff --git a/pom.xml b/pom.xml
index 54e58423ceb4883efedc86b7c466b9c9018a8302..812cb733a531be730ed3ec010737a90e140ef5e1 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -71,7 +71,7 @@
   </prerequisites>
 
   <properties>
-    <sonarJava.version>1.1</sonarJava.version>
+    <sonarJava.version>1.2-SNAPSHOT</sonarJava.version>
     <sonarGwt.version>3.3.1</sonarGwt.version>
     <h2.version>1.3.167</h2.version>
     <jetty.version>6.1.25</jetty.version>
index c29939a57385300e11e4a4cc30deac3b5e1d347d..a97525439438984d9b79b0b748518b765824edd8 100644 (file)
@@ -26,23 +26,24 @@ import org.sonar.api.batch.maven.MavenPluginHandler;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.SonarException;
 import org.sonar.api.utils.TimeProfiler;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 /**
  * Abstract implementation of {@link MavenPluginExecutor} to reduce duplications in concrete implementations for different Maven versions.
  */
 public abstract class AbstractMavenPluginExecutor implements MavenPluginExecutor {
 
-  public final MavenPluginHandler execute(Project project, ProjectDefinition projectDefinition, MavenPluginHandler handler) {
+  public final MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) {
     for (String goal : handler.getGoals()) {
       MavenPlugin plugin = MavenPlugin.getPlugin(project.getPom(), handler.getGroupId(), handler.getArtifactId());
       execute(project,
-          projectDefinition,
+          fs,
           getGoal(handler.getGroupId(), handler.getArtifactId(), (plugin != null && plugin.getPlugin() != null ? plugin.getPlugin().getVersion() : null), goal));
     }
     return handler;
   }
 
-  public final void execute(Project project, ProjectDefinition projectDefinition, String goal) {
+  public final void execute(Project project, DefaultModuleFileSystem fs, String goal) {
     TimeProfiler profiler = new TimeProfiler().start("Execute " + goal);
     ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
     try {
@@ -56,7 +57,7 @@ public abstract class AbstractMavenPluginExecutor implements MavenPluginExecutor
     }
 
     if (project.getPom() != null) {
-      MavenProjectConverter.synchronizeFileSystem(project.getPom(), projectDefinition);
+      MavenProjectConverter.synchronizeFileSystem(project.getPom(), fs);
     }
   }
 
diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java
deleted file mode 100644 (file)
index 2dfe6db..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import org.apache.commons.io.FileUtils;
-import org.apache.maven.project.MavenProject;
-import org.sonar.api.batch.FileFilter;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.resources.DefaultProjectFileSystem;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.SonarException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Implementation of {@link org.sonar.api.resources.ProjectFileSystem} based on {@link ProjectDefinition} and {@link MavenProject}.
- */
-public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
-
-  private ProjectDefinition def;
-  private MavenProject pom;
-
-  public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, FileFilter[] fileFilters) {
-    super(project, languages, fileFilters);
-    this.def = def;
-  }
-
-  /**
-   * For Maven.
-   */
-  public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom, FileFilter[] fileFilters) {
-    this(project, languages, def, fileFilters);
-    this.pom = pom;
-  }
-
-  public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def) {
-    this(project, languages, def, new FileFilter[0]);
-  }
-
-  /**
-   * For Maven.
-   */
-  public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom) {
-    this(project, languages, def, pom, new FileFilter[0]);
-  }
-
-  @Override
-  public File getBasedir() {
-    return def.getBaseDir();
-  }
-
-  @Override
-  public File getBuildDir() {
-    if (pom != null) {
-      return resolvePath(pom.getBuild().getDirectory());
-    } else {
-      // TODO workaround
-      return new File(getSonarWorkingDirectory(), "target");
-    }
-  }
-
-  @Override
-  public File getBuildOutputDir() {
-    if (pom != null) {
-      return resolvePath(pom.getBuild().getOutputDirectory());
-    } else {
-      if (def.getBinaries().isEmpty()) {
-        // workaround for IndexOutOfBoundsException
-        return new File(getBuildDir(), "classes");
-      }
-      // TODO we assume that there is only one directory which contains compiled code
-      return resolvePath(def.getBinaries().get(0));
-    }
-  }
-
-  @Override
-  public List<File> getSourceDirs() {
-    List<File> unfiltered = resolvePaths(def.getSourceDirs());
-    return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS));
-  }
-
-  /**
-   * @deprecated since 2.6, because should be immutable
-   */
-  @Override
-  @Deprecated
-  public DefaultProjectFileSystem addSourceDir(File dir) {
-    if (dir == null) {
-      throw new IllegalArgumentException("Can not add null to project source dirs");
-    }
-    if (pom != null) {
-      pom.getCompileSourceRoots().add(0, dir.getAbsolutePath());
-    }
-    def.addSourceDirs(dir.getAbsolutePath());
-    return this;
-  }
-
-  /**
-   * Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
-   */
-  @Override
-  public List<File> getTestDirs() {
-    List<File> unfiltered = resolvePaths(def.getTestDirs());
-    return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS));
-  }
-
-  /**
-   * @deprecated since 2.6, because should be immutable
-   */
-  @Override
-  @Deprecated
-  public DefaultProjectFileSystem addTestDir(File dir) {
-    if (dir == null) {
-      throw new IllegalArgumentException("Can not add null to project test dirs");
-    }
-    if (pom != null) {
-      pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
-    }
-    def.addTestDirs(dir.getAbsolutePath());
-    return this;
-  }
-
-  /**
-   * TODO Godin: seems that used only by Cobertura and Clover
-   */
-  @Override
-  public File getReportOutputDir() {
-    if (pom != null) {
-      return resolvePath(pom.getReporting().getOutputDirectory());
-    } else {
-      return new File(getBuildDir(), "site");
-    }
-  }
-
-  @Override
-  public File getSonarWorkingDirectory() {
-    try {
-      FileUtils.forceMkdir(def.getWorkDir());
-      return def.getWorkDir();
-    } catch (IOException e) {
-      throw new SonarException("Unable to retrieve Sonar working directory.", e);
-    }
-  }
-
-  @Override
-  protected List<File> getInitialSourceFiles() {
-    return resolvePaths(def.getSourceFiles());
-  }
-
-  @Override
-  protected List<File> getInitialTestFiles() {
-    return resolvePaths(def.getTestFiles());
-  }
-
-  // Hack to instantiate DefaultProjectFileSystem2 before executing Phases.
-  // TODO all the project bootstrapping must be refactored. It's overcomplicated.
-  public void start() {
-
-  }
-}
index cd31e21bbda19f8c6815e8f785c93fa1adaef972..0129cf50fdf733efb0bd4a5851874e050bcbae40 100644 (file)
  */
 package org.sonar.batch;
 
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.maven.MavenPluginHandler;
 import org.sonar.api.resources.Project;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 public final class FakeMavenPluginExecutor implements MavenPluginExecutor {
-  public void execute(Project project, ProjectDefinition projectDef, String goal) {
+  public void execute(Project project, DefaultModuleFileSystem fs, String goal) {
     // do nothing
   }
 
-  public MavenPluginHandler execute(Project project, ProjectDefinition projectDefinition, MavenPluginHandler handler) {
+  public MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) {
     // do nothing
     return handler;
   }
index 55d18caa39bf8344f8dda7840dd40b018c5464cd..89bc49f577e4294da15f4ceeb0e6e08aae30fee0 100644 (file)
@@ -23,11 +23,12 @@ import org.sonar.api.BatchComponent;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.maven.MavenPluginHandler;
 import org.sonar.api.resources.Project;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 public interface MavenPluginExecutor extends BatchComponent {
 
-  void execute(Project project, ProjectDefinition def, String goal);
+  void execute(Project project, DefaultModuleFileSystem def, String goal);
 
-  MavenPluginHandler execute(Project project, ProjectDefinition def, MavenPluginHandler handler);
+  MavenPluginHandler execute(Project project, DefaultModuleFileSystem def, MavenPluginHandler handler);
 
 }
index 9e214b5611783823085915f914061f3e7600c381..7aecc6d72d33459091d79b521314a06eb7a9bf5b 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.batch;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.commons.lang.StringUtils;
 import org.apache.maven.model.CiManagement;
@@ -29,16 +30,18 @@ import org.apache.maven.project.MavenProject;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.utils.SonarException;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
 public final class MavenProjectConverter {
 
   private static final String UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE = "Unable to determine structure of project." +
-      " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used.";
+    " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used.";
 
   private MavenProjectConverter() {
     // only static methods
@@ -104,12 +107,12 @@ public final class MavenProjectConverter {
     ProjectDefinition definition = ProjectDefinition.create();
     // IMPORTANT NOTE : reference on properties from POM model must not be saved, instead they should be copied explicitly - see SONAR-2896
     definition
-        .setProperties(pom.getModel().getProperties())
-        .setKey(key)
-        .setVersion(pom.getVersion())
-        .setName(pom.getName())
-        .setDescription(pom.getDescription())
-        .addContainerExtension(pom);
+      .setProperties(pom.getModel().getProperties())
+      .setKey(key)
+      .setVersion(pom.getVersion())
+      .setName(pom.getName())
+      .setDescription(pom.getDescription())
+      .addContainerExtension(pom);
 
     convertMavenLinksToProperties(definition, pom);
 
@@ -152,20 +155,53 @@ public final class MavenProjectConverter {
 
   public static void synchronizeFileSystem(MavenProject pom, ProjectDefinition into) {
     into.setBaseDir(pom.getBasedir());
-    into.setWorkDir(new File(resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), "sonar"));
+    File buildDir = resolvePath(pom.getBuild().getDirectory(), pom.getBasedir());
+    if (buildDir != null) {
+      into.setBuildDir(buildDir);
+      into.setWorkDir(new File(buildDir, "sonar"));
+    }
     into.setSourceDirs((String[]) pom.getCompileSourceRoots().toArray(new String[pom.getCompileSourceRoots().size()]));
     into.setTestDirs((String[]) pom.getTestCompileSourceRoots().toArray(new String[pom.getTestCompileSourceRoots().size()]));
+    File binaryDir = resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir());
+    if (binaryDir != null) {
+      into.addBinaryDir(binaryDir);
+    }
+  }
+
+  public static void synchronizeFileSystem(MavenProject pom, DefaultModuleFileSystem into) {
+    into.resetDirs(
+      pom.getBasedir(),
+      new File(resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), "sonar"),
+      resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()),
+      resolvePaths((List<String>) pom.getCompileSourceRoots(), pom.getBasedir()),
+      resolvePaths((List<String>) pom.getTestCompileSourceRoots(), pom.getBasedir()),
+      Arrays.asList(resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir()))
+    );
   }
 
   static File resolvePath(String path, File basedir) {
-    File file = new File(path);
-    if (!file.isAbsolute()) {
-      try {
-        file = new File(basedir, path).getCanonicalFile();
-      } catch (IOException e) {
-        throw new SonarException("Unable to resolve path '" + path + "'", e);
+    if (path != null) {
+      File file = new File(path);
+      if (!file.isAbsolute()) {
+        try {
+          file = new File(basedir, path).getCanonicalFile();
+        } catch (IOException e) {
+          throw new SonarException("Unable to resolve path '" + path + "'", e);
+        }
+      }
+      return file;
+    }
+    return null;
+  }
+
+  static List<File> resolvePaths(List<String> paths, File basedir) {
+    List<File> result = Lists.newArrayList();
+    for (String path : paths) {
+      File dir = resolvePath(path, basedir);
+      if (dir != null) {
+        result.add(dir);
       }
     }
-    return file;
+    return result;
   }
 }
index 83d16a37fe60ed138bcb66b7eea090daecd898dd..2885cfd3ffbc318c38cf4b530c3f914469d4505a 100644 (file)
@@ -26,9 +26,10 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.resources.Project;
+import org.sonar.api.scan.filesystem.ModuleExclusions;
+import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.batch.DefaultProfileLoader;
 import org.sonar.batch.DefaultProjectClasspath;
-import org.sonar.batch.DefaultProjectFileSystem2;
 import org.sonar.batch.DefaultSensorContext;
 import org.sonar.batch.DefaultTimeMachine;
 import org.sonar.batch.ProfileProvider;
@@ -42,6 +43,10 @@ import org.sonar.batch.index.ResourcePersister;
 import org.sonar.batch.local.DryRunExporter;
 import org.sonar.batch.phases.Phases;
 import org.sonar.batch.phases.PhasesTimeProfiler;
+import org.sonar.batch.scan.filesystem.DeprecatedFileSystemAdapter;
+import org.sonar.batch.scan.filesystem.ExclusionFileFilter;
+import org.sonar.batch.scan.filesystem.LanguageFileFilters;
+import org.sonar.batch.scan.filesystem.ModuleFileSystemProvider;
 import org.sonar.core.qualitymodel.DefaultModelFinder;
 import org.sonar.jpa.dao.ProfilesDao;
 import org.sonar.jpa.dao.RulesDao;
@@ -83,10 +88,18 @@ public class InspectionContainer extends Container {
       container.addSingleton(component);
     }
     container.addSingleton(Languages.class);
-    container.addSingleton(DefaultProjectClasspath.class);
-    container.addSingleton(DefaultProjectFileSystem2.class);
     container.addSingleton(RulesDao.class);
 
+    // file system
+    container.addSingleton(PathResolver.class);
+    container.addSingleton(ModuleExclusions.class);
+    container.addSingleton(LanguageFileFilters.class);
+    container.addSingleton(ExclusionFileFilter.class);
+    container.addSingleton(DefaultProjectClasspath.class);
+    container.addPicoAdapter(new ModuleFileSystemProvider());
+    container.addSingleton(DeprecatedFileSystemAdapter.class);
+
+
     // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
     container.addSingleton(container.getComponentByType(ResourcePersister.class).getSnapshot(project));
 
@@ -120,9 +133,9 @@ public class InspectionContainer extends Container {
   protected void doStart() {
     DefaultIndex index = container.getComponentByType(DefaultIndex.class);
     index.setCurrentProject(project,
-        container.getComponentByType(ResourceFilters.class),
-        container.getComponentByType(ViolationFilters.class),
-        container.getComponentByType(RulesProfile.class));
+      container.getComponentByType(ResourceFilters.class),
+      container.getComponentByType(ViolationFilters.class),
+      container.getComponentByType(RulesProfile.class));
 
     container.getComponentByType(Phases.class).execute(project);
   }
index 6f478c2fda7378b387c8ded74005f5f86761ce07..e2a82ed534268fce020de71b4f4fffca4a0e8ce8 100644 (file)
@@ -29,10 +29,10 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.Server;
-import org.sonar.api.resources.ProjectFileSystem;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.Violation;
+import org.sonar.api.scan.filesystem.ModuleFileSystem;
 import org.sonar.api.utils.SonarException;
 import org.sonar.batch.index.DefaultIndex;
 import org.sonar.core.i18n.RuleI18nManager;
@@ -54,14 +54,14 @@ public class DryRunExporter implements BatchComponent {
 
   private final Settings settings;
   private final DefaultIndex sonarIndex;
-  private final ProjectFileSystem projectFileSystem;
+  private final ModuleFileSystem fileSystem;
   private final Server server;
   private final RuleI18nManager ruleI18nManager;
 
-  public DryRunExporter(Settings settings, DefaultIndex sonarIndex, ProjectFileSystem projectFileSystem, Server server, RuleI18nManager ruleI18nManager) {
+  public DryRunExporter(Settings settings, DefaultIndex sonarIndex, ModuleFileSystem fileSystem, Server server, RuleI18nManager ruleI18nManager) {
     this.settings = settings;
     this.sonarIndex = sonarIndex;
-    this.projectFileSystem = projectFileSystem;
+    this.fileSystem = fileSystem;
     this.server = server;
     this.ruleI18nManager = ruleI18nManager;
   }
@@ -73,7 +73,7 @@ public class DryRunExporter implements BatchComponent {
   }
 
   private void exportResults(Collection<Resource> resources) {
-    File exportFile = new File(projectFileSystem.getSonarWorkingDirectory(), settings.getString("sonar.dryRun.export.path"));
+    File exportFile = new File(fileSystem.workingDir(), settings.getString("sonar.dryRun.export.path"));
 
     LOG.info("Exporting DryRun results to " + exportFile.getAbsolutePath());
     Writer output = null;
index 7f37d4cb18c119218270697e0e63a0849fa2487c..f4d58be33e8e23c77865a2d13809360234d205ef 100644 (file)
@@ -24,12 +24,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.BatchExtensionDictionnary;
 import org.sonar.api.batch.Initializer;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.maven.DependsUponMavenPlugin;
 import org.sonar.api.batch.maven.MavenPluginHandler;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.TimeProfiler;
 import org.sonar.batch.MavenPluginExecutor;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import java.util.Collection;
 
@@ -39,15 +39,15 @@ public class InitializersExecutor {
 
   private MavenPluginExecutor mavenExecutor;
 
-  private ProjectDefinition projectDef;
+  private DefaultModuleFileSystem fs;
   private Project project;
   private BatchExtensionDictionnary selector;
 
-  public InitializersExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDef, MavenPluginExecutor mavenExecutor) {
+  public InitializersExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor) {
     this.selector = selector;
     this.mavenExecutor = mavenExecutor;
     this.project = project;
-    this.projectDef = projectDef;
+    this.fs = fs;
   }
 
   public void execute() {
@@ -70,7 +70,7 @@ public class InitializersExecutor {
       MavenPluginHandler handler = ((DependsUponMavenPlugin) sensor).getMavenPluginHandler(project);
       if (handler != null) {
         TimeProfiler profiler = new TimeProfiler(LOG).start("Execute maven plugin " + handler.getArtifactId());
-        mavenExecutor.execute(project, projectDef, handler);
+        mavenExecutor.execute(project, fs, handler);
         profiler.stop();
       }
     }
index a6d88708d867e03dc3f4422fdfb3168ea05e42c8..87d397d5a302ca55d32aef0c0a43c488ca49958f 100644 (file)
@@ -24,23 +24,24 @@ import org.sonar.api.BatchComponent;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.resources.Project;
 import org.sonar.batch.MavenPluginExecutor;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 public class MavenPhaseExecutor implements BatchComponent {
 
   public static final String PROP_PHASE = "sonar.phase";
 
   private MavenPluginExecutor executor;
-  private ProjectDefinition projectDef;
+  private DefaultModuleFileSystem fs;
 
-  public MavenPhaseExecutor(ProjectDefinition projectDef, MavenPluginExecutor executor) {
-    this.projectDef = projectDef;
+  public MavenPhaseExecutor(DefaultModuleFileSystem fs, MavenPluginExecutor executor) {
+    this.fs = fs;
     this.executor = executor;
   }
 
   public void execute(Project project) {
     String mavenPhase = (String) project.getProperty(PROP_PHASE);
     if (!StringUtils.isBlank(mavenPhase)) {
-      executor.execute(project, projectDef, mavenPhase);
+      executor.execute(project, fs, mavenPhase);
     }
   }
 }
index f5530102336eeea08a16fe1d1917ab875b8f8f6c..e2871b9b63264ec16a0b4c9c8e78988f3c76e998 100644 (file)
@@ -26,12 +26,12 @@ import org.sonar.api.BatchComponent;
 import org.sonar.api.batch.BatchExtensionDictionnary;
 import org.sonar.api.batch.PostJob;
 import org.sonar.api.batch.SensorContext;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.maven.DependsUponMavenPlugin;
 import org.sonar.api.batch.maven.MavenPluginHandler;
 import org.sonar.api.resources.Project;
 import org.sonar.batch.MavenPluginExecutor;
 import org.sonar.batch.local.DryRunExporter;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import java.util.Collection;
 
@@ -40,15 +40,15 @@ public class PostJobsExecutor implements BatchComponent {
 
   private final BatchExtensionDictionnary selector;
   private final Project project;
-  private final ProjectDefinition projectDefinition;
+  private final DefaultModuleFileSystem fs;
   private final MavenPluginExecutor mavenExecutor;
   private final DryRunExporter localModeExporter;
 
-  public PostJobsExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDefinition, MavenPluginExecutor mavenExecutor,
-      DryRunExporter localModeExporter) {
+  public PostJobsExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor,
+                          DryRunExporter localModeExporter) {
     this.selector = selector;
     this.project = project;
-    this.projectDefinition = projectDefinition;
+    this.fs = fs;
     this.mavenExecutor = mavenExecutor;
     this.localModeExporter = localModeExporter;
   }
@@ -79,7 +79,7 @@ public class PostJobsExecutor implements BatchComponent {
     if (job instanceof DependsUponMavenPlugin) {
       MavenPluginHandler handler = ((DependsUponMavenPlugin) job).getMavenPluginHandler(project);
       if (handler != null) {
-        mavenExecutor.execute(project, projectDefinition, handler);
+        mavenExecutor.execute(project, fs, handler);
       }
     }
   }
index ac8f7ca756cb4a48ad66c91071c5b50877514b1b..d08ae6cba8be678d588dcbfea08f9f888e376928 100644 (file)
@@ -33,6 +33,7 @@ import org.sonar.api.resources.Project;
 import org.sonar.api.utils.TimeProfiler;
 import org.sonar.batch.MavenPluginExecutor;
 import org.sonar.batch.events.EventBus;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import java.util.Collection;
 
@@ -42,15 +43,15 @@ public class SensorsExecutor implements BatchComponent {
   private MavenPluginExecutor mavenExecutor;
   private EventBus eventBus;
   private Project project;
-  private ProjectDefinition projectDefinition;
+  private DefaultModuleFileSystem fs;
   private BatchExtensionDictionnary selector;
 
-  public SensorsExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDefinition, MavenPluginExecutor mavenExecutor, EventBus eventBus) {
+  public SensorsExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor, EventBus eventBus) {
     this.selector = selector;
     this.mavenExecutor = mavenExecutor;
     this.eventBus = eventBus;
     this.project = project;
-    this.projectDefinition = projectDefinition;
+    this.fs = fs;
   }
 
   public void execute(SensorContext context) {
@@ -73,7 +74,7 @@ public class SensorsExecutor implements BatchComponent {
       MavenPluginHandler handler = ((DependsUponMavenPlugin) sensor).getMavenPluginHandler(project);
       if (handler != null) {
         TimeProfiler profiler = new TimeProfiler(LOG).start("Execute maven plugin " + handler.getArtifactId());
-        mavenExecutor.execute(project, projectDefinition, handler);
+        mavenExecutor.execute(project, fs, handler);
         profiler.stop();
       }
     }
index 10733249b6a4ac11bc44d978e672c12f40189b5b..9b864e150de60e55709762fbf6e755b327e139b3 100644 (file)
@@ -29,6 +29,7 @@ import org.apache.commons.io.filefilter.IOFileFilter;
 import org.apache.commons.io.filefilter.TrueFileFilter;
 import org.sonar.api.scan.filesystem.FileFilter;
 import org.sonar.api.scan.filesystem.ModuleFileSystem;
+import org.sonar.api.scan.filesystem.PathResolver;
 
 import java.io.File;
 import java.nio.charset.Charset;
@@ -46,7 +47,7 @@ public class DefaultModuleFileSystem implements ModuleFileSystem {
   private static final IOFileFilter DIR_FILTER = FileFilterUtils.and(HiddenFileFilter.VISIBLE, FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter(".")));
 
   private final Charset sourceCharset;
-  private File baseDir, workingDir;
+  private File baseDir, workingDir, buildDir;
   private List<File> sourceDirs, testDirs, binaryDirs;
   private final PathResolver pathResolver;
   private final List<FileFilter> fileFilters;
@@ -55,6 +56,7 @@ public class DefaultModuleFileSystem implements ModuleFileSystem {
   private DefaultModuleFileSystem(Builder builder) {
     sourceCharset = builder.sourceCharset;
     baseDir = builder.baseDir;
+    buildDir = builder.buildDir;
     workingDir = builder.workingDir;
     sourceDirs = ImmutableList.copyOf(builder.sourceDirs);
     testDirs = ImmutableList.copyOf(builder.testDirs);
@@ -68,6 +70,10 @@ public class DefaultModuleFileSystem implements ModuleFileSystem {
     return baseDir;
   }
 
+  public File buildDir() {
+    return buildDir;
+  }
+
   public List<File> sourceDirs() {
     return sourceDirs;
   }
@@ -119,12 +125,24 @@ public class DefaultModuleFileSystem implements ModuleFileSystem {
   /**
    * Breaks immutability but it's required to allow Maven Plugins to be executed and to change project structure.
    */
-  public void resetDirs(File basedir, File workDir, List<File> sourceDirs, List<File> testDirs, List<File> binaryDirs) {
+  public void resetDirs(File basedir, File workDir, File buildDir, List<File> sourceDirs, List<File> testDirs, List<File> binaryDirs) {
+    Preconditions.checkNotNull(basedir, "Basedir can't be null");
     this.baseDir = basedir;
     this.workingDir = workDir;
-    this.sourceDirs = ImmutableList.copyOf(sourceDirs);
-    this.testDirs = ImmutableList.copyOf(testDirs);
-    this.binaryDirs = ImmutableList.copyOf(binaryDirs);
+    this.buildDir = buildDir;
+    this.sourceDirs = existingDirs(sourceDirs);
+    this.testDirs = existingDirs(testDirs);
+    this.binaryDirs = existingDirs(binaryDirs);
+  }
+
+  private List<File> existingDirs(List<File> dirs) {
+    ImmutableList.Builder<File> builder = ImmutableList.builder();
+    for (File dir : dirs) {
+      if (dir.exists() && dir.isDirectory()) {
+        builder.add(dir);
+      }
+    }
+    return builder.build();
   }
 
   private List<File> files(List<File> dirs, FileFilter.FileType fileType, IOFileFilter languageFilter) {
@@ -167,7 +185,7 @@ public class DefaultModuleFileSystem implements ModuleFileSystem {
 
   static final class Builder {
     private Charset sourceCharset;
-    private File baseDir, workingDir;
+    private File baseDir, workingDir, buildDir;
     private List<File> sourceDirs = Lists.newArrayList(), testDirs = Lists.newArrayList(), binaryDirs = Lists.newArrayList();
     private List<FileFilter> fileFilters = Lists.newArrayList();
     private PathResolver pathResolver;
@@ -178,13 +196,18 @@ public class DefaultModuleFileSystem implements ModuleFileSystem {
       return this;
     }
 
-    Builder baseDir(File f) {
-      this.baseDir = f;
+    Builder baseDir(File d) {
+      this.baseDir = d;
+      return this;
+    }
+
+    Builder buildDir(File d) {
+      this.buildDir = d;
       return this;
     }
 
-    Builder workingDir(File f) {
-      this.workingDir = f;
+    Builder workingDir(File d) {
+      this.workingDir = d;
       return this;
     }
 
index a0a8120951b27cc9b5665b614544b53d8e37612f..92a98988f5bbfcd44ac36d54a2dbbac5eb96baa0 100644 (file)
@@ -23,26 +23,46 @@ import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.CharEncoding;
+import org.apache.maven.project.MavenProject;
 import org.sonar.api.resources.InputFile;
+import org.sonar.api.resources.InputFileUtils;
 import org.sonar.api.resources.Java;
 import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Project;
 import org.sonar.api.resources.ProjectFileSystem;
 import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.ModuleFileSystem;
+import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.api.utils.SonarException;
+
+import javax.annotation.Nullable;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.List;
 
+/**
+ * Adapter for keeping the backward-compatibility of the deprecated component {@link org.sonar.api.resources.ProjectFileSystem}
+ * @since 3.5
+ */
 public class DeprecatedFileSystemAdapter implements ProjectFileSystem {
 
-  private final ModuleFileSystem target;
-  private final PathResolver pathResolver;
+  private final DefaultModuleFileSystem target;
+  private final PathResolver pathResolver = new PathResolver();
+  private final MavenProject pom;
+
 
-  public DeprecatedFileSystemAdapter(ModuleFileSystem target, PathResolver pathResolver) {
+  public DeprecatedFileSystemAdapter(DefaultModuleFileSystem target, Project project, @Nullable MavenProject pom) {
     this.target = target;
-    this.pathResolver = pathResolver;
+    this.pom = pom;
+
+    // TODO See http://jira.codehaus.org/browse/SONAR-2126
+    // previously MavenProjectBuilder was responsible for creation of ProjectFileSystem
+    project.setFileSystem(this);
+  }
+
+  public DeprecatedFileSystemAdapter(DefaultModuleFileSystem target, Project project) {
+    this(target, project, null);
   }
 
   public Charset getSourceCharset() {
@@ -54,12 +74,22 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem {
   }
 
   public File getBuildDir() {
-    // TODO
-    return null;
+    File dir = target.buildDir();
+    if (dir == null) {
+      // emulate build dir to keep backward-compatibility
+      dir = new File(getSonarWorkingDirectory(), "build");
+    }
+    return dir;
   }
 
   public File getBuildOutputDir() {
-    return Iterables.getFirst(target.binaryDirs(), null);
+    File dir = Iterables.getFirst(target.binaryDirs(), null);
+    if (dir == null) {
+      // emulate binary dir
+      dir = new File(getBuildDir(), "classes");
+    }
+
+    return dir;
   }
 
   public List<File> getSourceDirs() {
@@ -79,8 +109,11 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem {
   }
 
   public File getReportOutputDir() {
-    // TODO
-    return null;
+    if (pom != null) {
+      return resolvePath(pom.getReporting().getOutputDirectory());
+    }
+    // emulate Maven report output dir
+    return new File(getBuildDir(), "site");
   }
 
   public File getSonarWorkingDirectory() {
@@ -88,8 +121,15 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem {
   }
 
   public File resolvePath(String path) {
-    // TODO
-    return null;
+    File file = new File(path);
+    if (!file.isAbsolute()) {
+      try {
+        file = new File(getBasedir(), path).getCanonicalFile();
+      } catch (IOException e) {
+        throw new SonarException("Unable to resolve path '" + path + "'", e);
+      }
+    }
+    return file;
   }
 
   public List<File> getSourceFiles(Language... langs) {
@@ -132,17 +172,41 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem {
   }
 
   public Resource toResource(File file) {
-    // TODO
-    return null;
+    if (file == null || !file.exists()) {
+      return null;
+    }
+    PathResolver.RelativePath relativePath = pathResolver.relativePath(getSourceDirs(), file);
+    if (relativePath == null) {
+      return null;
+    }
+    return (file.isFile() ? new org.sonar.api.resources.File(relativePath.path()) : new org.sonar.api.resources.Directory(relativePath.path()));
   }
 
   public List<InputFile> mainFiles(String... langs) {
-    // TODO
-    return null;
+    List<InputFile> result = Lists.newArrayList();
+    for (String lang : langs) {
+      List<File> files = target.sourceFilesOfLang(lang);
+      for (File file : files) {
+        PathResolver.RelativePath relativePath = pathResolver.relativePath(getSourceDirs(), file);
+        if (relativePath != null) {
+          result.add(InputFileUtils.create(relativePath.dir(), relativePath.path()));
+        }
+      }
+    }
+    return result;
   }
 
   public List<InputFile> testFiles(String... langs) {
-    // TODO
-    return null;
+    List<InputFile> result = Lists.newArrayList();
+    for (String lang : langs) {
+      List<File> files = target.testFilesOfLang(lang);
+      for (File file : files) {
+        PathResolver.RelativePath relativePath = pathResolver.relativePath(getTestDirs(), file);
+        if (relativePath != null) {
+          result.add(InputFileUtils.create(relativePath.dir(), relativePath.path()));
+        }
+      }
+    }
+    return result;
   }
 }
index edc8dfa35182086cdf29dd64ac5e0e38a53d66ee..1935205bad0d2aad0e1b0c22437a582f4eef59d4 100644 (file)
@@ -23,10 +23,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.batch.ResourceFilter;
-import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.ResourceUtils;
 import org.sonar.api.scan.filesystem.FileFilter;
+import org.sonar.api.scan.filesystem.ModuleExclusions;
 import org.sonar.api.utils.WildcardPattern;
 
 import java.io.File;
@@ -37,18 +37,18 @@ public class ExclusionFileFilter implements FileFilter, ResourceFilter, BatchCom
   private final WildcardPattern[] sourceExclusions;
   private final WildcardPattern[] testExclusions;
 
-  public ExclusionFileFilter(Settings settings) {
-    sourceInclusions = ExclusionPatterns.sourceInclusions(settings);
+  public ExclusionFileFilter(ModuleExclusions exclusions) {
+    sourceInclusions = WildcardPattern.create(exclusions.sourceInclusions());
     log("Included sources: ", sourceInclusions);
 
-    testInclusions = ExclusionPatterns.testInclusions(settings);
-    log("Included tests: ", sourceInclusions);
-
-    sourceExclusions = ExclusionPatterns.sourceExclusions(settings);
+    sourceExclusions = WildcardPattern.create(exclusions.sourceExclusions());
     log("Excluded sources: ", sourceExclusions);
 
-    testExclusions = ExclusionPatterns.testExclusions(settings);
-    log("Excluded tests: ", sourceExclusions);
+    testInclusions = WildcardPattern.create(exclusions.testInclusions());
+    log("Included tests: ", testInclusions);
+
+    testExclusions = WildcardPattern.create(exclusions.testExclusions());
+    log("Excluded tests: ", testExclusions);
   }
 
   private void log(String title, WildcardPattern[] patterns) {
@@ -63,8 +63,12 @@ public class ExclusionFileFilter implements FileFilter, ResourceFilter, BatchCom
 
   public boolean accept(File file, Context context) {
     WildcardPattern[] inclusionPatterns = (context.fileType() == FileType.TEST ? testInclusions : sourceInclusions);
-    for (WildcardPattern pattern : inclusionPatterns) {
-      if (!pattern.match(context.fileRelativePath())) {
+    if (inclusionPatterns.length > 0) {
+      boolean matchInclusion = false;
+      for (WildcardPattern pattern : inclusionPatterns) {
+        matchInclusion |= pattern.match(context.fileRelativePath());
+      }
+      if (!matchInclusion) {
         return false;
       }
     }
@@ -78,9 +82,16 @@ public class ExclusionFileFilter implements FileFilter, ResourceFilter, BatchCom
   }
 
   public boolean isIgnored(Resource resource) {
+    if (!ResourceUtils.isFile(resource)) {
+      return false;
+    }
     WildcardPattern[] inclusionPatterns = (ResourceUtils.isUnitTestClass(resource) ? testInclusions : sourceInclusions);
-    for (WildcardPattern pattern : inclusionPatterns) {
-      if (!resource.matchFilePattern(pattern.toString())) {
+    if (inclusionPatterns.length > 0) {
+      boolean matchInclusion = false;
+      for (WildcardPattern pattern : inclusionPatterns) {
+        matchInclusion |= resource.matchFilePattern(pattern.toString());
+      }
+      if (!matchInclusion) {
         return true;
       }
     }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionPatterns.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionPatterns.java
deleted file mode 100644 (file)
index 3b4e3ba..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.scan.filesystem;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.ObjectArrays;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.utils.WildcardPattern;
-
-import java.util.List;
-
-/**
- * Get configuration of file inclusions and exclusions
- *
- * @since 3.5
- */
-class ExclusionPatterns {
-  static WildcardPattern[] sourceInclusions(Settings settings) {
-    return inclusions(settings, CoreProperties.PROJECT_INCLUSIONS_PROPERTY);
-  }
-
-  static WildcardPattern[] testInclusions(Settings settings) {
-    return inclusions(settings, CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY);
-  }
-
-  private static WildcardPattern[] inclusions(Settings settings, String propertyKey) {
-    String[] patterns = sanitize(settings.getStringArray(propertyKey));
-    List<WildcardPattern> list = Lists.newArrayList();
-    for (String pattern : patterns) {
-      if (!"**/*".equals(pattern)) {
-        list.add(WildcardPattern.create(pattern));
-      }
-    }
-    return list.toArray(new WildcardPattern[list.size()]);
-  }
-
-  static WildcardPattern[] sourceExclusions(Settings settings) {
-    return exclusions(settings, CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_EXCLUSIONS_PROPERTY);
-  }
-
-  static WildcardPattern[] testExclusions(Settings settings) {
-    return exclusions(settings, CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY);
-  }
-
-  private static WildcardPattern[] exclusions(Settings settings, String globalExclusionsProperty, String exclusionsProperty) {
-    String[] globalExclusions = settings.getStringArray(globalExclusionsProperty);
-    String[] exclusions = settings.getStringArray(exclusionsProperty);
-    String[] patterns = sanitize(ObjectArrays.concat(globalExclusions, exclusions, String.class));
-    return WildcardPattern.create(patterns);
-  }
-
-  private static String[] sanitize(String[] patterns) {
-    for (int i = 0; i < patterns.length; i++) {
-      patterns[i] = StringUtils.trim(patterns[i]);
-    }
-    return patterns;
-  }
-}
index f5cc8aacfa774abcd65d4855f980fc5e4ee71ce4..608330ba4e3ff4b92dbaaa8fcf41680abdd72352 100644 (file)
@@ -23,9 +23,10 @@ import org.apache.commons.io.IOCase;
 import org.apache.commons.io.filefilter.IOFileFilter;
 import org.apache.commons.io.filefilter.SuffixFileFilter;
 import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.sonar.api.BatchComponent;
 import org.sonar.api.resources.Languages;
 
-public class LanguageFileFilters {
+public class LanguageFileFilters implements BatchComponent {
   private final Languages languages;
 
   public LanguageFileFilters(Languages languages) {
index 119d38518432ec0eec48b91810a96cca9299473f..90b84addc0a7590310ce0b0105ea3b7dbe614700 100644 (file)
  */
 package org.sonar.batch.scan.filesystem;
 
+import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
-import org.jfree.util.Log;
 import org.picocontainer.injectors.ProviderAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.Settings;
-import org.sonar.api.scan.filesystem.FailToCreateFileException;
 import org.sonar.api.scan.filesystem.FileFilter;
-import org.sonar.api.scan.filesystem.ModuleFileSystem;
+import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.batch.bootstrap.TempDirectories;
 
 import java.io.File;
@@ -45,10 +45,10 @@ import java.util.Locale;
 public class ModuleFileSystemProvider extends ProviderAdapter {
   private static final Logger LOG = LoggerFactory.getLogger(ModuleFileSystemProvider.class);
 
-  private ModuleFileSystem singleton;
+  private DefaultModuleFileSystem singleton;
 
-  public ModuleFileSystem provide(ProjectDefinition module, PathResolver pathResolver, TempDirectories tempDirectories,
-                                  LanguageFileFilters languageFileFilters, Settings settings, FileFilter[] pluginFileFilters) {
+  public DefaultModuleFileSystem provide(ProjectDefinition module, PathResolver pathResolver, TempDirectories tempDirectories,
+                                         LanguageFileFilters languageFileFilters, Settings settings, FileFilter[] pluginFileFilters) {
     if (singleton == null) {
       DefaultModuleFileSystem.Builder builder = new DefaultModuleFileSystem.Builder();
 
@@ -59,6 +59,7 @@ public class ModuleFileSystemProvider extends ProviderAdapter {
       // files and directories
       // TODO should the basedir always exist ? If yes, then we check also check that it's a dir but not a file
       builder.baseDir(module.getBaseDir());
+      builder.buildDir(module.getBuildDir());
       builder.sourceCharset(guessCharset(settings));
       builder.workingDir(guessWorkingDir(module, tempDirectories));
       initBinaryDirs(module, pathResolver, builder);
@@ -82,7 +83,7 @@ public class ModuleFileSystemProvider extends ProviderAdapter {
       try {
         FileUtils.forceMkdir(workDir);
       } catch (Exception e) {
-        throw new FailToCreateFileException("Fail to create working dir: " + workDir.getAbsolutePath(), e);
+        throw new IllegalStateException("Fail to create working dir: " + workDir.getAbsolutePath(), e);
       }
     }
     return workDir;
@@ -102,14 +103,17 @@ public class ModuleFileSystemProvider extends ProviderAdapter {
   }
 
   private void initSources(ProjectDefinition module, PathResolver pathResolver, DefaultModuleFileSystem.Builder builder) {
-    if (!module.getSourceDirs().isEmpty()) {
-      LOG.info("Source dirs: ");
-      for (String sourcePath : module.getSourceDirs()) {
-        File dir = pathResolver.relativeFile(module.getBaseDir(), sourcePath);
-        LOG.info("  " + dir.getAbsolutePath());
+    List<String> paths = Lists.newArrayList();
+    for (String sourcePath : module.getSourceDirs()) {
+      File dir = pathResolver.relativeFile(module.getBaseDir(), sourcePath);
+      if (dir.isDirectory() && dir.exists()) {
+        paths.add(dir.getAbsolutePath());
         builder.addSourceDir(dir);
       }
     }
+    if (!paths.isEmpty()) {
+      LOG.info("Source dirs: " + Joiner.on(", ").join(paths));
+    }
     List<File> sourceFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getSourceFiles());
     if (!sourceFiles.isEmpty()) {
       LOG.info("Source files: ");
@@ -121,17 +125,21 @@ public class ModuleFileSystemProvider extends ProviderAdapter {
   }
 
   private void initTests(ProjectDefinition module, PathResolver pathResolver, DefaultModuleFileSystem.Builder builder) {
-    if (!module.getTestDirs().isEmpty()) {
-      Log.info("Test dirs:");
-      for (String testPath : module.getTestDirs()) {
-        File dir = pathResolver.relativeFile(module.getBaseDir(), testPath);
-        LOG.info("  " + dir.getAbsolutePath());
+    List<String> paths = Lists.newArrayList();
+    for (String testPath : module.getTestDirs()) {
+      File dir = pathResolver.relativeFile(module.getBaseDir(), testPath);
+      if (dir.exists() && dir.isDirectory()) {
+        paths.add(dir.getAbsolutePath());
         builder.addTestDir(dir);
       }
     }
+    if (!paths.isEmpty()) {
+      LOG.info("Test dirs: " + Joiner.on(", ").join(paths));
+    }
+
     List<File> testFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getTestFiles());
     if (!testFiles.isEmpty()) {
-      Log.info("Test files:");
+      LOG.info("Test files:");
       for (File testFile : testFiles) {
         LOG.info("  " + testFile.getAbsolutePath());
       }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java
deleted file mode 100644 (file)
index 357e584..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.scan.filesystem;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import org.apache.commons.io.FilenameUtils;
-import org.sonar.api.scan.filesystem.IllegalPathException;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * @since 3.5
- */
-public class PathResolver {
-
-  File relativeFile(File dir, String path) {
-    Preconditions.checkArgument(dir.isDirectory(), "Not a directory: " + dir.getAbsolutePath());
-    File file = new File(path);
-    if (!file.isAbsolute()) {
-      try {
-        file = new File(dir, path).getCanonicalFile();
-      } catch (Exception e) {
-        throw new IllegalPathException("Fail to resolve path '" + path + "' relative to: " + dir.getAbsolutePath());
-      }
-    }
-    return file;
-  }
-
-  List<File> relativeFiles(File dir, List<String> paths) {
-    List<File> result = Lists.newArrayList();
-    for (String path : paths) {
-      result.add(relativeFile(dir, path));
-    }
-    return result;
-  }
-
-  String relativePath(File dir, File file) {
-    List<String> stack = Lists.newArrayList();
-    String path = FilenameUtils.normalize(file.getAbsolutePath());
-    File cursor = new File(path);
-    while (cursor != null) {
-      if (containsFile(dir, cursor)) {
-        return Joiner.on("/").join(stack);
-      }
-      stack.add(0, cursor.getName());
-      cursor = cursor.getParentFile();
-    }
-    return null;
-  }
-
-  private boolean containsFile(File dir, File cursor) {
-    return FilenameUtils.equalsNormalizedOnSystem(dir.getAbsolutePath(), cursor.getAbsolutePath());
-  }
-}
index a208fcb5978c519df728a64f51f1968ac9212286..982a31d7167f54c72dcfebb7486e45cf0d453370 100644 (file)
@@ -21,16 +21,19 @@ package org.sonar.batch;
 
 import org.apache.maven.project.MavenProject;
 import org.junit.Test;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.maven.MavenPlugin;
 import org.sonar.api.batch.maven.MavenPluginHandler;
 import org.sonar.api.resources.Project;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import java.io.File;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
-import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyList;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
 public class AbstractMavenPluginExecutorTest {
 
@@ -56,10 +59,10 @@ public class AbstractMavenPluginExecutorTest {
     pom.getBuild().setDirectory("target");
     Project foo = new Project("foo");
     foo.setPom(pom);
-    ProjectDefinition definition = ProjectDefinition.create();
-    executor.execute(foo, definition, new AddSourceMavenPluginHandler());
+    DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
+    executor.execute(foo, fs, new AddSourceMavenPluginHandler());
 
-    assertThat(definition.getSourceDirs(), hasItem("src/java"));
+    verify(fs).resetDirs(any(File.class), any(File.class), any(File.class), anyList(), anyList(), anyList());
   }
 
   static class AddSourceMavenPluginHandler implements MavenPluginHandler {
@@ -80,7 +83,7 @@ public class AbstractMavenPluginExecutorTest {
     }
 
     public String[] getGoals() {
-      return new String[] { "fake" };
+      return new String[]{"fake"};
     }
 
     public void configure(Project project, MavenPlugin plugin) {
diff --git a/sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java b/sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java
deleted file mode 100644 (file)
index 65773ca..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch;
-
-import org.hamcrest.core.Is;
-import org.junit.Test;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.test.TestUtils;
-
-import java.io.File;
-
-import static org.junit.Assert.assertThat;
-import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
-
-public class DefaultProjectFileSystem2Test {
-  @Test
-  public void shouldIgnoreInexistingSourceDirs() {
-    File exists = TestUtils.getResource("/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs");
-    File notExists = new File("target/unknown");
-
-    ProjectDefinition definition = ProjectDefinition.create().addSourceDirs(exists, notExists);
-
-    DefaultProjectFileSystem2 fs = new DefaultProjectFileSystem2(new Project("foo"), new Languages(), definition);
-    assertThat(fs.getSourceDirs().size(), Is.is(1));
-    assertThat(fs.getSourceDirs(), hasItem(exists));
-  }
-}
index 325fbdd4a53b850337ff081fd495b94d8c2297f6..b4274ecd00d65d0f339637540719c52a9d69a7dc 100644 (file)
@@ -25,7 +25,9 @@ import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 import org.hamcrest.core.Is;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.test.TestUtils;
@@ -46,9 +48,13 @@ import static org.junit.Assert.fail;
 
 public class MavenProjectConverterTest {
 
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
   /**
    * See SONAR-2681
    */
+  @Test
   public void shouldThrowExceptionWhenUnableToDetermineProjectStructure() {
     MavenProject root = new MavenProject();
     root.setFile(new File("/foo/pom.xml"));
@@ -64,14 +70,18 @@ public class MavenProjectConverterTest {
   }
 
   @Test
-  public void shouldConvertModules() {
+  public void shouldConvertModules() throws IOException {
+    File basedir = temp.newFolder();
+
     MavenProject root = new MavenProject();
-    root.setFile(new File("/foo/pom.xml"));
+    root.setFile(new File(basedir, "pom.xml"));
     root.getBuild().setDirectory("target");
+    root.getBuild().setOutputDirectory("target/classes");
     root.getModules().add("module/pom.xml");
     MavenProject module = new MavenProject();
-    module.setFile(new File("/foo/module/pom.xml"));
+    module.setFile(new File(basedir, "module/pom.xml"));
     module.getBuild().setDirectory("target");
+    module.getBuild().setOutputDirectory("target/classes");
     ProjectDefinition project = MavenProjectConverter.convert(Arrays.asList(root, module), root);
 
     assertThat(project.getSubProjects().size(), is(1));
index 069840eaf868765a8c4e9dbde7f793a9976b0c40..db80de5c1bf3bb4e33eae3d838ab4dcc75a93a9f 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.api.batch.maven.MavenPluginHandler;
 import org.sonar.api.resources.Project;
 import org.sonar.batch.FakeMavenPluginExecutor;
 import org.sonar.batch.MavenPluginExecutor;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import static org.fest.assertions.Assertions.assertThat;
 
@@ -75,10 +76,10 @@ public class BootstrapContainerTest {
   }
 
   public static class MyMavenPluginExecutor implements MavenPluginExecutor {
-    public void execute(Project project, ProjectDefinition projectDef, String goal) {
+    public void execute(Project project, DefaultModuleFileSystem fs, String goal) {
     }
 
-    public MavenPluginHandler execute(Project project, ProjectDefinition projectDef, MavenPluginHandler handler) {
+    public MavenPluginHandler execute(Project project, DefaultModuleFileSystem  fs, MavenPluginHandler handler) {
       return handler;
     }
   }
index a2a6ce5dc71738a4c7a33175b9fbf8c3cd11befc..b892aa9af66987c7826d974099ef653fd3b363f3 100644 (file)
@@ -27,11 +27,11 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.Server;
-import org.sonar.api.resources.ProjectFileSystem;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.api.rules.Violation;
+import org.sonar.api.scan.filesystem.ModuleFileSystem;
 import org.sonar.batch.index.DefaultIndex;
 import org.sonar.core.i18n.RuleI18nManager;
 import org.sonar.java.api.JavaClass;
@@ -55,7 +55,7 @@ public class DryRunExporterTest {
   SensorContext sensorContext = mock(SensorContext.class);
   Resource resource = JavaClass.create("KEY");
   Violation violation = mock(Violation.class);
-  ProjectFileSystem projectFileSystem = mock(ProjectFileSystem.class);
+  ModuleFileSystem fileSystem = mock(ModuleFileSystem.class);
   Server server = mock(Server.class);
   RuleI18nManager ruleI18nManager = mock(RuleI18nManager.class);
   Settings settings;
@@ -67,7 +67,7 @@ public class DryRunExporterTest {
   public void setUp() {
     settings = new Settings();
     settings.setProperty(CoreProperties.DRY_RUN, true);
-    dryRunExporter = spy(new DryRunExporter(settings, sonarIndex, projectFileSystem, server, ruleI18nManager));
+    dryRunExporter = spy(new DryRunExporter(settings, sonarIndex, fileSystem, server, ruleI18nManager));
   }
 
   @Test
@@ -139,7 +139,7 @@ public class DryRunExporterTest {
     when(server.getVersion()).thenReturn("3.4");
     doReturn(Arrays.<Violation>asList()).when(dryRunExporter).getViolations(resource);
     settings.setProperty("sonar.dryRun.export.path", "output.json");
-    when(projectFileSystem.getSonarWorkingDirectory()).thenReturn(sonarDirectory);
+    when(fileSystem.workingDir()).thenReturn(sonarDirectory);
 
     dryRunExporter.execute(sensorContext);
 
index ea40f8a6ce51ed86ac334d3d75cd2070a9dddeb2..8d185ff0a46a2c3de1bea4dfd44fbb94e4e20471 100644 (file)
@@ -30,27 +30,28 @@ import org.junit.Test;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.resources.Project;
 import org.sonar.batch.MavenPluginExecutor;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 public class MavenPhaseExecutorTest {
 
   @Test
   public void doNothingIfNoPhase() {
-    ProjectDefinition projectDef = ProjectDefinition.create();
+    DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
     MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class);
-    MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(projectDef, mavenPluginExecutor);
+    MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(fs, mavenPluginExecutor);
 
 
     Project project = new Project("key");
     phaseExecutor.execute(project);
 
-    verify(mavenPluginExecutor, never()).execute(eq(project), eq(projectDef), anyString());
+    verify(mavenPluginExecutor, never()).execute(eq(project), eq(fs), anyString());
   }
 
   @Test
   public void executePhase() {
-    ProjectDefinition projectDef = ProjectDefinition.create();
+    DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
     MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class);
-    MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(projectDef, mavenPluginExecutor);
+    MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(fs, mavenPluginExecutor);
 
     Project project = new Project("key");
     PropertiesConfiguration conf = new PropertiesConfiguration();
@@ -59,6 +60,6 @@ public class MavenPhaseExecutorTest {
 
     phaseExecutor.execute(project);
 
-    verify(mavenPluginExecutor).execute(project, projectDef, "myphase");
+    verify(mavenPluginExecutor).execute(project, fs, "myphase");
   }
 }
index 1af0a26cc9eeabced77aa9b0481a857bae2decb2..dc7eb79101f196254f8e64e98268acf0c855865d 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.resources.Project;
 import org.sonar.batch.MavenPluginExecutor;
 import org.sonar.batch.local.DryRunExporter;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import java.util.Arrays;
 
@@ -48,7 +49,7 @@ public class PostJobsExecutorTest {
 
   @Before
   public void setUp() {
-    executor = new PostJobsExecutor(selector, project, ProjectDefinition.create(), mavenPluginExecutor, localModeExporter);
+    executor = new PostJobsExecutor(selector, project, mock(DefaultModuleFileSystem.class), mavenPluginExecutor, localModeExporter);
   }
 
   @Test
index 8d45a5703e634d9318459fb609063c5bf7a1fe9a..8646364216a1b095b62c40904472a6011dfac96d 100644 (file)
@@ -28,9 +28,11 @@ import org.sonar.api.resources.AbstractLanguage;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.scan.filesystem.FileFilter;
 import org.sonar.api.scan.filesystem.JavaIoFileFilter;
+import org.sonar.api.scan.filesystem.PathResolver;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.List;
 
 import static org.fest.assertions.Assertions.assertThat;
@@ -184,4 +186,33 @@ public class DefaultModuleFileSystemTest {
       return new String[]{"java", "jav"};
     }
   }
+
+  @Test
+  public void test_reset_dirs() throws IOException {
+    File basedir = temp.newFolder();
+    DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder()
+      .baseDir(basedir)
+      .sourceCharset(Charsets.UTF_8)
+      .workingDir(basedir)
+      .addSourceDir(new File(basedir, "src/main/java"))
+      .addFileFilter(JavaIoFileFilter.create(FileFilterUtils.nameFileFilter("Foo.java")))
+      .pathResolver(new PathResolver())
+      .build();
+
+    File existingDir = temp.newFolder("new_folder");
+    File notExistingDir = new File(existingDir, "not_exist");
+
+    fileSystem.resetDirs(existingDir, existingDir, existingDir,
+      Arrays.asList(existingDir, notExistingDir), Arrays.asList(existingDir, notExistingDir), Arrays.asList(existingDir, notExistingDir));
+
+    assertThat(fileSystem.baseDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath());
+    assertThat(fileSystem.workingDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath());
+    assertThat(fileSystem.buildDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath());
+    assertThat(fileSystem.sourceDirs()).hasSize(1);
+    assertThat(fileSystem.sourceDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath());
+    assertThat(fileSystem.testDirs()).hasSize(1);
+    assertThat(fileSystem.testDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath());
+    assertThat(fileSystem.binaryDirs()).hasSize(1);
+    assertThat(fileSystem.binaryDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath());
+  }
 }
index 13fc2529b11a12f9378dd20d269b5595611d18dc..0bdf7ea726b9789b677b2f4b7cec4813578cdd28 100644 (file)
@@ -27,6 +27,7 @@ import org.sonar.api.config.Settings;
 import org.sonar.api.resources.File;
 import org.sonar.api.resources.JavaFile;
 import org.sonar.api.scan.filesystem.FileFilter;
+import org.sonar.api.scan.filesystem.ModuleExclusions;
 import org.sonar.api.scan.filesystem.ModuleFileSystem;
 
 import java.io.IOException;
@@ -42,7 +43,7 @@ public class ExclusionFileFilterTest {
   public void source_inclusions() throws IOException {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.java");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE);
     context.setFileRelativePath("com/mycompany/Foo.java");
@@ -61,7 +62,7 @@ public class ExclusionFileFilterTest {
   public void source_exclusions() throws IOException {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Dao.java");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE);
     context.setFileRelativePath("com/mycompany/FooDao.java");
@@ -80,7 +81,7 @@ public class ExclusionFileFilterTest {
   public void resource_inclusions() throws IOException {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.c");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     assertThat(filter.isIgnored(new File("org/sonar", "FooDao.c"))).isFalse();
     assertThat(filter.isIgnored(new File("org/sonar", "Foo.c"))).isTrue();
@@ -90,7 +91,7 @@ public class ExclusionFileFilterTest {
   public void resource_exclusions() throws IOException {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Dao.c");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     assertThat(filter.isIgnored(new File("org/sonar", "FooDao.c"))).isTrue();
     assertThat(filter.isIgnored(new File("org/sonar", "Foo.c"))).isFalse();
@@ -103,7 +104,7 @@ public class ExclusionFileFilterTest {
   public void java_resource_inclusions() throws IOException {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.java");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     assertThat(filter.isIgnored(new JavaFile("org.sonar", "FooDao"))).isFalse();
     assertThat(filter.isIgnored(new JavaFile("org.sonar", "Foo"))).isTrue();
@@ -116,7 +117,7 @@ public class ExclusionFileFilterTest {
   public void java_resource_exclusions() throws IOException {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Dao.java");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     assertThat(filter.isIgnored(new JavaFile("org.sonar", "FooDao"))).isTrue();
     assertThat(filter.isIgnored(new JavaFile("org.sonar", "Foo"))).isFalse();
@@ -129,7 +130,7 @@ public class ExclusionFileFilterTest {
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "source/exclusions");
     settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "test/inclusions");
     settings.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, "test/exclusions");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     assertThat(filter.sourceInclusions()[0].toString()).isEqualTo("source/inclusions");
     assertThat(filter.testInclusions()[0].toString()).isEqualTo("test/inclusions");
@@ -141,7 +142,7 @@ public class ExclusionFileFilterTest {
   public void should_trim_pattern() throws IOException {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "   **/*Dao.java   ");
-    ExclusionFileFilter filter = new ExclusionFileFilter(settings);
+    ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings));
 
     assertThat(filter.sourceExclusions()[0].toString()).isEqualTo("**/*Dao.java");
   }
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionPatternsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionPatternsTest.java
deleted file mode 100644 (file)
index 230b56c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.utils.WildcardPattern;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class ExclusionPatternsTest {
-  @Test
-  public void ignore_inclusion_of_world() {
-    Settings settings = new Settings();
-    settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*");
-    assertThat(ExclusionPatterns.sourceInclusions(settings)).isEmpty();
-  }
-
-  @Test
-  public void load_inclusion() {
-    Settings settings = new Settings();
-    settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Foo.java");
-    WildcardPattern[] inclusions = ExclusionPatterns.sourceInclusions(settings);
-
-    assertThat(inclusions).hasSize(1);
-    assertThat(inclusions[0].toString()).isEqualTo("**/*Foo.java");
-  }
-}
index 5fa1bc1a492d70e81ca7f2aa241129c1061acd94..6a406912055599bce261cf827a9d3b516acc2b91 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.batch.scan.filesystem;
 
 import com.google.common.base.Charsets;
+import org.apache.commons.io.FileUtils;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -28,6 +29,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.Settings;
 import org.sonar.api.scan.filesystem.FileFilter;
 import org.sonar.api.scan.filesystem.ModuleFileSystem;
+import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.batch.bootstrap.TempDirectories;
 
 import java.io.File;
@@ -84,6 +86,39 @@ public class ModuleFileSystemProviderTest {
     assertThat(fs.sourceCharset()).isEqualTo(Charsets.ISO_8859_1);
   }
 
+  @Test
+  public void test_directories() throws IOException {
+    ModuleFileSystemProvider provider = new ModuleFileSystemProvider();
+
+    File baseDir = temp.newFolder("base");
+    File buildDir = temp.newFolder("build");
+    File sourceDir = new File(baseDir, "src/main/java");
+    FileUtils.forceMkdir(sourceDir);
+    File testDir = new File(baseDir, "src/test/java");
+    FileUtils.forceMkdir(testDir);
+    File binaryDir = new File(baseDir, "target/classes");
+    FileUtils.forceMkdir(binaryDir);
+
+    ProjectDefinition project = ProjectDefinition.create()
+      .setBaseDir(baseDir)
+      .setBuildDir(buildDir)
+      .addSourceDirs("src/main/java", "src/main/unknown")
+      .addTestDirs("src/test/java", "src/test/unknown")
+      .addBinaryDir("target/classes");
+
+    ModuleFileSystem fs = provider.provide(project, new PathResolver(), new TempDirectories(), mock(LanguageFileFilters.class),
+      new Settings(), new FileFilter[0]);
+
+    assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(baseDir.getCanonicalPath());
+    assertThat(fs.buildDir().getCanonicalPath()).isEqualTo(buildDir.getCanonicalPath());
+    assertThat(fs.sourceDirs()).hasSize(1);
+    assertThat(fs.sourceDirs().get(0).getCanonicalPath()).endsWith("src/main/java");
+    assertThat(fs.testDirs()).hasSize(1);
+    assertThat(fs.testDirs().get(0).getCanonicalPath()).endsWith("src/test/java");
+    assertThat(fs.binaryDirs()).hasSize(1);
+    assertThat(fs.binaryDirs().get(0).getCanonicalPath()).endsWith("target/classes");
+  }
+
   private ProjectDefinition newSimpleModule() {
     return ProjectDefinition.create()
       .setBaseDir(temp.newFolder("base"));
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java
deleted file mode 100644 (file)
index 8515aa7..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.apache.commons.io.FilenameUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class PathResolverTest {
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @Test
-  public void get_file_by_relative_path() throws IOException {
-    PathResolver resolver = new PathResolver();
-    File rootDir = temp.newFolder();
-    File file = resolver.relativeFile(rootDir, "org/foo/Bar.java");
-    assertThat(file.getName()).isEqualTo("Bar.java");
-    assertThat(FilenameUtils.separatorsToUnix(file.getCanonicalPath())).endsWith("org/foo/Bar.java");
-    assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath());
-  }
-
-  @Test
-  public void get_file_by_absolute_path() throws IOException {
-    PathResolver resolver = new PathResolver();
-    File rootDir = temp.newFolder();
-    File file = resolver.relativeFile(rootDir, new File(rootDir, "org/foo/Bar.java").getAbsolutePath());
-    assertThat(file.getName()).isEqualTo("Bar.java");
-    assertThat(FilenameUtils.separatorsToUnix(file.getCanonicalPath())).endsWith("org/foo/Bar.java");
-    assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath());
-  }
-
-  @Test
-  public void get_files_by_relative_paths() throws IOException {
-    PathResolver resolver = new PathResolver();
-    File rootDir = temp.newFolder();
-    List<File> files = resolver.relativeFiles(rootDir, Arrays.asList("org/foo/Bar.java", "org/hello/World.java"));
-    assertThat(files).hasSize(2);
-    for (File file : files) {
-      assertThat(file.getName()).endsWith(".java");
-      assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath());
-    }
-  }
-
-  @Test
-  public void get_relative_path() throws IOException {
-    PathResolver resolver = new PathResolver();
-    File rootDir = temp.newFolder();
-    File org = new File(rootDir, "org");
-    File hello = new File(org, "hello");
-    File world = new File(hello, "World.java");
-
-    assertThat(resolver.relativePath(rootDir, world)).isEqualTo("org/hello/World.java");
-  }
-
-  @Test
-  public void null_relative_path_when_file_is_not_in_dir() throws IOException {
-    PathResolver resolver = new PathResolver();
-    File rootDir = temp.newFolder();
-
-    assertThat(resolver.relativePath(rootDir, new File("Elsewhere.java"))).isNull();
-  }
-}
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt b/sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt
deleted file mode 100644 (file)
index f0f877c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-fake
\ No newline at end of file
index 88f78593a7f38263adc2e7c767fc0842365d7851..2109104273eda40f75cc272c5b274ebb4a261d59 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.core.persistence;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -29,6 +30,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+@Ignore
 public class SemaphoreUpdaterTest extends AbstractDaoTestCase {
 
   private SemaphoreUpdater updater;
index 9f3a7f94e3e9212eac4712152544ddbb8e48e5a5..3975c067c9cab9a6ec397bc5534910941676f602 100644 (file)
@@ -42,11 +42,11 @@ public class ProjectDefinition {
   public static final String TEST_FILES_PROPERTY = "sonar.testFiles";
   public static final String BINARIES_PROPERTY = "sonar.binaries";
   public static final String LIBRARIES_PROPERTY = "sonar.libraries";
+  public static final String BUILD_DIR_PROPERTY = "sonar.buildDir";
 
   private static final char SEPARATOR = ',';
 
-  private File baseDir;
-  private File workDir;
+  private File baseDir, workDir, buildDir;
   private Properties properties = new Properties();
   private ProjectDefinition parent = null;
   private List<ProjectDefinition> subProjects = Lists.newArrayList();
@@ -89,6 +89,15 @@ public class ProjectDefinition {
     return workDir;
   }
 
+  public ProjectDefinition setBuildDir(File d) {
+    this.buildDir = d;
+    return this;
+  }
+
+  public File getBuildDir() {
+    return buildDir;
+  }
+
   public Properties getProperties() {
     return properties;
   }
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java
deleted file mode 100644 (file)
index d555361..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.api.resources;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.filefilter.*;
-import org.apache.commons.lang.CharEncoding;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.FileFilter;
-import org.sonar.api.utils.Logs;
-import org.sonar.api.utils.SonarException;
-import org.sonar.api.utils.WildcardPattern;
-
-import javax.annotation.Nullable;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.*;
-
-/**
- * An implementation of {@link ProjectFileSystem}.
- * For internal use only.
- *
- * @since 1.10
- * @deprecated in 2.8. In fact this class should not be located in sonar-plugin-api and most of the methods were overridden by a component in sonar-batch.
- */
-@Deprecated
-public class DefaultProjectFileSystem implements ProjectFileSystem {
-
-  protected static final Predicate<File> DIRECTORY_EXISTS = new Predicate<File>() {
-    public boolean apply(@Nullable File input) {
-      return input != null && input.exists() && input.isDirectory();
-    }
-  };
-
-  private Project project;
-  private Languages languages;
-  private List<IOFileFilter> filters = Lists.newArrayList();
-
-  public DefaultProjectFileSystem(Project project, Languages languages) {
-    this.project = project;
-    this.languages = languages;
-    // TODO See http://jira.codehaus.org/browse/SONAR-2126
-    // previously MavenProjectBuilder was responsible for creation of ProjectFileSystem
-    project.setFileSystem(this);
-  }
-
-  public DefaultProjectFileSystem(Project project, Languages languages, FileFilter... fileFilters) {
-    this(project, languages);
-    for (FileFilter fileFilter : fileFilters) {
-      filters.add(new DelegateFileFilter(fileFilter));
-    }
-  }
-
-  public Charset getSourceCharset() {
-    String encoding = project.getConfiguration().getString(CoreProperties.ENCODING_PROPERTY);
-    if (StringUtils.isNotEmpty(encoding)) {
-      try {
-        return Charset.forName(encoding);
-      } catch (Exception e) {
-        Logs.INFO.warn("Can not get project charset", e);
-      }
-    }
-    return Charset.defaultCharset();
-  }
-
-  public File getBasedir() {
-    return project.getPom().getBasedir();
-  }
-
-  public File getBuildDir() {
-    return resolvePath(project.getPom().getBuild().getDirectory());
-  }
-
-  public File getBuildOutputDir() {
-    return resolvePath(project.getPom().getBuild().getOutputDirectory());
-  }
-
-  /**
-   * Maven can modify source directories during Sonar execution - see MavenPhaseExecutor.
-   */
-  public List<File> getSourceDirs() {
-    return ImmutableList.copyOf(Iterables.filter(resolvePaths(project.getPom().getCompileSourceRoots()), DIRECTORY_EXISTS));
-  }
-
-  /**
-   * @deprecated since 2.6, because should be immutable
-   */
-  @Deprecated
-  public DefaultProjectFileSystem addSourceDir(File dir) {
-    if (dir == null) {
-      throw new IllegalArgumentException("Can not add null to project source dirs");
-    }
-    project.getPom().getCompileSourceRoots().add(0, dir.getAbsolutePath());
-    return this;
-  }
-
-  /**
-   * Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
-   */
-  public List<File> getTestDirs() {
-    return ImmutableList.copyOf(Iterables.filter(resolvePaths(project.getPom().getTestCompileSourceRoots()), DIRECTORY_EXISTS));
-  }
-
-  /**
-   * @deprecated since 2.6, because should be immutable
-   */
-  @Deprecated
-  public DefaultProjectFileSystem addTestDir(File dir) {
-    if (dir == null) {
-      throw new IllegalArgumentException("Can not add null to project test dirs");
-    }
-    project.getPom().getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
-    return this;
-  }
-
-  public File getReportOutputDir() {
-    return resolvePath(project.getPom().getReporting().getOutputDirectory());
-  }
-
-  public File getSonarWorkingDirectory() {
-    try {
-      File dir = new File(getBuildDir(), "sonar");
-      FileUtils.forceMkdir(dir);
-      return dir;
-
-    } catch (IOException e) {
-      throw new SonarException("Unable to retrieve Sonar working directory.", e);
-    }
-  }
-
-  public File resolvePath(String path) {
-    File file = new File(path);
-    if (!file.isAbsolute()) {
-      try {
-        file = new File(getBasedir(), path).getCanonicalFile();
-      } catch (IOException e) {
-        throw new SonarException("Unable to resolve path '" + path + "'", e);
-      }
-    }
-    return file;
-  }
-
-  protected List<File> resolvePaths(List<String> paths) {
-    List<File> result = Lists.newArrayList();
-    if (paths != null) {
-      for (String path : paths) {
-        result.add(resolvePath(path));
-      }
-    }
-    return result;
-  }
-
-  /**
-   * @deprecated in 2.6, use {@link #mainFiles(String...)} instead
-   */
-  @Deprecated
-  public List<File> getSourceFiles(Language... langs) {
-    return toFiles(mainFiles(getLanguageKeys(langs)));
-  }
-
-  /**
-   * @deprecated in 2.6, use {@link #mainFiles(String...)} instead
-   */
-  @Deprecated
-  public List<File> getJavaSourceFiles() {
-    return getSourceFiles(Java.INSTANCE);
-  }
-
-  public boolean hasJavaSourceFiles() {
-    return !mainFiles(Java.KEY).isEmpty();
-  }
-
-  /**
-   * @deprecated in 2.6, use {@link #testFiles(String...)} instead
-   */
-  @Deprecated
-  public List<File> getTestFiles(Language... langs) {
-    return toFiles(testFiles(getLanguageKeys(langs)));
-  }
-
-  /**
-   * @deprecated in 2.6
-   */
-  @Deprecated
-  public boolean hasTestFiles(Language lang) {
-    return !testFiles(lang.getKey()).isEmpty();
-  }
-
-  List<InputFile> getFiles(List<File> directories, List<File> initialFiles, String[] patterns, String... langs) {
-    List<InputFile> result = Lists.newArrayList();
-    if (directories == null) {
-      return result;
-    }
-
-    IOFileFilter suffixFilter = getFileSuffixFilter(langs);
-    WildcardPattern[] exclusionPatterns = WildcardPattern.create(patterns);
-
-    IOFileFilter initialFilesFilter = TrueFileFilter.TRUE;
-    if (initialFiles != null && !initialFiles.isEmpty()) {
-      initialFilesFilter = new FileSelectionFilter(initialFiles);
-    }
-
-    for (File dir : directories) {
-      if (dir.exists()) {
-        IOFileFilter exclusionFilter = new ExclusionFilter(dir, exclusionPatterns);
-        IOFileFilter visibleFileFilter = HiddenFileFilter.VISIBLE;
-        List<IOFileFilter> fileFilters = Lists.newArrayList(visibleFileFilter, suffixFilter, exclusionFilter, initialFilesFilter);
-        fileFilters.addAll(this.filters);
-
-        IOFileFilter dotPrefixDirFilter = FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter("."));
-        List<File> files = (List<File>) FileUtils.listFiles(dir, new AndFileFilter(fileFilters), FileFilterUtils.and(HiddenFileFilter.VISIBLE, dotPrefixDirFilter));
-        for (File file : files) {
-          String relativePath = DefaultProjectFileSystem.getRelativePath(file, dir);
-          result.add(InputFileUtils.create(dir, relativePath));
-        }
-      }
-    }
-    return result;
-  }
-
-  private IOFileFilter getFileSuffixFilter(String... langKeys) {
-    IOFileFilter suffixFilter = FileFilterUtils.trueFileFilter();
-    if (langKeys != null && langKeys.length > 0) {
-      List<String> suffixes = Arrays.asList(languages.getSuffixes(langKeys));
-      if (!suffixes.isEmpty()) {
-        suffixFilter = new SuffixFileFilter(suffixes);
-      }
-    }
-    return suffixFilter;
-  }
-
-  private static class ExclusionFilter implements IOFileFilter {
-    File sourceDir;
-    WildcardPattern[] patterns;
-
-    ExclusionFilter(File sourceDir, WildcardPattern[] patterns) {
-      this.sourceDir = sourceDir;
-      this.patterns = patterns;
-    }
-
-    public boolean accept(File file) {
-      String relativePath = getRelativePath(file, sourceDir);
-      if (relativePath == null) {
-        return false;
-      }
-      for (WildcardPattern pattern : patterns) {
-        if (pattern.match(relativePath)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    public boolean accept(File file, String name) {
-      return accept(file);
-    }
-  }
-
-  static class FileSelectionFilter implements IOFileFilter {
-    private Set<File> files;
-
-    public FileSelectionFilter(List<File> f) {
-      files = Sets.newHashSet(f);
-    }
-
-    public boolean accept(File file) {
-      return files.contains(file);
-    }
-
-    public boolean accept(File file, String name) {
-      return accept(file);
-    }
-  }
-
-  public File writeToWorkingDirectory(String content, String fileName) throws IOException {
-    return writeToFile(content, getSonarWorkingDirectory(), fileName);
-  }
-
-  protected static File writeToFile(String content, File dir, String fileName) throws IOException {
-    File file = new File(dir, fileName);
-    FileUtils.writeStringToFile(file, content, CharEncoding.UTF_8);
-    return file;
-  }
-
-  /**
-   * getRelativePath("c:/foo/src/my/package/Hello.java", "c:/foo/src") is "my/package/Hello.java"
-   *
-   * @return null if file is not in dir (including recursive subdirectories)
-   */
-  public static String getRelativePath(File file, File dir) {
-    return getRelativePath(file, Arrays.asList(dir));
-  }
-
-  /**
-   * getRelativePath("c:/foo/src/my/package/Hello.java", ["c:/bar", "c:/foo/src"]) is "my/package/Hello.java".
-   * <p>
-   * Relative path is composed of slashes. Windows backslaches are replaced by /
-   * </p>
-   *
-   * @return null if file is not in dir (including recursive subdirectories)
-   */
-  public static String getRelativePath(File file, List<File> dirs) {
-    List<String> stack = new ArrayList<String>();
-    String path = FilenameUtils.normalize(file.getAbsolutePath());
-    File cursor = new File(path);
-    while (cursor != null) {
-      if (containsFile(dirs, cursor)) {
-        return StringUtils.join(stack, "/");
-      }
-      stack.add(0, cursor.getName());
-      cursor = cursor.getParentFile();
-    }
-    return null;
-  }
-
-  public File getFileFromBuildDirectory(String filename) {
-    File file = new File(getBuildDir(), filename);
-    return (file.exists() ? file : null);
-  }
-
-  public Resource toResource(File file) {
-    if (file == null || !file.exists()) {
-      return null;
-    }
-
-    String relativePath = getRelativePath(file, getSourceDirs());
-    if (relativePath == null) {
-      return null;
-    }
-
-    return (file.isFile() ? new org.sonar.api.resources.File(relativePath) : new org.sonar.api.resources.Directory(relativePath));
-  }
-
-  private static boolean containsFile(List<File> dirs, File cursor) {
-    for (File dir : dirs) {
-      if (FilenameUtils.equalsNormalizedOnSystem(dir.getAbsolutePath(), cursor.getAbsolutePath())) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Conversion from Language to key. Allows to provide backward compatibility.
-   */
-  private String[] getLanguageKeys(Language[] langs) {
-    String[] keys = new String[langs.length];
-    for (int i = 0; i < langs.length; i++) {
-      keys[i] = langs[i].getKey();
-    }
-    return keys;
-  }
-
-  /**
-   * Conversion from InputFile to File. Allows to provide backward compatibility.
-   */
-  private static List<File> toFiles(List<InputFile> files) {
-    List<File> result = Lists.newArrayList();
-    for (InputFile file : files) {
-      result.add(file.getFile());
-    }
-    return result;
-  }
-
-  /**
-   * @since 2.6
-   */
-  public List<InputFile> mainFiles(String... langs) {
-    return getFiles(getSourceDirs(), getInitialSourceFiles(), project.getExclusionPatterns(), langs);
-  }
-
-  /**
-   * @since 2.6
-   */
-  public List<InputFile> testFiles(String... langs) {
-    return getFiles(getTestDirs(), getInitialTestFiles(), project.getTestExclusionPatterns(), langs);
-  }
-
-  protected List<File> getInitialSourceFiles() {
-    return Collections.emptyList();
-  }
-
-  protected List<File> getInitialTestFiles() {
-    return Collections.emptyList();
-  }
-}
index eaa8090bfd7a82c1dc24d2a13c42e29a1e952148..542ad02b679d7509a829f3fb0cc8b0b05fbb4349 100644 (file)
@@ -21,13 +21,14 @@ package org.sonar.api.resources;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.ToStringBuilder;
+import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.utils.WildcardPattern;
 
 import java.util.List;
 
 /**
  * This class is an implementation of a resource of type FILE
- * 
+ *
  * @since 1.10
  */
 public class File extends Resource<Directory> {
@@ -93,7 +94,7 @@ public class File extends Resource<Directory> {
 
   /**
    * {@inheritDoc}
-   * 
+   *
    * @see Resource#getParent()
    */
   @Override
@@ -116,7 +117,7 @@ public class File extends Resource<Directory> {
 
   /**
    * {@inheritDoc}
-   * 
+   *
    * @see Resource#matchFilePattern(String)
    */
   @Override
@@ -129,9 +130,9 @@ public class File extends Resource<Directory> {
    * Creates a File from an io.file and a list of sources directories
    */
   public static File fromIOFile(java.io.File file, List<java.io.File> sourceDirs) {
-    String relativePath = DefaultProjectFileSystem.getRelativePath(file, sourceDirs);
+    PathResolver.RelativePath relativePath = new PathResolver().relativePath(sourceDirs, file);
     if (relativePath != null) {
-      return new File(relativePath);
+      return new File(relativePath.path());
     }
     return null;
   }
@@ -145,7 +146,7 @@ public class File extends Resource<Directory> {
 
   /**
    * {@inheritDoc}
-   * 
+   *
    * @see Resource#getName()
    */
   @Override
@@ -155,7 +156,7 @@ public class File extends Resource<Directory> {
 
   /**
    * {@inheritDoc}
-   * 
+   *
    * @see Resource#getLongName()
    */
   @Override
@@ -165,7 +166,7 @@ public class File extends Resource<Directory> {
 
   /**
    * {@inheritDoc}
-   * 
+   *
    * @see Resource#getDescription()
    */
   @Override
@@ -175,7 +176,7 @@ public class File extends Resource<Directory> {
 
   /**
    * {@inheritDoc}
-   * 
+   *
    * @see Resource#getLanguage()
    */
   @Override
@@ -200,7 +201,7 @@ public class File extends Resource<Directory> {
 
   /**
    * Returns the qualifier associated to this File. Should be QUALIFIER_FILE or
-   * 
+   *
    * @return QUALIFIER_UNIT_TEST_CLASS
    */
   @Override
@@ -215,10 +216,10 @@ public class File extends Resource<Directory> {
   @Override
   public String toString() {
     return new ToStringBuilder(this)
-        .append("key", getKey())
-        .append("dir", directoryKey)
-        .append("filename", filename)
-        .append("language", language)
-        .toString();
+      .append("key", getKey())
+      .append("dir", directoryKey)
+      .append("filename", filename)
+      .append("language", language)
+      .toString();
   }
 }
\ No newline at end of file
index fb4bde7518907f50eca6ed7241b2fc08ddca4967..340895b234b47cb3731b68660ce99a79ccd09419 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.api.resources;
 
 import org.apache.commons.lang.StringUtils;
+import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.utils.WildcardPattern;
 
 import java.io.File;
@@ -210,8 +211,11 @@ public class JavaFile extends Resource<JavaPackage> {
     if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), ".java")) {
       return null;
     }
-    String relativePath = DefaultProjectFileSystem.getRelativePath(file, sourceDirs);
-    return fromRelativePath(relativePath, unitTest);
+    PathResolver.RelativePath relativePath = new PathResolver().relativePath(sourceDirs, file);
+    if (relativePath != null) {
+      return fromRelativePath(relativePath.path(), unitTest);
+    }
+    return null;
   }
 
   /**
index 9500b6b9c095fe2afbd9cfb333f59c731232e02a..28d2b3a436a3362c63cc46041d79d8422ab57cc2 100644 (file)
@@ -330,7 +330,9 @@ public class Project extends Resource {
    * Patterns of resource exclusion as defined in project settings page.
    *
    * @since 3.3 also applies exclusions in general settings page and global exclusions.
+   * @deprecated replaced by {@link org.sonar.api.scan.filesystem.ModuleExclusions} in version 3.5
    */
+  @Deprecated
   public String[] getExclusionPatterns() {
     return trimExclusions(ImmutableList.<String> builder()
       .add(configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY))
@@ -342,7 +344,9 @@ public class Project extends Resource {
    * Also applies exclusions in general settings page and global exclusions.
    *
    * @since 3.3
+   * @deprecated replaced by {@link org.sonar.api.scan.filesystem.ModuleExclusions} in version 3.5
    */
+  @Deprecated
   public String[] getTestExclusionPatterns() {
     String[] globalTestExclusions = configuration.getStringArray(CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY);
     if (globalTestExclusions.length == 0) {
@@ -365,15 +369,18 @@ public class Project extends Resource {
 
   /**
    * Set exclusion patterns. Configuration is not saved, so this method must be used ONLY IN UNIT TESTS.
+   * @deprecated replaced by {@link org.sonar.api.scan.filesystem.ModuleExclusions} in version 3.5
    */
+  @Deprecated
   public Project setExclusionPatterns(String[] s) {
-    configuration.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, StringUtils.join(s, ","));
-    return this;
+    throw new UnsupportedOperationException("deprecated in 3.5");
   }
 
   /**
    * Note: it's better to get a reference on ProjectFileSystem as an IoC dependency (constructor parameter)
+   * @deprecated replaced by {@link org.sonar.api.scan.filesystem.ModuleFileSystem} in 3.5
    */
+  @Deprecated
   public ProjectFileSystem getFileSystem() {
     return fileSystem;
   }
index f3557507b45ecc6142c50bb124a30dce9e1bb4c3..b1a1af269804a70fe04e66bea65a87c8ce9736be 100644 (file)
@@ -28,6 +28,7 @@ import java.util.List;
 
 /**
  * @since 1.10
+ * @deprecated replaced by {@link org.sonar.api.scan.filesystem.ModuleFileSystem} in 3.5
  */
 public interface ProjectFileSystem extends BatchComponent {
   /**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FailToCreateFileException.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FailToCreateFileException.java
deleted file mode 100644 (file)
index 7bf68c6..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.api.scan.filesystem;
-
-import com.google.common.annotations.Beta;
-
-/**
- * @since 3.5
- */
-@Beta
-public class FailToCreateFileException extends FileSystemException {
-  public FailToCreateFileException(String message, Throwable cause) {
-    super(message, cause);
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleExclusions.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleExclusions.java
new file mode 100644 (file)
index 0000000..7331a98
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.api.scan.filesystem;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.ObjectArrays;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
+
+import java.util.List;
+
+/**
+ * Configuration of file inclusions and exclusions
+ *
+ * @since 3.5
+ */
+public class ModuleExclusions implements BatchComponent {
+  private final Settings settings;
+
+  public ModuleExclusions(Settings settings) {
+    this.settings = settings;
+  }
+
+  public String[] sourceInclusions() {
+    return inclusions(CoreProperties.PROJECT_INCLUSIONS_PROPERTY);
+  }
+
+  public String[] testInclusions() {
+    return inclusions(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY);
+  }
+
+  private String[] inclusions(String propertyKey) {
+    String[] patterns = sanitize(settings.getStringArray(propertyKey));
+    List<String> list = Lists.newArrayList();
+    for (String pattern : patterns) {
+      if (!"**/*".equals(pattern)) {
+        list.add(pattern);
+      }
+    }
+    return list.toArray(new String[list.size()]);
+  }
+
+  public String[] sourceExclusions() {
+    return exclusions(CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_EXCLUSIONS_PROPERTY);
+  }
+
+  public String[] testExclusions() {
+    return exclusions(CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY);
+  }
+
+  private String[] exclusions(String globalExclusionsProperty, String exclusionsProperty) {
+    String[] globalExclusions = settings.getStringArray(globalExclusionsProperty);
+    String[] exclusions = settings.getStringArray(exclusionsProperty);
+    return sanitize(ObjectArrays.concat(globalExclusions, exclusions, String.class));
+  }
+
+  private static String[] sanitize(String[] patterns) {
+    for (int i = 0; i < patterns.length; i++) {
+      patterns[i] = StringUtils.trim(patterns[i]);
+    }
+    return patterns;
+  }
+}
index 49031608d5e46c4a05e12e20df08ba2c8137fdc4..e0311225ce00202e9171effaa6be4f6520e00009 100644 (file)
  */
 package org.sonar.api.scan.filesystem;
 
-import com.google.common.annotations.Beta;
 import org.sonar.api.BatchComponent;
 
+import javax.annotation.CheckForNull;
+
 import java.io.File;
 import java.nio.charset.Charset;
 import java.util.List;
@@ -29,16 +30,71 @@ import java.util.List;
 /**
  * @since 3.5
  */
-@Beta
 public interface ModuleFileSystem extends BatchComponent {
+  /**
+   * Base directory.
+   */
   File baseDir();
+
+  /**
+   * Optional directory used by the build tool to generate various kinds of data (test reports, temp files, ...).
+   * In Maven, it's given by the property ${project.build.directory}, which value is generally ${project.basedir}/target.
+   */
+  @CheckForNull
+  File buildDir();
+
+  /**
+   * Source directories. Non-existing directories are excluded.
+   * Example in Maven : ${project.basedir}/src/main/java
+   */
   List<File> sourceDirs();
+
+  /**
+   * The files that are located in source directories and that match preconditions (inclusions/exclusions/{@link FileFilter})
+   */
   List<File> sourceFiles();
+
+  /**
+   * The subset of {@link #sourceFiles()} matching the given language. For example {@code sourceFilesOfLang("java")} return all the source
+   * files suffixed with .java or .jav.
+   */
   List<File> sourceFilesOfLang(String language);
+
+  /**
+   * Test directories. Non-existing directories are excluded.
+   * Example in Maven : ${project.basedir}/src/test/java
+   */
   List<File> testDirs();
+
+  /**
+   * The files that are located in test directories and that match preconditions (inclusions/exclusions/{@link FileFilter})
+   */
   List<File> testFiles();
+
+  /**
+   * The subset of {@link #testFiles()} matching the given language. For example {@code testFilesOfLang("java")} return all the test
+   * files suffixed with .java or .jav.
+   */
   List<File> testFilesOfLang(String language);
+
+  /**
+   * Optional directories that contain the compiled sources, for example java bytecode.
+   * Note that :
+   * <ul>
+   * <li>Maven projects have only a single binary directory, which is generally ${project.basedir}/target/classes</li>
+   * <li>Binary directories can be empty</li>
+   * <li>Test binary directories are not supported yet.</li>
+   * </ul>
+   */
   List<File> binaryDirs();
+
+  /**
+   * Charset of source and test files. If it's not defined, then return the platform default charset.
+   */
   Charset sourceCharset();
+
+  /**
+   * Working directory used by Sonar. This directory can be used for example to store intermediary reports.
+   */
   File workingDir();
 }
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/PathResolver.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/PathResolver.java
new file mode 100644 (file)
index 0000000..d3de2de
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.api.scan.filesystem;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import org.apache.commons.io.FilenameUtils;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.scan.filesystem.IllegalPathException;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @since 3.5
+ */
+public class PathResolver implements BatchComponent {
+
+  public File relativeFile(File dir, String path) {
+    Preconditions.checkArgument(dir.isDirectory(), "Not a directory: " + dir.getAbsolutePath());
+    File file = new File(path);
+    if (!file.isAbsolute()) {
+      try {
+        file = new File(dir, path).getCanonicalFile();
+      } catch (Exception e) {
+        throw new IllegalPathException("Fail to resolve path '" + path + "' relative to: " + dir.getAbsolutePath());
+      }
+    }
+    return file;
+  }
+
+  public List<File> relativeFiles(File dir, List<String> paths) {
+    List<File> result = Lists.newArrayList();
+    for (String path : paths) {
+      result.add(relativeFile(dir, path));
+    }
+    return result;
+  }
+
+  public RelativePath relativePath(Collection<File> dirs, File file) {
+    List<String> stack = Lists.newArrayList();
+    String path = FilenameUtils.normalize(file.getAbsolutePath());
+    File cursor = new File(path);
+    while (cursor != null) {
+      File parentDir = parentDir(dirs, cursor);
+      if (parentDir != null) {
+        return new RelativePath(parentDir, Joiner.on("/").join(stack));
+      }
+      stack.add(0, cursor.getName());
+      cursor = cursor.getParentFile();
+    }
+    return null;
+  }
+
+  public String relativePath(File dir, File file) {
+    List<String> stack = Lists.newArrayList();
+    String path = FilenameUtils.normalize(file.getAbsolutePath());
+    File cursor = new File(path);
+    while (cursor != null) {
+      if (containsFile(dir, cursor)) {
+        return Joiner.on("/").join(stack);
+      }
+      stack.add(0, cursor.getName());
+      cursor = cursor.getParentFile();
+    }
+    return null;
+  }
+
+  private File parentDir(Collection<File> dirs, File cursor) {
+    for (File dir : dirs) {
+      if (FilenameUtils.equalsNormalizedOnSystem(dir.getAbsolutePath(), cursor.getAbsolutePath())) {
+        return dir;
+      }
+    }
+    return null;
+  }
+
+  private boolean containsFile(File dir, File cursor) {
+    return FilenameUtils.equalsNormalizedOnSystem(dir.getAbsolutePath(), cursor.getAbsolutePath());
+  }
+
+  public static class RelativePath {
+    private File dir;
+    private String path;
+
+    RelativePath(File dir, String path) {
+      this.dir = dir;
+      this.path = path;
+    }
+
+    public File dir() {
+      return dir;
+    }
+
+    public String path() {
+      return path;
+    }
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java
deleted file mode 100644 (file)
index da456d5..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.api.resources;
-
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.SystemUtils;
-import org.apache.maven.project.MavenProject;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.Matchers;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.FileFilter;
-import org.sonar.api.test.MavenTestUtils;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class DefaultProjectFileSystemTest {
-
-  private Project project = null;
-
-  @Before
-  public void before() {
-    project = MavenTestUtils.loadProjectFromPom(DefaultProjectFileSystemTest.class, "sample/pom.xml");
-  }
-
-  /**
-   * See http://jira.codehaus.org/browse/SONAR-2266
-   */
-  @Test
-  public void shouldReturnOnlyExistingSourceAndTestDirectories() {
-    // in this example : "src/main/java" is a file, "src/test/java" doesn't exists
-    project = MavenTestUtils.loadProjectFromPom(DefaultProjectFileSystemTest.class, "nonexistent-dirs/pom.xml");
-    DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-    assertThat(fs.getSourceDirs().size(), is(0));
-    assertThat(fs.getTestDirs().size(), is(0));
-  }
-
-  @Test
-  public void getJavaSourceFiles() {
-    final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-
-    assertThat(fs.getJavaSourceFiles().size(), is(2));
-    assertThat(fs.getJavaSourceFiles(), hasItem(named("Bar.java")));
-    assertThat(fs.getJavaSourceFiles(), hasItem(named("Whizz.java")));
-  }
-
-  @Test
-  public void hasJavaSourceFiles() {
-    final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-    assertThat(fs.hasJavaSourceFiles(), is(true));
-
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*.java");
-    project.setConfiguration(conf);
-    assertThat(fs.hasJavaSourceFiles(), is(false));
-  }
-
-  @Test
-  public void getTestFiles() {
-    final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-
-    assertThat(fs.getTestFiles(Java.INSTANCE).size(), is(1));
-    assertThat(fs.getTestFiles(Java.INSTANCE), hasItem(named("BarTest.java")));
-  }
-
-  @Test
-  public void applyExclusionPatternsToSourceFiles() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/B*.java");
-    project.setConfiguration(conf);
-
-    final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-
-    assertThat(fs.getJavaSourceFiles().size(), is(1));
-    assertThat(fs.getJavaSourceFiles(), hasItem(named("Whizz.java")));
-  }
-
-  /**
-   * See http://jira.codehaus.org/browse/SONAR-1449
-   */
-  @Test
-  public void exclusionPatternOnAjFiles() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*.aj");
-    project.setConfiguration(conf);
-
-    final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-
-    assertThat(fs.getSourceFiles(Java.INSTANCE).size(), is(2));
-    assertThat(fs.getSourceFiles(Java.INSTANCE), hasItem(named("Whizz.java")));
-    assertThat(fs.getSourceFiles(Java.INSTANCE), hasItem(named("Bar.java")));
-  }
-
-  @Test
-  public void doNotApplyExclusionPatternsToTestFiles() {
-    PropertiesConfiguration conf = new PropertiesConfiguration();
-    conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/B*.java");
-    project.setConfiguration(conf);
-
-    final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-
-    assertThat(fs.getTestFiles(Java.INSTANCE).size(), is(1));
-    assertThat(fs.getTestFiles(Java.INSTANCE), hasItem(named("BarTest.java")));
-  }
-
-  @Test
-  public void createSonarWorkingDirectory() {
-    DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-    java.io.File dir = fs.getSonarWorkingDirectory();
-    assertThat(dir.exists(), is(true));
-    assertThat(dir.listFiles().length, is(0));
-  }
-
-  @Test
-  public void getJapaneseCharSet() {
-    project = MavenTestUtils.loadProjectFromPom(DefaultProjectFileSystemTest.class, "japanese-project/pom.xml");
-    DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project);
-    assertThat(fs.getSourceCharset().name(), is("Shift_JIS"));
-  }
-
-  @Test
-  public void languageWithNoSpecificFileSuffixes() {
-    class NoSuffixLanguage implements Language {
-      public String getKey() {
-        return "no-suffix";
-      }
-
-      public String getName() {
-        return "no-suffix";
-      }
-
-      public String[] getFileSuffixes() {
-        return new String[0];
-      }
-    }
-
-    project = MavenTestUtils.loadProjectFromPom(DefaultProjectFileSystemTest.class, "sample-with-different-suffixes/pom.xml");
-    ProjectFileSystem fs = newDefaultProjectFileSystem(project);
-    List<File> files = fs.getSourceFiles(new NoSuffixLanguage());
-    assertThat(files.size(), is(2));
-  }
-
-  /**
-   * See http://jira.codehaus.org/browse/SONAR-2280
-   */
-  @Test
-  public void resolvePathShouldReturnCanonicalFile() {
-    MavenProject pom = mock(MavenProject.class);
-    when(pom.getBasedir()).thenReturn(new File("/project"));
-    Project project = new Project("foo").setPom(pom);
-    DefaultProjectFileSystem fs = new DefaultProjectFileSystem(project, null);
-
-    assertThat(fs.resolvePath(".").getAbsolutePath(), endsWith("project"));
-    assertThat(fs.resolvePath("../project").getAbsolutePath(), endsWith("project"));
-  }
-
-  /**
-   * Example of hidden files/directories : .DSStore, .svn, .git
-   */
-  @Test
-  public void hiddenFilesAreIgnored() {
-    if (!SystemUtils.IS_OS_WINDOWS) {
-      // hidden files/directories can not be stored in svn windows
-      // On Mac/Linux it's easy, just prefix the filename by '.'
-      project = MavenTestUtils.loadProjectFromPom(DefaultProjectFileSystemTest.class, "hidden-files/pom.xml");
-      ProjectFileSystem fs = newDefaultProjectFileSystem(project);
-      List<File> files = fs.getSourceFiles();
-      assertThat(files.size(), is(1));
-      assertThat(files.get(0).getName(), is("foo.sql"));
-    }
-  }
-
-  @Test
-  public void shouldUseExtendedFilters() {
-    DefaultProjectFileSystem fsWithoutFilter = newDefaultProjectFileSystem(project);
-    assertThat(fsWithoutFilter.getSourceFiles().size(), is(2));
-    assertThat(fsWithoutFilter.getSourceFiles(), hasItem(named("Bar.java")));
-
-    FileFilter filter = new FileFilter() {
-      public boolean accept(File file) {
-        return !StringUtils.equals(file.getName(), "Bar.java");
-      }
-    };
-    DefaultProjectFileSystem fsWithFilter = new DefaultProjectFileSystem(project, new Languages(Java.INSTANCE), filter);
-    assertThat(fsWithFilter.getSourceFiles().size(), is(1));
-    assertThat(fsWithFilter.getSourceFiles(), not(hasItem(named("Bar.java"))));
-  }
-
-  @Test
-  public void testSelectiveFileFilter() {
-    DefaultProjectFileSystem.FileSelectionFilter filter = new DefaultProjectFileSystem.FileSelectionFilter(
-      Arrays.asList(new File("foo/Bar.java"), new File("hello/Bar.java"), new File("hello/World.java")));
-    assertThat(filter.accept(new File("foo/Bar.java")), Matchers.is(true));
-    assertThat(filter.accept(new File("hello/Bar.java")), Matchers.is(true));
-    assertThat(filter.accept(new File("hello/World.java")), Matchers.is(true));
-
-    assertThat(filter.accept(new File("foo/Unknown.java")), Matchers.is(false));
-    assertThat(filter.accept(new File("foo/bar/Bar.java")), Matchers.is(false));
-    assertThat(filter.accept(new File("foo/World.java")), Matchers.is(false));
-  }
-
-  /**
-   * SONAR-3096
-   */
-  @Test
-  public void shouldExcludeDirectoriesStartingWithDot() {
-    List<File> dirs = Arrays.asList(new File("test-resources/org/sonar/api/resources/DefaultProjectFileSystemTest/shouldExcludeDirectoriesStartingWithDot/src"));
-
-    List<InputFile> files = new DefaultProjectFileSystem(new Project("foo"), null).getFiles(dirs, Collections.<File>emptyList(), new String[0]);
-    assertThat(files.size(), is(1));
-    assertThat(files.get(0).getRelativePath(), is("org/sonar/Included.java"));
-  }
-
-  private DefaultProjectFileSystem newDefaultProjectFileSystem(Project project) {
-    return (DefaultProjectFileSystem) project.getFileSystem();
-  }
-
-  private static Matcher<java.io.File> named(final String name) {
-    return new TypeSafeMatcher<java.io.File>() {
-      java.io.File fileTested;
-
-      @Override
-      public boolean matchesSafely(java.io.File item) {
-        fileTested = item;
-        return name.equals(item.getName());
-      }
-
-      public void describeTo(Description description) {
-        description.appendText(" that file ");
-        description.appendValue(fileTested);
-        description.appendText(" is named");
-        description.appendText(name);
-        description.appendText(" not ");
-        description.appendValue(fileTested.getName());
-      }
-    };
-  }
-}
\ No newline at end of file
index 81c3f209886c2e7e587892999a2e5cb3a55d7212..63789a313c450e33c60624fb2739f4cbb89515b3 100644 (file)
@@ -94,13 +94,4 @@ public class ProjectTest {
 
     assertThat(project.getTestExclusionPatterns()).containsOnly("**/*Test.java", "**/*IntegrationTest.java", "**/*FunctionalTest.java");
   }
-
-  @Test
-  public void testSetExclusionPatterns() {
-    Project project = new Project("key").setConfiguration(conf);
-
-    project.setExclusionPatterns(new String[] {"**/*Foo.java", "**/*Bar.java"});
-
-    assertThat(project.getExclusionPatterns()).containsOnly("**/*Foo.java", "**/*Bar.java");
-  }
 }
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/JavaIoFileFilterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/JavaIoFileFilterTest.java
new file mode 100644 (file)
index 0000000..b38dbd7
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.api.scan.filesystem;
+
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class JavaIoFileFilterTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Test
+  public void should_wrap_java_io_filefilter() throws IOException {
+    IOFileFilter javaIoFilter = mock(IOFileFilter.class);
+    JavaIoFileFilter filter = JavaIoFileFilter.create(javaIoFilter);
+
+    File file = temp.newFile();
+    filter.accept(file, mock(FileFilter.Context.class));
+
+    verify(javaIoFilter).accept(file);
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/ModuleExclusionsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/ModuleExclusionsTest.java
new file mode 100644 (file)
index 0000000..25f52de
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.api.scan.filesystem;
+
+import org.junit.Test;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ModuleExclusionsTest {
+  @Test
+  public void ignore_inclusion_of_world() {
+    Settings settings = new Settings();
+    settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*");
+    settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "**/*");
+    assertThat(new ModuleExclusions(settings).sourceInclusions()).isEmpty();
+    assertThat(new ModuleExclusions(settings).testInclusions()).isEmpty();
+  }
+
+  @Test
+  public void load_inclusions() {
+    Settings settings = new Settings();
+    settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Foo.java");
+    settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "**/*FooTest.java");
+    ModuleExclusions moduleExclusions = new ModuleExclusions(settings);
+
+    assertThat(moduleExclusions.sourceInclusions()).containsOnly("**/*Foo.java");
+    assertThat(moduleExclusions.testInclusions()).containsOnly("**/*FooTest.java");
+  }
+
+  @Test
+  public void load_exclusions() {
+    Settings settings = new Settings();
+    settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Foo.java");
+    settings.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, "**/*FooTest.java");
+    ModuleExclusions moduleExclusions = new ModuleExclusions(settings);
+
+    assertThat(moduleExclusions.sourceInclusions()).isEmpty();
+    assertThat(moduleExclusions.sourceExclusions()).containsOnly("**/*Foo.java");
+    assertThat(moduleExclusions.testInclusions()).isEmpty();
+    assertThat(moduleExclusions.testExclusions()).containsOnly("**/*FooTest.java");
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/PathResolverTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/PathResolverTest.java
new file mode 100644 (file)
index 0000000..f4256ca
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.api.scan.filesystem;
+
+import org.apache.commons.io.FilenameUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PathResolverTest {
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Test
+  public void get_file_by_relative_path() throws IOException {
+    PathResolver resolver = new PathResolver();
+    File rootDir = temp.newFolder();
+    File file = resolver.relativeFile(rootDir, "org/foo/Bar.java");
+    assertThat(file.getName()).isEqualTo("Bar.java");
+    assertThat(FilenameUtils.separatorsToUnix(file.getCanonicalPath())).endsWith("org/foo/Bar.java");
+    assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath());
+  }
+
+  @Test
+  public void get_file_by_absolute_path() throws IOException {
+    PathResolver resolver = new PathResolver();
+    File rootDir = temp.newFolder();
+    File file = resolver.relativeFile(rootDir, new File(rootDir, "org/foo/Bar.java").getAbsolutePath());
+    assertThat(file.getName()).isEqualTo("Bar.java");
+    assertThat(FilenameUtils.separatorsToUnix(file.getCanonicalPath())).endsWith("org/foo/Bar.java");
+    assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath());
+  }
+
+  @Test
+  public void get_files_by_relative_paths() throws IOException {
+    PathResolver resolver = new PathResolver();
+    File rootDir = temp.newFolder();
+    List<File> files = resolver.relativeFiles(rootDir, Arrays.asList("org/foo/Bar.java", "org/hello/World.java"));
+    assertThat(files).hasSize(2);
+    for (File file : files) {
+      assertThat(file.getName()).endsWith(".java");
+      assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath());
+    }
+  }
+
+  @Test
+  public void relative_path_from_dir() throws IOException {
+    PathResolver resolver = new PathResolver();
+    File rootDir = temp.newFolder();
+    File org = new File(rootDir, "org");
+    File hello = new File(org, "hello");
+    File world = new File(hello, "World.java");
+
+    assertThat(resolver.relativePath(rootDir, world)).isEqualTo("org/hello/World.java");
+  }
+
+  @Test
+  public void relative_path_from_multiple_dirs() throws IOException {
+    PathResolver resolver = new PathResolver();
+    File dir1 = temp.newFolder("D1");
+    File dir2 = temp.newFolder("D2");
+
+    File org = new File(dir2, "org");
+    File hello = new File(org, "hello");
+    File world = new File(hello, "World.java");
+
+    PathResolver.RelativePath relativePath = resolver.relativePath(Arrays.asList(dir1, dir2), world);
+    assertThat(relativePath.dir().getCanonicalPath()).isEqualTo(dir2.getCanonicalPath());
+    assertThat(relativePath.path()).isEqualTo("org/hello/World.java");
+  }
+
+  @Test
+  public void cant_find_relative_path_from_multiple_dirs() throws IOException {
+    PathResolver resolver = new PathResolver();
+    File dir1 = temp.newFolder("D1");
+    File dir2 = temp.newFolder("D2");
+
+    File org = new File(dir2, "org");
+    File hello = new File(org, "hello");
+    File world = new File(hello, "World.java");
+
+    PathResolver.RelativePath relativePath = resolver.relativePath(Arrays.asList(dir1), world);
+    assertThat(relativePath).isNull();
+  }
+
+  @Test
+  public void null_relative_path_when_file_is_not_in_dir() throws IOException {
+    PathResolver resolver = new PathResolver();
+    File rootDir = temp.newFolder();
+
+    assertThat(resolver.relativePath(rootDir, new File("Elsewhere.java"))).isNull();
+  }
+}
index 7dfc3bcf67d71a9fa64c376e005e77cf5e1dc8c6..0b86e3bb661f38c9bdfbe5c348a7379b40fa3c98 100644 (file)
@@ -21,20 +21,27 @@ package org.sonar.api.test;
 
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
 import org.apache.maven.project.MavenProject;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.maven.MavenUtils;
-import org.sonar.api.resources.DefaultProjectFileSystem;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.InputFile;
+import org.sonar.api.resources.Language;
 import org.sonar.api.resources.Project;
+import org.sonar.api.resources.ProjectFileSystem;
+import org.sonar.api.resources.Resource;
 import org.sonar.api.utils.SonarException;
 
 import java.io.File;
 import java.io.FileReader;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -71,13 +78,13 @@ public final class MavenTestUtils {
     MavenProject pom = loadPom(clazz, path);
     Configuration configuration = new MapConfiguration(pom.getProperties());
     Project project = new Project(pom.getGroupId() + ":" + pom.getArtifactId())
-        .setPom(pom)
-        .setConfiguration(configuration);
+      .setPom(pom)
+      .setConfiguration(configuration);
     configuration.setProperty("sonar.java.source", MavenUtils.getJavaSourceVersion(pom));
     configuration.setProperty("sonar.java.target", MavenUtils.getJavaVersion(pom));
     configuration.setProperty(CoreProperties.ENCODING_PROPERTY, MavenUtils.getSourceEncoding(pom));
-    DefaultProjectFileSystem fs = new DefaultProjectFileSystem(project, new Languages(Java.INSTANCE));
-    project.setFileSystem(fs);
+
+    project.setFileSystem(new MavenModuleFileSystem(pom));
     return project;
   }
 
@@ -86,4 +93,102 @@ public final class MavenTestUtils {
     when(mavenProject.getPackaging()).thenReturn(packaging);
     return mavenProject;
   }
+
+  static class MavenModuleFileSystem implements ProjectFileSystem {
+    private MavenProject pom;
+
+    MavenModuleFileSystem(MavenProject pom) {
+      this.pom = pom;
+    }
+
+    public Charset getSourceCharset() {
+      return Charset.forName(MavenUtils.getSourceEncoding(pom));
+    }
+
+    public File getBasedir() {
+      return pom.getBasedir();
+    }
+
+    public File getBuildDir() {
+      return new File(pom.getBuild().getDirectory());
+    }
+
+    public File getBuildOutputDir() {
+      return new File(pom.getBuild().getOutputDirectory());
+    }
+
+    public List<File> getSourceDirs() {
+      return Arrays.asList(new File(pom.getBuild().getSourceDirectory()));
+    }
+
+    public ProjectFileSystem addSourceDir(File dir) {
+      throw new UnsupportedOperationException();
+    }
+
+    public List<File> getTestDirs() {
+      return null;
+    }
+
+    public ProjectFileSystem addTestDir(File dir) {
+      throw new UnsupportedOperationException();
+    }
+
+    public File getReportOutputDir() {
+      return null;
+    }
+
+    public File getSonarWorkingDirectory() {
+      File dir = new File(getBuildDir(), "sonar");
+      try {
+        FileUtils.forceMkdir(dir);
+      } catch (IOException e) {
+        throw new IllegalStateException(e);
+      }
+      return dir;
+    }
+
+    public File resolvePath(String path) {
+      throw new UnsupportedOperationException();
+    }
+
+    public List<File> getSourceFiles(Language... langs) {
+      return new ArrayList(FileUtils.listFiles(getSourceDirs().get(0), new String[]{"java"}, true));
+    }
+
+    public List<File> getJavaSourceFiles() {
+      return getSourceFiles();
+    }
+
+    public boolean hasJavaSourceFiles() {
+      return !getJavaSourceFiles().isEmpty();
+    }
+
+    public List<File> getTestFiles(Language... langs) {
+      return new ArrayList(FileUtils.listFiles(getTestDirs().get(0), new String[]{"java"}, true));
+    }
+
+    public boolean hasTestFiles(Language lang) {
+      return !getTestFiles(lang).isEmpty();
+    }
+
+    public File writeToWorkingDirectory(String content, String fileName) throws IOException {
+      throw new UnsupportedOperationException();
+    }
+
+    public File getFileFromBuildDirectory(String filename) {
+      throw new UnsupportedOperationException();
+    }
+
+    public Resource toResource(File file) {
+      throw new UnsupportedOperationException();
+    }
+
+    public List<InputFile> mainFiles(String... langs) {
+      throw new UnsupportedOperationException();
+    }
+
+    public List<InputFile> testFiles(String... langs) {
+      throw new UnsupportedOperationException();
+    }
+  }
 }