Browse Source

SONAR-1896 refactor file system components used during project analysis

tags/3.5
Simon Brandhof 11 years ago
parent
commit
83d3271555
35 changed files with 1907 additions and 117 deletions
  1. 129
    113
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
  2. 228
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java
  3. 148
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileSystemAdapter.java
  4. 47
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionFileFilter.java
  5. 63
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileFilterContext.java
  6. 58
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InclusionFileFilter.java
  7. 42
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageFileFilters.java
  8. 166
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProvider.java
  9. 74
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java
  10. 42
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/WhiteListFileFilter.java
  11. 27
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/package-info.java
  12. 187
    0
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java
  13. 71
    0
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFileFilterTest.java
  14. 76
    0
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InclusionFileFilterTest.java
  15. 75
    0
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageFileFiltersTest.java
  16. 51
    0
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProviderTest.java
  17. 88
    0
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java
  18. 54
    0
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/WhiteListFileFilterTest.java
  19. 1
    0
      sonar-batch/test-resources/DefaultModuleFileSystemTest/exclude_dir_starting_with_dot/src/org/.dirPrefixedWithDot/Excluded.java
  20. 1
    0
      sonar-batch/test-resources/DefaultModuleFileSystemTest/exclude_dir_starting_with_dot/src/org/.sonar/Excluded2.java
  21. 3
    0
      sonar-batch/test-resources/DefaultModuleFileSystemTest/exclude_dir_starting_with_dot/src/org/sonar/Included.java
  22. 1
    0
      sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/main/java/Foo.java
  23. 1
    0
      sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/main/java/Hello.java
  24. 1
    0
      sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/test/java/FooTest.java
  25. 1
    0
      sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/test/java/HelloTest.java
  26. 2
    0
      sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
  27. 5
    3
      sonar-plugin-api/src/main/java/org/sonar/api/batch/FileFilter.java
  28. 1
    1
      sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java
  29. 32
    0
      sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FailToCreateFileException.java
  30. 44
    0
      sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileFilter.java
  31. 36
    0
      sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileSystemException.java
  32. 37
    0
      sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/IllegalPathException.java
  33. 44
    0
      sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/JavaIoFileFilter.java
  34. 44
    0
      sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java
  35. 27
    0
      sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/package-info.java

+ 129
- 113
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java View File

@@ -189,6 +189,22 @@ import java.util.List;
multiValues = true,
category = CoreProperties.CATEGORY_EXCLUSIONS,
defaultValue = CoreProperties.GLOBAL_TEST_EXCLUSIONS_DEFAULT),
@Property(
key = CoreProperties.PROJECT_INCLUSIONS_PROPERTY,
name = "Inclusions",
description = "Define the file sources to analyze. Changes will be applied during next code analysis.",
project = true,
global = true,
multiValues = true,
category = CoreProperties.CATEGORY_EXCLUSIONS),
@Property(
key = CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY,
name = "Test Inclusions",
description = "Define the test files to analyze. Changes will be applied during next code analysis.",
project = true,
global = true,
multiValues = true,
category = CoreProperties.CATEGORY_EXCLUSIONS),
@Property(
key = CoreProperties.PROJECT_EXCLUSIONS_PROPERTY,
name = "Exclusions",
@@ -395,129 +411,129 @@ public final class CorePlugin extends SonarPlugin {
@SuppressWarnings("unchecked")
public List getExtensions() {
return ImmutableList.of(
DefaultResourceTypes.class,
UserManagedMetrics.class,
ProjectFileSystemLogger.class,
Periods.class,
DefaultResourceTypes.class,
UserManagedMetrics.class,
ProjectFileSystemLogger.class,
Periods.class,

// maven
MavenInitializer.class,
// maven
MavenInitializer.class,

// languages
Java.class,
// languages
Java.class,

// pages
Lcom4Viewer.class,
TestsViewer.class,
// pages
Lcom4Viewer.class,
TestsViewer.class,

// measure filters
ProjectFilter.class,
MyFavouritesFilter.class,
// measure filters
ProjectFilter.class,
MyFavouritesFilter.class,

// widgets
AlertsWidget.class,
CoverageWidget.class,
ItCoverageWidget.class,
CommentsDuplicationsWidget.class,
DescriptionWidget.class,
ComplexityWidget.class,
RulesWidget.class,
SizeWidget.class,
EventsWidget.class,
CustomMeasuresWidget.class,
TimelineWidget.class,
TimeMachineWidget.class,
HotspotMetricWidget.class,
HotspotMostViolatedResourcesWidget.class,
HotspotMostViolatedRulesWidget.class,
MyReviewsWidget.class,
ProjectReviewsWidget.class,
FalsePositiveReviewsWidget.class,
ReviewsPerDeveloperWidget.class,
PlannedReviewsWidget.class,
UnplannedReviewsWidget.class,
ActionPlansWidget.class,
ReviewsMetricsWidget.class,
TreemapWidget.class,
MeasureFilterListWidget.class,
MeasureFilterTreemapWidget.class,
WelcomeWidget.class,
// widgets
AlertsWidget.class,
CoverageWidget.class,
ItCoverageWidget.class,
CommentsDuplicationsWidget.class,
DescriptionWidget.class,
ComplexityWidget.class,
RulesWidget.class,
SizeWidget.class,
EventsWidget.class,
CustomMeasuresWidget.class,
TimelineWidget.class,
TimeMachineWidget.class,
HotspotMetricWidget.class,
HotspotMostViolatedResourcesWidget.class,
HotspotMostViolatedRulesWidget.class,
MyReviewsWidget.class,
ProjectReviewsWidget.class,
FalsePositiveReviewsWidget.class,
ReviewsPerDeveloperWidget.class,
PlannedReviewsWidget.class,
UnplannedReviewsWidget.class,
ActionPlansWidget.class,
ReviewsMetricsWidget.class,
TreemapWidget.class,
MeasureFilterListWidget.class,
MeasureFilterTreemapWidget.class,
WelcomeWidget.class,

// dashboards
ProjectDefaultDashboard.class,
ProjectHotspotDashboard.class,
ProjectReviewsDashboard.class,
ProjectTimeMachineDashboard.class,
GlobalDefaultDashboard.class,
// dashboards
ProjectDefaultDashboard.class,
ProjectHotspotDashboard.class,
ProjectReviewsDashboard.class,
ProjectTimeMachineDashboard.class,
GlobalDefaultDashboard.class,

// chart
XradarChart.class,
DistributionBarChart.class,
DistributionAreaChart.class,
// chart
XradarChart.class,
DistributionBarChart.class,
DistributionAreaChart.class,

// colorizers
JavaColorizerFormat.class,
// colorizers
JavaColorizerFormat.class,

// batch
ProfileSensor.class,
ProfileEventsSensor.class,
ProjectLinksSensor.class,
UnitTestDecorator.class,
VersionEventsSensor.class,
CheckAlertThresholds.class,
GenerateAlertEvents.class,
ViolationsDecorator.class,
WeightedViolationsDecorator.class,
ViolationsDensityDecorator.class,
LineCoverageDecorator.class,
CoverageDecorator.class,
BranchCoverageDecorator.class,
ItLineCoverageDecorator.class,
ItCoverageDecorator.class,
ItBranchCoverageDecorator.class,
OverallLineCoverageDecorator.class,
OverallCoverageDecorator.class,
OverallBranchCoverageDecorator.class,
ApplyProjectRolesDecorator.class,
ExcludedResourceFilter.class,
CommentDensityDecorator.class,
NoSonarFilter.class,
DirectoriesDecorator.class,
FilesDecorator.class,
ReviewNotifications.class,
ReviewWorkflowDecorator.class,
ReferenceAnalysis.class,
ManualMeasureDecorator.class,
ManualViolationInjector.class,
ViolationSeverityUpdater.class,
IndexProjectPostJob.class,
ReviewsMeasuresDecorator.class,
// batch
ProfileSensor.class,
ProfileEventsSensor.class,
ProjectLinksSensor.class,
UnitTestDecorator.class,
VersionEventsSensor.class,
CheckAlertThresholds.class,
GenerateAlertEvents.class,
ViolationsDecorator.class,
WeightedViolationsDecorator.class,
ViolationsDensityDecorator.class,
LineCoverageDecorator.class,
CoverageDecorator.class,
BranchCoverageDecorator.class,
ItLineCoverageDecorator.class,
ItCoverageDecorator.class,
ItBranchCoverageDecorator.class,
OverallLineCoverageDecorator.class,
OverallCoverageDecorator.class,
OverallBranchCoverageDecorator.class,
ApplyProjectRolesDecorator.class,
ExcludedResourceFilter.class,
CommentDensityDecorator.class,
NoSonarFilter.class,
DirectoriesDecorator.class,
FilesDecorator.class,
ReviewNotifications.class,
ReviewWorkflowDecorator.class,
ReferenceAnalysis.class,
ManualMeasureDecorator.class,
ManualViolationInjector.class,
ViolationSeverityUpdater.class,
IndexProjectPostJob.class,
ReviewsMeasuresDecorator.class,

// time machine
TendencyDecorator.class,
VariationDecorator.class,
ViolationTrackingDecorator.class,
ViolationPersisterDecorator.class,
NewViolationsDecorator.class,
TimeMachineConfigurationPersister.class,
NewCoverageFileAnalyzer.class,
NewItCoverageFileAnalyzer.class,
NewOverallCoverageFileAnalyzer.class,
NewCoverageAggregator.class,
// time machine
TendencyDecorator.class,
VariationDecorator.class,
ViolationTrackingDecorator.class,
ViolationPersisterDecorator.class,
NewViolationsDecorator.class,
TimeMachineConfigurationPersister.class,
NewCoverageFileAnalyzer.class,
NewItCoverageFileAnalyzer.class,
NewOverallCoverageFileAnalyzer.class,
NewCoverageAggregator.class,

// notifications
// Notify incoming violations on my favourite projects
NewViolationsOnMyFavouriteProject.class,
NotificationDispatcherMetadata.create("NewViolationsOnMyFavouriteProject")
.setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, "true"),
// Notify alerts on my favourite projects
AlertsOnMyFavouriteProject.class,
NotificationDispatcherMetadata.create("AlertsOnMyFavouriteProject")
.setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, "true"),
// Notify reviews changes
ChangesInReviewAssignedToMeOrCreatedByMe.class,
NotificationDispatcherMetadata.create("ChangesInReviewAssignedToMeOrCreatedByMe")
.setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, "true")
.setProperty(NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION, "true"));
// notifications
// Notify incoming violations on my favourite projects
NewViolationsOnMyFavouriteProject.class,
NotificationDispatcherMetadata.create("NewViolationsOnMyFavouriteProject")
.setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, "true"),
// Notify alerts on my favourite projects
AlertsOnMyFavouriteProject.class,
NotificationDispatcherMetadata.create("AlertsOnMyFavouriteProject")
.setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, "true"),
// Notify reviews changes
ChangesInReviewAssignedToMeOrCreatedByMe.class,
NotificationDispatcherMetadata.create("ChangesInReviewAssignedToMeOrCreatedByMe")
.setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, "true")
.setProperty(NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION, "true"));
}
}

+ 228
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java View File

@@ -0,0 +1,228 @@
/*
* 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.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.HiddenFileFilter;
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 java.io.File;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
* This class can't be immutable because of execution of maven plugins that can change the project structure (see MavenPluginHandler and sonar.phase)
*
* @since 3.5
*/
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 List<File> sourceDirs, testDirs, binaryDirs;
private final PathResolver pathResolver;
private final List<FileFilter> fileFilters;
private final LanguageFileFilters languageFileFilters;

private DefaultModuleFileSystem(Builder builder) {
sourceCharset = builder.sourceCharset;
baseDir = builder.baseDir;
workingDir = builder.workingDir;
sourceDirs = ImmutableList.copyOf(builder.sourceDirs);
testDirs = ImmutableList.copyOf(builder.testDirs);
binaryDirs = ImmutableList.copyOf(builder.binaryDirs);
fileFilters = ImmutableList.copyOf(builder.fileFilters);
pathResolver = builder.pathResolver;
languageFileFilters = builder.languageFileFilters;
}

public File baseDir() {
return baseDir;
}

public List<File> sourceDirs() {
return sourceDirs;
}

public List<File> sourceFiles() {
return files(sourceDirs, FileFilter.FileType.SOURCE, TrueFileFilter.TRUE);
}

public List<File> sourceFilesOfLang(String language) {
return files(sourceDirs, FileFilter.FileType.SOURCE, languageFileFilters.forLang(language));
}

public List<File> testDirs() {
return testDirs;
}

public List<File> testFiles() {
return files(testDirs, FileFilter.FileType.TEST, TrueFileFilter.TRUE);
}

public List<File> testFilesOfLang(String language) {
return files(testDirs, FileFilter.FileType.TEST, languageFileFilters.forLang(language));
}

public List<File> binaryDirs() {
return binaryDirs;
}

public Charset sourceCharset() {
return sourceCharset;
}

public File workingDir() {
return workingDir;
}

PathResolver pathResolver() {
return pathResolver;
}

List<FileFilter> fileFilters() {
return fileFilters;
}

LanguageFileFilters languageFileFilters() {
return languageFileFilters;
}

/**
* 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) {
this.baseDir = basedir;
this.workingDir = workDir;
this.sourceDirs = ImmutableList.copyOf(sourceDirs);
this.testDirs = ImmutableList.copyOf(testDirs);
this.binaryDirs = ImmutableList.copyOf(binaryDirs);
}

private List<File> files(List<File> dirs, FileFilter.FileType fileType, IOFileFilter languageFilter) {
List<File> result = Lists.newLinkedList();
if (dirs != null && !dirs.isEmpty()) {
FileFilterContext context = new FileFilterContext(this, fileType);
for (File dir : dirs) {
if (dir.exists()) {
context.setSourceDir(dir);
Collection<File> files = FileUtils.listFiles(dir, FileFilterUtils.and(HiddenFileFilter.VISIBLE, languageFilter), DIR_FILTER);
applyFilters(files, context);
result.addAll(files);
}
}
}
return result;
}

private void applyFilters(Collection<File> files, FileFilterContext context) {
if (!fileFilters.isEmpty()) {
Iterator<File> it = files.iterator();
while (it.hasNext()) {
File file = it.next();
if (!accept(file, context)) {
it.remove();
}
}
}
}

private boolean accept(File file, FileFilterContext context) {
context.setFileRelativePath(pathResolver.relativePath(context.sourceDir(), file));
for (FileFilter fileFilter : fileFilters) {
if (!fileFilter.accept(file, context)) {
return false;
}
}
return true;
}

static final class Builder {
private Charset sourceCharset;
private File baseDir, workingDir;
private List<File> sourceDirs = Lists.newArrayList(), testDirs = Lists.newArrayList(), binaryDirs = Lists.newArrayList();
private List<FileFilter> fileFilters = Lists.newArrayList();
private PathResolver pathResolver;
LanguageFileFilters languageFileFilters;

Builder sourceCharset(Charset c) {
this.sourceCharset = c;
return this;
}

Builder baseDir(File f) {
this.baseDir = f;
return this;
}

Builder workingDir(File f) {
this.workingDir = f;
return this;
}

Builder addSourceDir(File d) {
sourceDirs.add(d);
return this;
}

Builder addTestDir(File d) {
testDirs.add(d);
return this;
}

Builder addBinaryDir(File d) {
binaryDirs.add(d);
return this;
}

Builder addFileFilter(FileFilter f) {
fileFilters.add(f);
return this;
}

Builder pathResolver(PathResolver r) {
pathResolver = r;
return this;
}

Builder languageFileFilters(LanguageFileFilters l) {
languageFileFilters = l;
return this;
}

DefaultModuleFileSystem build() {
Preconditions.checkNotNull(baseDir, "Module base directory is not set");
Preconditions.checkNotNull(workingDir, "Module working directory is not set");
Preconditions.checkNotNull(sourceCharset, "Module source charset is not set");
return new DefaultModuleFileSystem(this);
}
}
}

+ 148
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileSystemAdapter.java View File

@@ -0,0 +1,148 @@
/*
* 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.Iterables;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.CharEncoding;
import org.sonar.api.resources.InputFile;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.ProjectFileSystem;
import org.sonar.api.resources.Resource;
import org.sonar.api.scan.filesystem.ModuleFileSystem;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

public class DeprecatedFileSystemAdapter implements ProjectFileSystem {

private final ModuleFileSystem target;
private final PathResolver pathResolver;

public DeprecatedFileSystemAdapter(ModuleFileSystem target, PathResolver pathResolver) {
this.target = target;
this.pathResolver = pathResolver;
}

public Charset getSourceCharset() {
return target.sourceCharset();
}

public File getBasedir() {
return target.baseDir();
}

public File getBuildDir() {
// TODO
return null;
}

public File getBuildOutputDir() {
return Iterables.getFirst(target.binaryDirs(), null);
}

public List<File> getSourceDirs() {
return target.sourceDirs();
}

public ProjectFileSystem addSourceDir(File dir) {
throw new UnsupportedOperationException("File system is immutable");
}

public List<File> getTestDirs() {
return target.testDirs();
}

public ProjectFileSystem addTestDir(File dir) {
throw new UnsupportedOperationException("File system is immutable");
}

public File getReportOutputDir() {
// TODO
return null;
}

public File getSonarWorkingDirectory() {
return target.workingDir();
}

public File resolvePath(String path) {
// TODO
return null;
}

public List<File> getSourceFiles(Language... langs) {
List<File> result = Lists.newArrayList();
for (Language lang : langs) {
result.addAll(target.sourceFilesOfLang(lang.getKey()));
}
return result;
}

public List<File> getJavaSourceFiles() {
return getSourceFiles(Java.INSTANCE);
}

public boolean hasJavaSourceFiles() {
return !getJavaSourceFiles().isEmpty();
}

public List<File> getTestFiles(Language... langs) {
List<File> result = Lists.newArrayList();
for (Language lang : langs) {
result.addAll(target.testFilesOfLang(lang.getKey()));
}
return result;
}

public boolean hasTestFiles(Language lang) {
return !getTestFiles(lang).isEmpty();
}

public File writeToWorkingDirectory(String content, String fileName) throws IOException {
File file = new File(target.workingDir(), fileName);
FileUtils.writeStringToFile(file, content, CharEncoding.UTF_8);
return file;
}

public File getFileFromBuildDirectory(String filename) {
File file = new File(getBuildDir(), filename);
return (file.exists() ? file : null);
}

public Resource toResource(File file) {
// TODO
return null;
}

public List<InputFile> mainFiles(String... langs) {
// TODO
return null;
}

public List<InputFile> testFiles(String... langs) {
// TODO
return null;
}
}

+ 47
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionFileFilter.java View File

@@ -0,0 +1,47 @@
/*
* 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.lang.StringUtils;
import org.sonar.api.scan.filesystem.FileFilter;
import org.sonar.api.utils.WildcardPattern;

import java.io.File;

/**
* @since 3.5
*/
class ExclusionFileFilter implements FileFilter {
private final FileType fileType;
private final WildcardPattern pattern;

ExclusionFileFilter(FileType fileType, String pattern) {
this.fileType = fileType;
this.pattern = WildcardPattern.create(StringUtils.trim(pattern));
}

public boolean accept(File file, Context context) {
return !fileType.equals(context.fileType()) || !pattern.match(context.fileRelativePath());
}

WildcardPattern pattern() {
return pattern;
}
}

+ 63
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileFilterContext.java View File

@@ -0,0 +1,63 @@
/*
* 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.sonar.api.batch.FileFilter;
import org.sonar.api.scan.filesystem.ModuleFileSystem;

import java.io.File;

class FileFilterContext implements FileFilter.Context {
private final ModuleFileSystem fileSystem;
private final FileFilter.FileType fileType;
private File sourceDir;
private String fileRelativePath;

FileFilterContext(ModuleFileSystem fileSystem, FileFilter.FileType fileType) {
this.fileSystem = fileSystem;
this.fileType = fileType;
}

public ModuleFileSystem fileSystem() {
return fileSystem;
}

public FileFilter.FileType fileType() {
return fileType;
}

public File sourceDir() {
return sourceDir;
}

public String fileRelativePath() {
return fileRelativePath;
}

FileFilterContext setSourceDir(File sourceDir) {
this.sourceDir = sourceDir;
return this;
}

FileFilterContext setFileRelativePath(String fileRelativePath) {
this.fileRelativePath = fileRelativePath;
return this;
}
}

+ 58
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InclusionFileFilter.java View File

@@ -0,0 +1,58 @@
/*
* 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.lang.StringUtils;
import org.sonar.api.scan.filesystem.FileFilter;
import org.sonar.api.utils.WildcardPattern;

import javax.annotation.CheckForNull;

import java.io.File;

/**
* @since 3.5
*/
class InclusionFileFilter implements FileFilter {
private final FileType fileType;
private final WildcardPattern pattern;

private InclusionFileFilter(FileType fileType, String pattern) {
this.fileType = fileType;
this.pattern = WildcardPattern.create(pattern);
}

public boolean accept(File file, Context context) {
return !fileType.equals(context.fileType()) || pattern.match(context.fileRelativePath());
}

@CheckForNull
static InclusionFileFilter create(FileType fileType, String pattern) {
String trimmedPattern = StringUtils.trim(pattern);
if (!"".equals(trimmedPattern) && !"**/*".equals(trimmedPattern)) {
return new InclusionFileFilter(fileType, trimmedPattern);
}
return null;
}

WildcardPattern pattern() {
return pattern;
}
}

+ 42
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageFileFilters.java View File

@@ -0,0 +1,42 @@
/*
* 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.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.resources.Languages;

public class LanguageFileFilters {
private final Languages languages;

public LanguageFileFilters(Languages languages) {
this.languages = languages;
}

public IOFileFilter forLang(String lang) {
String[] suffixes = languages.getSuffixes(lang);
if (suffixes != null && suffixes.length>0) {
return new SuffixFileFilter(suffixes, IOCase.SENSITIVE);
}
return TrueFileFilter.TRUE;
}
}

+ 166
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProvider.java View File

@@ -0,0 +1,166 @@
/*
* 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.ImmutableSet;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
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.batch.bootstrap.TempDirectories;

import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Locale;

/**
* @since 3.5
*/
public class ModuleFileSystemProvider extends ProviderAdapter {
private static final Logger LOG = LoggerFactory.getLogger(ModuleFileSystemProvider.class);

private ModuleFileSystem singleton;

public ModuleFileSystem provide(ProjectDefinition module, PathResolver pathResolver, TempDirectories tempDirectories,
LanguageFileFilters languageFileFilters, Settings settings, FileFilter[] pluginFileFilters) {
if (singleton == null) {
DefaultModuleFileSystem.Builder builder = new DefaultModuleFileSystem.Builder();

// dependencies
builder.pathResolver(pathResolver);
builder.languageFileFilters(languageFileFilters);

// 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.sourceCharset(guessCharset(settings));
builder.workingDir(guessWorkingDir(module, tempDirectories));
initBinaryDirs(module, pathResolver, builder);
initSources(module, pathResolver, builder);
initTests(module, pathResolver, builder);

// file filters
initPluginFilters(builder, pluginFileFilters);
initSourceInclusions(builder, settings);
initTestInclusions(builder, settings);

singleton = builder.build();
}
return singleton;
}

private File guessWorkingDir(ProjectDefinition module, TempDirectories tempDirectories) {
File workDir = module.getWorkDir();
if (workDir == null) {
workDir = tempDirectories.getDir("work");
LOG.warn("Working dir is not set. Using: " + workDir.getAbsolutePath());
} else {
LOG.warn("Working dir: " + workDir.getAbsolutePath());
try {
FileUtils.forceMkdir(workDir);
} catch (Exception e) {
throw new FailToCreateFileException("Fail to create working dir: " + workDir.getAbsolutePath(), e);
}
}
return workDir;
}

private Charset guessCharset(Settings settings) {
final Charset charset;
String encoding = settings.getString(CoreProperties.ENCODING_PROPERTY);
if (StringUtils.isNotEmpty(encoding)) {
charset = Charset.forName(StringUtils.trim(encoding));
LOG.info("Source encoding: " + charset.displayName() + ", default locale: " + Locale.getDefault());
} else {
charset = Charset.defaultCharset();
LOG.warn("Source encoding is platform dependent (" + charset.displayName() + "), default locale: " + Locale.getDefault());
}
return charset;
}

private void initSources(ProjectDefinition module, PathResolver pathResolver, DefaultModuleFileSystem.Builder builder) {
for (String sourcePath : module.getSourceDirs()) {
builder.addSourceDir(pathResolver.relativeFile(module.getBaseDir(), sourcePath));
}
List<File> sourceFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getSourceFiles());
if (!sourceFiles.isEmpty()) {
builder.addFileFilter(new WhiteListFileFilter(FileFilter.FileType.SOURCE, ImmutableSet.copyOf(sourceFiles)));
}
}

private void initTests(ProjectDefinition module, PathResolver pathResolver, DefaultModuleFileSystem.Builder builder) {
for (String testPath : module.getTestDirs()) {
builder.addTestDir(pathResolver.relativeFile(module.getBaseDir(), testPath));
}
List<File> testFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getTestFiles());
if (!testFiles.isEmpty()) {
builder.addFileFilter(new WhiteListFileFilter(FileFilter.FileType.TEST, ImmutableSet.copyOf(testFiles)));
}
}

private void initPluginFilters(DefaultModuleFileSystem.Builder builder, FileFilter[] pluginFileFilters) {
for (FileFilter pluginFileFilter : pluginFileFilters) {
builder.addFileFilter(pluginFileFilter);
}
}

private void initSourceInclusions(DefaultModuleFileSystem.Builder builder, Settings settings) {
initInclusions(builder, settings, FileFilter.FileType.SOURCE,
CoreProperties.PROJECT_INCLUSIONS_PROPERTY, CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_EXCLUSIONS_PROPERTY);
}

private void initTestInclusions(DefaultModuleFileSystem.Builder builder, Settings settings) {
initInclusions(builder, settings, FileFilter.FileType.TEST,
CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY);
}

private static void initInclusions(DefaultModuleFileSystem.Builder builder, Settings settings, FileFilter.FileType fileType,
String inclusionsProperty, String globalExclusionsProperty, String exclusionsProperty) {
String[] inclusions = settings.getStringArray(inclusionsProperty);
for (String inclusion : inclusions) {
InclusionFileFilter filter = InclusionFileFilter.create(fileType, inclusion);
if (filter != null) {
builder.addFileFilter(filter);
}
}
String[] globalExclusions = settings.getStringArray(globalExclusionsProperty);
for (String globalExclusion : globalExclusions) {
builder.addFileFilter(new ExclusionFileFilter(fileType, globalExclusion));
}
String[] exclusions = settings.getStringArray(exclusionsProperty);
for (String exclusion : exclusions) {
builder.addFileFilter(new ExclusionFileFilter(fileType, exclusion));
}
}

private void initBinaryDirs(ProjectDefinition module, PathResolver pathResolver, DefaultModuleFileSystem.Builder builder) {
for (String path : module.getBinaries()) {
builder.addBinaryDir(pathResolver.relativeFile(module.getBaseDir(), path));
}
}
}

+ 74
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java View File

@@ -0,0 +1,74 @@
/*
* 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());
}
}

+ 42
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/WhiteListFileFilter.java View File

@@ -0,0 +1,42 @@
/*
* 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.sonar.api.scan.filesystem.FileFilter;

import java.io.File;
import java.util.Set;

/**
* @since 3.5
*/
class WhiteListFileFilter implements FileFilter {
private final FileFilter.FileType fileType;
private final Set<File> files;

WhiteListFileFilter(FileType fileType, Set<File> files) {
this.fileType = fileType;
this.files = files;
}

public boolean accept(File file, Context context) {
return !context.fileType().equals(fileType) || files.contains(file);
}
}

+ 27
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/package-info.java View File

@@ -0,0 +1,27 @@
/*
* 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
*/

/**
* This package is a part of bootstrap process, so we should take care about backward compatibility.
*/
@ParametersAreNonnullByDefault
package org.sonar.batch.scan.filesystem;

import javax.annotation.ParametersAreNonnullByDefault;

+ 187
- 0
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java View File

@@ -0,0 +1,187 @@
/*
* 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.filefilter.FileFilterUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
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 java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class DefaultModuleFileSystemTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void test_builder() throws IOException {
File basedir = temp.newFolder("base");
File workingDir = temp.newFolder("work");
PathResolver pathResolver = mock(PathResolver.class);
LanguageFileFilters languageFileFilters = mock(LanguageFileFilters.class);
FileFilter fileFilter = mock(FileFilter.class);

DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder()
.baseDir(basedir)
.workingDir(workingDir)
.addBinaryDir(new File(basedir, "target/classes"))
.addSourceDir(new File(basedir, "src/main/java"))
.addSourceDir(new File(basedir, "src/main/groovy"))
.addTestDir(new File(basedir, "src/test/java"))
.addFileFilter(fileFilter)
.sourceCharset(StandardCharsets.UTF_8)
.pathResolver(pathResolver)
.languageFileFilters(languageFileFilters)
.build();

assertThat(fileSystem).isNotNull();
assertThat(fileSystem.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath());
assertThat(fileSystem.workingDir().getCanonicalPath()).isEqualTo(workingDir.getCanonicalPath());
assertThat(fileSystem.sourceDirs()).hasSize(2);
assertThat(fileSystem.testDirs()).hasSize(1);
assertThat(fileSystem.binaryDirs()).hasSize(1);
assertThat(fileSystem.sourceCharset().name()).isEqualTo("UTF-8");
assertThat(fileSystem.pathResolver()).isSameAs(pathResolver);
assertThat(fileSystem.fileFilters()).containsOnly(fileFilter);
assertThat(fileSystem.languageFileFilters()).isSameAs(languageFileFilters);
}

@Test
public void should_exclude_dirs_starting_with_dot() throws IOException {
File basedir = new File("test-resources/DefaultModuleFileSystemTest/exclude_dir_starting_with_dot");
DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder()
.baseDir(basedir)
.sourceCharset(StandardCharsets.UTF_8)
.workingDir(temp.newFolder())
.addSourceDir(new File(basedir, "src"))
.build();

assertThat(fileSystem.sourceFiles()).hasSize(1);
assertThat(fileSystem.sourceFiles().get(0).getName()).isEqualTo("Included.java");
}

@Test
public void should_load_source_files_by_language() throws IOException {
File basedir = new File("test-resources/DefaultModuleFileSystemTest/main_and_test_files");
DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder()
.baseDir(basedir)
.sourceCharset(StandardCharsets.UTF_8)
.workingDir(temp.newFolder())
.addSourceDir(new File(basedir, "src/main/java"))
.addTestDir(new File(basedir, "src/test/java"))
.languageFileFilters(new LanguageFileFilters(new Languages(new Java(), new Php())))
.build();

List<File> files = fileSystem.sourceFilesOfLang("java");
assertThat(files).hasSize(2);
for (File sourceFiles : files) {
assertThat(sourceFiles).exists().isFile();
assertThat(sourceFiles.getName()).isIn("Hello.java", "Foo.java");
}
assertThat(fileSystem.sourceFilesOfLang("php")).isEmpty();
}

@Test
public void should_load_test_files() throws IOException {
File basedir = new File("test-resources/DefaultModuleFileSystemTest/main_and_test_files");
DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder()
.baseDir(basedir)
.sourceCharset(StandardCharsets.UTF_8)
.workingDir(temp.newFolder())
.addSourceDir(new File(basedir, "src/main/java"))
.addTestDir(new File(basedir, "src/test/java"))
.build();

assertThat(fileSystem.testDirs()).hasSize(1);
assertThat(fileSystem.testFiles()).hasSize(2);
for (File testFile : fileSystem.testFiles()) {
assertThat(testFile).exists().isFile();
assertThat(testFile.getName()).endsWith("Test.java");
}
}

@Test
public void should_load_test_files_by_language() throws IOException {
File basedir = new File("test-resources/DefaultModuleFileSystemTest/main_and_test_files");
DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder()
.baseDir(basedir)
.sourceCharset(StandardCharsets.UTF_8)
.workingDir(temp.newFolder())
.addSourceDir(new File(basedir, "src/main/java"))
.addTestDir(new File(basedir, "src/test/java"))
.languageFileFilters(new LanguageFileFilters(new Languages(new Java(), new Php())))
.build();

List<File> testFiles = fileSystem.testFilesOfLang("java");
assertThat(testFiles).hasSize(2);
for (File testFile : testFiles) {
assertThat(testFile).exists().isFile();
assertThat(testFile.getName()).endsWith("Test.java");
}
assertThat(fileSystem.testFilesOfLang("php")).isEmpty();
}

@Test
public void should_apply_file_filters() throws IOException {
File basedir = new File("test-resources/DefaultModuleFileSystemTest/main_and_test_files");
DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder()
.baseDir(basedir)
.sourceCharset(StandardCharsets.UTF_8)
.workingDir(temp.newFolder())
.addSourceDir(new File(basedir, "src/main/java"))
.addFileFilter(JavaIoFileFilter.create(FileFilterUtils.nameFileFilter("Foo.java")))
.pathResolver(new PathResolver())
.build();

List<File> files = fileSystem.sourceFiles();
assertThat(files).hasSize(1);
assertThat(files.get(0).getName()).isEqualTo("Foo.java");
}

static class Php extends AbstractLanguage {
public Php() {
super("php");
}

public String[] getFileSuffixes() {
return new String[]{"php"};
}
}

static class Java extends AbstractLanguage {
public Java() {
super("java");
}

public String[] getFileSuffixes() {
return new String[]{"java", "jav"};
}
}
}

+ 71
- 0
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFileFilterTest.java View File

@@ -0,0 +1,71 @@
/*
* 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.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.scan.filesystem.FileFilter;
import org.sonar.api.scan.filesystem.ModuleFileSystem;

import java.io.File;
import java.io.IOException;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class ExclusionFileFilterTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void should_accept() throws IOException {
ExclusionFileFilter filter = new ExclusionFileFilter(FileFilter.FileType.SOURCE, "**/*Dao.java");
File acceptedFile = temp.newFile("Foo.java");

FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE);
context.setFileRelativePath("com/mycompany/Foo.java");
assertThat(filter.accept(acceptedFile, context)).isTrue();

context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.TEST);
context.setFileRelativePath("com/mycompany/Foo.java");
assertThat(filter.accept(acceptedFile, context)).isTrue();
}

@Test
public void should_exclude() throws IOException {
ExclusionFileFilter filter = new ExclusionFileFilter(FileFilter.FileType.SOURCE, "**/*Dao.java");
File excludedFile = temp.newFile("FooDao.java");

FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE);
context.setFileRelativePath("com/mycompany/FooDao.java");
assertThat(filter.accept(excludedFile, context)).isFalse();

context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.TEST);
context.setFileRelativePath("com/mycompany/FooDao.java");
assertThat(filter.accept(excludedFile, context)).isTrue();
}

@Test
public void should_trim_pattern() throws IOException {
ExclusionFileFilter filter = new ExclusionFileFilter(FileFilter.FileType.SOURCE, " **/*Dao.java ");
assertThat(filter.pattern().toString()).isEqualTo("**/*Dao.java");
}
}

+ 76
- 0
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InclusionFileFilterTest.java View File

@@ -0,0 +1,76 @@
/*
* 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.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.scan.filesystem.FileFilter;
import org.sonar.api.scan.filesystem.ModuleFileSystem;

import java.io.File;
import java.io.IOException;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class InclusionFileFilterTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void should_accept() throws IOException {
InclusionFileFilter filter = InclusionFileFilter.create(FileFilter.FileType.SOURCE, "**/*Dao.java");
File acceptedFile = temp.newFile("FooDao.java");

FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE);
context.setFileRelativePath("com/mycompany/FooDao.java");
assertThat(filter.accept(acceptedFile, context)).isTrue();

context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.TEST);
context.setFileRelativePath("com/mycompany/Foo.java");
assertThat(filter.accept(acceptedFile, context)).isTrue();
}

@Test
public void should_exclude() throws IOException {
InclusionFileFilter filter = InclusionFileFilter.create(FileFilter.FileType.SOURCE, "**/*Dao.java");
File excludedFile = temp.newFile("Foo.java");

FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE);
context.setFileRelativePath("com/mycompany/Foo.java");
assertThat(filter.accept(excludedFile, context)).isFalse();

context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.TEST);
context.setFileRelativePath("com/mycompany/Foo.java");
assertThat(filter.accept(excludedFile, context)).isTrue();
}

@Test
public void should_trim_pattern() throws IOException {
InclusionFileFilter filter = InclusionFileFilter.create(FileFilter.FileType.SOURCE, " **/*Dao.java ");
assertThat(filter.pattern().toString()).isEqualTo("**/*Dao.java");
}

@Test
public void ignore_if_include_world() throws IOException {
assertThat(InclusionFileFilter.create(FileFilter.FileType.SOURCE, " **/* ")).isNull();
}
}

+ 75
- 0
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageFileFiltersTest.java View File

@@ -0,0 +1,75 @@
/*
* 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.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.junit.Test;
import org.sonar.api.resources.AbstractLanguage;
import org.sonar.api.resources.Languages;

import java.lang.reflect.Field;

import static org.fest.assertions.Assertions.assertThat;

public class LanguageFileFiltersTest {
@Test
public void forLang() throws Exception {
LanguageFileFilters filters = new LanguageFileFilters(new Languages(new Java(), new Php()));

IOFileFilter filter = filters.forLang("php");
assertThat(filter).isInstanceOf(SuffixFileFilter.class);
assertThat(suffixes((SuffixFileFilter) filter)).containsOnly("php");

filter = filters.forLang("java");
assertThat(filter).isInstanceOf(SuffixFileFilter.class);
assertThat(suffixes((SuffixFileFilter) filter)).containsOnly("java", "jav");

assertThat(filters.forLang("unknown")).isSameAs(TrueFileFilter.TRUE);
}

private String[] suffixes(SuffixFileFilter filter) throws Exception {
Field privateField = SuffixFileFilter.class.getDeclaredField("suffixes");
privateField.setAccessible(true);

return (String[]) privateField.get(filter);
}

static class Php extends AbstractLanguage {
public Php() {
super("php");
}

public String[] getFileSuffixes() {
return new String[]{"php"};
}
}

static class Java extends AbstractLanguage {
public Java() {
super("java");
}

public String[] getFileSuffixes() {
return new String[]{"java", "jav"};
}
}
}

+ 51
- 0
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProviderTest.java View File

@@ -0,0 +1,51 @@
/*
* 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.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
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.batch.bootstrap.TempDirectories;

import java.io.IOException;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class ModuleFileSystemProviderTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void test_provide() throws IOException {
ModuleFileSystemProvider provider = new ModuleFileSystemProvider();
ProjectDefinition module = ProjectDefinition.create()
.setBaseDir(temp.newFolder())
.setWorkDir(temp.newFolder());
ModuleFileSystem fs = provider.provide(module, new PathResolver(), new TempDirectories(), mock(LanguageFileFilters.class),
new Settings(), new FileFilter[0]);

assertThat(fs).isNotNull();
}
}

+ 88
- 0
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java View File

@@ -0,0 +1,88 @@
/*
* 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();
}
}

+ 54
- 0
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/WhiteListFileFilterTest.java View File

@@ -0,0 +1,54 @@
/*
* 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.Sets;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.scan.filesystem.FileFilter;
import org.sonar.api.scan.filesystem.ModuleFileSystem;

import java.io.File;
import java.io.IOException;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class WhiteListFileFilterTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void should_accept() throws IOException {
WhiteListFileFilter filter = new WhiteListFileFilter(FileFilter.FileType.SOURCE, Sets.newHashSet(
new File("Foo.java"),
new File("Bar.java")
));

FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE);
assertThat(filter.accept(new File("Foo.java"), context)).isTrue();
assertThat(filter.accept(new File("Other.java"), context)).isFalse();

context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.TEST);
assertThat(filter.accept(new File("Foo.java"), context)).isTrue();
assertThat(filter.accept(new File("Other.java"), context)).isTrue();
}
}

+ 1
- 0
sonar-batch/test-resources/DefaultModuleFileSystemTest/exclude_dir_starting_with_dot/src/org/.dirPrefixedWithDot/Excluded.java View File

@@ -0,0 +1 @@
public class Excluded2 {}

+ 1
- 0
sonar-batch/test-resources/DefaultModuleFileSystemTest/exclude_dir_starting_with_dot/src/org/.sonar/Excluded2.java View File

@@ -0,0 +1 @@
public class Excluded2 {}

+ 3
- 0
sonar-batch/test-resources/DefaultModuleFileSystemTest/exclude_dir_starting_with_dot/src/org/sonar/Included.java View File

@@ -0,0 +1,3 @@
package org.sonar;

public class Included {}

+ 1
- 0
sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/main/java/Foo.java View File

@@ -0,0 +1 @@
class Foo {}

+ 1
- 0
sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/main/java/Hello.java View File

@@ -0,0 +1 @@
public class Hello {}

+ 1
- 0
sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/test/java/FooTest.java View File

@@ -0,0 +1 @@
class FooTest {}

+ 1
- 0
sonar-batch/test-resources/DefaultModuleFileSystemTest/main_and_test_files/src/test/java/HelloTest.java View File

@@ -0,0 +1 @@
public class HelloTest {}

+ 2
- 0
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java View File

@@ -108,11 +108,13 @@ public interface CoreProperties {
String DYNAMIC_ANALYSIS_PROPERTY = "sonar.dynamicAnalysis";

/* Exclusions */
String PROJECT_INCLUSIONS_PROPERTY = "sonar.inclusions";
String PROJECT_EXCLUSIONS_PROPERTY = "sonar.exclusions";

/**
* @since 3.3
*/
String PROJECT_TEST_INCLUSIONS_PROPERTY = "sonar.test.inclusions";
String PROJECT_TEST_EXCLUSIONS_PROPERTY = "sonar.test.exclusions";
String GLOBAL_EXCLUSIONS_PROPERTY = "sonar.global.exclusions";
String GLOBAL_TEST_EXCLUSIONS_PROPERTY = "sonar.global.test.exclusions";

+ 5
- 3
sonar-plugin-api/src/main/java/org/sonar/api/batch/FileFilter.java View File

@@ -19,8 +19,10 @@
*/
package org.sonar.api.batch;

import org.sonar.api.BatchExtension;

public abstract class FileFilter implements java.io.FileFilter, BatchExtension {
import java.io.File;

public abstract class FileFilter implements java.io.FileFilter, org.sonar.api.scan.filesystem.FileFilter {
public final boolean accept(File file, org.sonar.api.scan.filesystem.FileFilter.Context context) {
return accept(file);
}
}

+ 1
- 1
sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java View File

@@ -220,7 +220,7 @@ public class DefaultProjectFileSystem implements ProjectFileSystem {
IOFileFilter suffixFilter = getFileSuffixFilter(langs);
WildcardPattern[] exclusionPatterns = WildcardPattern.create(patterns);

IOFileFilter initialFilesFilter = TrueFileFilter.INSTANCE;
IOFileFilter initialFilesFilter = TrueFileFilter.TRUE;
if (initialFiles != null && !initialFiles.isEmpty()) {
initialFilesFilter = new FileSelectionFilter(initialFiles);
}

+ 32
- 0
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FailToCreateFileException.java View File

@@ -0,0 +1,32 @@
/*
* 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);
}
}

+ 44
- 0
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileFilter.java View File

@@ -0,0 +1,44 @@
/*
* 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;
import org.sonar.api.BatchExtension;

import java.io.File;

/**
* @since 3.5
*/
@Beta
public interface FileFilter extends BatchExtension {
enum FileType {
SOURCE, TEST
}

static interface Context {
ModuleFileSystem fileSystem();
FileType fileType();
File sourceDir();
String fileRelativePath();
}

boolean accept(File file, Context context);
}

+ 36
- 0
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileSystemException.java View File

@@ -0,0 +1,36 @@
/*
* 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 FileSystemException extends RuntimeException {
public FileSystemException(String message) {
super(message);
}

public FileSystemException(String message, Throwable cause) {
super(message, cause);
}
}

+ 37
- 0
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/IllegalPathException.java View File

@@ -0,0 +1,37 @@
/*
* 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 IllegalPathException extends FileSystemException {

public IllegalPathException(String message) {
super(message);
}

public IllegalPathException(String message, Throwable cause) {
super(message, cause);
}
}

+ 44
- 0
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/JavaIoFileFilter.java View File

@@ -0,0 +1,44 @@
/*
* 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;

import java.io.File;

/**
* @since 3.5
*/
@Beta
public class JavaIoFileFilter implements FileFilter {
private java.io.FileFilter ioFilter;

private JavaIoFileFilter(java.io.FileFilter ioFilter) {
this.ioFilter = ioFilter;
}

public static JavaIoFileFilter create(java.io.FileFilter filter) {
return new JavaIoFileFilter(filter);
}

public boolean accept(File file, Context context) {
return ioFilter.accept(file);
}
}

+ 44
- 0
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java View File

@@ -0,0 +1,44 @@
/*
* 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;
import org.sonar.api.BatchComponent;

import java.io.File;
import java.nio.charset.Charset;
import java.util.List;

/**
* @since 3.5
*/
@Beta
public interface ModuleFileSystem extends BatchComponent {
File baseDir();
List<File> sourceDirs();
List<File> sourceFiles();
List<File> sourceFilesOfLang(String language);
List<File> testDirs();
List<File> testFiles();
List<File> testFilesOfLang(String language);
List<File> binaryDirs();
Charset sourceCharset();
File workingDir();
}

+ 27
- 0
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/package-info.java View File

@@ -0,0 +1,27 @@
/*
* 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
*/

/**
* This package is a part of bootstrap process, so we should take care about backward compatibility.
*/
@ParametersAreNonnullByDefault
package org.sonar.api.scan.filesystem;

import javax.annotation.ParametersAreNonnullByDefault;

Loading…
Cancel
Save