import org.sonar.api.resources.Project;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.index.ComponentDataCache;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.core.DryRunIncompatible;
import org.sonar.core.source.SnapshotDataTypes;
@DryRunIncompatible
public final class FileHashSensor implements Sensor {
- private final InputFileCache fileCache;
+ private final InputPathCache fileCache;
private final ComponentDataCache componentDataCache;
- public FileHashSensor(InputFileCache fileCache, ComponentDataCache componentDataCache) {
+ public FileHashSensor(InputPathCache fileCache, ComponentDataCache componentDataCache) {
this.fileCache = fileCache;
this.componentDataCache = componentDataCache;
}
@Override
public void analyse(Project project, SensorContext context) {
Map<String, String> map = Maps.newHashMap();
- for (InputFile inputFile : fileCache.byModule(project.key())) {
+ for (InputFile inputFile : fileCache.filesByModule(project.key())) {
String hash = ((DeprecatedDefaultInputFile) inputFile).hash();
if (hash != null) {
map.put(inputFile.relativePath(), hash);
import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.ComponentDataCache;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.core.source.SnapshotDataTypes;
import java.util.Collections;
public ExpectedException thrown = ExpectedException.none();
Project project = new Project("struts");
- InputFileCache fileCache = mock(InputFileCache.class);
+ InputPathCache fileCache = mock(InputPathCache.class);
ComponentDataCache componentDataCache = mock(ComponentDataCache.class);
FileHashSensor sensor = new FileHashSensor(fileCache, componentDataCache);
@Test
public void store_file_hashes() throws Exception {
- when(fileCache.byModule("struts")).thenReturn(Lists.<InputFile>newArrayList(
+ when(fileCache.filesByModule("struts")).thenReturn(Lists.<InputFile>newArrayList(
new DeprecatedDefaultInputFile("src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
new DeprecatedDefaultInputFile("src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
@Test
public void store_file_hashes_for_branches() throws Exception {
project = new Project("struts", "branch-2.x", "Struts 2.x");
- when(fileCache.byModule("struts:branch-2.x")).thenReturn(Lists.<InputFile>newArrayList(
+ when(fileCache.filesByModule("struts:branch-2.x")).thenReturn(Lists.<InputFile>newArrayList(
new DeprecatedDefaultInputFile("src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
new DeprecatedDefaultInputFile("src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
@Test
public void dont_save_hashes_if_no_files() throws Exception {
- when(fileCache.byModule("struts")).thenReturn(Collections.<InputFile>emptyList());
+ when(fileCache.filesByModule("struts")).thenReturn(Collections.<InputFile>emptyList());
SensorContext sensorContext = mock(SensorContext.class);
sensor.analyse(project, sensorContext);
import org.sonar.batch.protocol.input.ProjectReferentials;
import org.sonar.batch.referential.GlobalReferentialsLoader;
import org.sonar.batch.referential.ProjectReferentialsLoader;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan2.AnalyzerIssueCache;
import org.sonar.batch.scan2.AnalyzerMeasureCache;
import org.sonar.batch.scan2.ProjectScanContainer;
measures.add(measure);
}
- InputFileCache inputFileCache = container.getComponentByType(InputFileCache.class);
+ InputPathCache inputFileCache = container.getComponentByType(InputPathCache.class);
for (InputFile inputFile : inputFileCache.all()) {
inputFiles.add(inputFile);
}
import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
import org.sonar.batch.referential.ProjectReferentialsProvider;
import org.sonar.batch.rule.RulesProvider;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
import org.sonar.batch.scan.measure.MeasureCache;
DefaultUserFinder.class,
// file system
- InputFileCache.class,
+ InputPathCache.class,
PathResolver.class,
// issues
import java.util.concurrent.Future;
/**
- * Index input files into {@link InputFileCache}.
+ * Index input files into {@link InputPathCache}.
*/
public class FileIndexer implements BatchComponent {
private static final IOFileFilter FILE_FILTER = HiddenFileFilter.VISIBLE;
private final List<InputFileFilter> filters;
- private final InputFileCache fileCache;
+ private final InputPathCache fileCache;
private final boolean isAggregator;
private final ExclusionFilters exclusionFilters;
private final InputFileBuilderFactory inputFileBuilderFactory;
public FileIndexer(List<InputFileFilter> filters, ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory,
- InputFileCache cache, ProjectDefinition def) {
+ InputPathCache cache, ProjectDefinition def) {
this(filters, exclusionFilters, inputFileBuilderFactory, cache, !def.getSubProjects().isEmpty());
}
private FileIndexer(List<InputFileFilter> filters, ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory,
- InputFileCache cache, boolean isAggregator) {
+ InputPathCache cache, boolean isAggregator) {
this.filters = filters;
this.exclusionFilters = exclusionFilters;
this.inputFileBuilderFactory = inputFileBuilderFactory;
LOG.info("Index files");
exclusionFilters.prepare();
- Progress progress = new Progress(fileCache.byModule(fileSystem.moduleKey()));
+ Progress progress = new Progress(fileCache.filesByModule(fileSystem.moduleKey()));
InputFileBuilder inputFileBuilder = inputFileBuilderFactory.create(fileSystem);
indexFiles(fileSystem, progress, inputFileBuilder, fileSystem.sources(), InputFile.Type.MAIN);
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.batch.index.Cache;
-import org.sonar.batch.index.Caches;
-
-import javax.annotation.CheckForNull;
-
-/**
- * Cache of all files. This cache is shared amongst all project modules. Inclusion and
- * exclusion patterns are already applied.
- */
-public class InputFileCache implements BatchComponent {
-
- // [path type | module key | path] -> InputFile
- // For example:
- // [rel | struts-core | src/main/java/Action.java] -> InputFile
- // [rel | struts-core | src/main/java/Filter.java] -> InputFile
- // [abs | struts-core | /absolute/path/to/src/main/java/Action.java] -> InputFile
- // [abs | struts-core | /absolute/path/to/src/main/java/Filter.java] -> InputFile
- private final Cache<InputFile> cache;
-
- public InputFileCache(Caches caches) {
- cache = caches.createCache("inputFiles");
- }
-
- public Iterable<InputFile> all() {
- return cache.values();
- }
-
- public Iterable<InputFile> byModule(String moduleKey) {
- return cache.values(moduleKey);
- }
-
- public InputFileCache removeModule(String moduleKey) {
- cache.clear(moduleKey);
- return this;
- }
-
- public InputFileCache remove(String moduleKey, InputFile inputFile) {
- cache.remove(moduleKey, inputFile.relativePath());
- return this;
- }
-
- public InputFileCache put(String moduleKey, InputFile inputFile) {
- cache.put(moduleKey, inputFile.relativePath(), inputFile);
- return this;
- }
-
- @CheckForNull
- public InputFile get(String moduleKey, String relativePath) {
- return cache.get(moduleKey, relativePath);
- }
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.scan.filesystem;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputDir;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputPath;
+import org.sonar.batch.index.Cache;
+import org.sonar.batch.index.Caches;
+
+import javax.annotation.CheckForNull;
+
+/**
+ * Cache of all files. This cache is shared amongst all project modules. Inclusion and
+ * exclusion patterns are already applied.
+ */
+public class InputPathCache implements BatchComponent {
+
+ private static final String DIR = "DIR";
+ private static final String FILE = "FILE";
+ // [module key | type | path] -> InputPath
+ // For example:
+ // [struts-core | FILE | src/main/java/Action.java] -> InputFile
+ // [struts-core | FILE | src/main/java/Filter.java] -> InputFile
+ // [struts-core | DIR | src/main/java] -> InputDir
+ private final Cache<InputPath> cache;
+
+ public InputPathCache(Caches caches) {
+ cache = caches.createCache("inputFiles");
+ }
+
+ public Iterable<InputPath> all() {
+ return cache.values();
+ }
+
+ public Iterable<InputFile> filesByModule(String moduleKey) {
+ return (Iterable) cache.values(moduleKey, FILE);
+ }
+
+ public InputPathCache removeModule(String moduleKey) {
+ cache.clear(moduleKey);
+ return this;
+ }
+
+ public InputPathCache remove(String moduleKey, InputFile inputFile) {
+ cache.remove(moduleKey, FILE, inputFile.relativePath());
+ return this;
+ }
+
+ public InputPathCache put(String moduleKey, InputFile inputFile) {
+ cache.put(moduleKey, FILE, inputFile.relativePath(), inputFile);
+ return this;
+ }
+
+ @CheckForNull
+ public InputFile getFile(String moduleKey, String relativePath) {
+ return (InputFile) cache.get(moduleKey, FILE, relativePath);
+ }
+
+ public InputDir getDir(String moduleKey, String relativePath) {
+ return (InputDir) cache.get(moduleKey, DIR, relativePath);
+ }
+}
import org.sonar.api.BatchComponent;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.RelativePathPredicate;
-import org.sonar.api.resources.Project;
public class ModuleInputFileCache extends DefaultFileSystem.Cache implements BatchComponent {
private final String moduleKey;
- private final InputFileCache projectCache;
+ private final InputPathCache projectCache;
- public ModuleInputFileCache(Project module, ProjectDefinition projectDef, InputFileCache projectCache) {
- this.moduleKey = module.getKey();
- this.projectCache = projectCache;
- }
-
- /**
- * Used by scan2
- */
- public ModuleInputFileCache(ProjectDefinition projectDef, InputFileCache projectCache) {
- this.moduleKey = projectDef.getKey();
+ public ModuleInputFileCache(ProjectDefinition projectDef, InputPathCache projectCache) {
+ this.moduleKey = projectDef.getKeyWithBranch();
this.projectCache = projectCache;
}
@Override
protected Iterable<InputFile> inputFiles() {
- return projectCache.byModule(moduleKey);
+ return projectCache.filesByModule(moduleKey);
}
@Override
protected InputFile inputFile(RelativePathPredicate predicate) {
- return projectCache.get(moduleKey, predicate.path());
+ return projectCache.getFile(moduleKey, predicate.path());
+ }
+
+ @Override
+ protected InputDir inputDir(String relativePath) {
+ return projectCache.getDir(moduleKey, relativePath);
}
@Override
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
+import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.platform.Server;
import org.sonar.batch.events.BatchStepEvent;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
private final EventBus eventBus;
private final AnalysisMode analysisMode;
private final UserFinder userFinder;
- private final InputFileCache fileCache;
+ private final InputPathCache fileCache;
private final Project rootModule;
public JsonReport(Settings settings, FileSystem fileSystem, Server server, RuleFinder ruleFinder, IssueCache issueCache,
- EventBus eventBus, AnalysisMode analysisMode, UserFinder userFinder, Project rootModule, InputFileCache fileCache) {
+ EventBus eventBus, AnalysisMode analysisMode, UserFinder userFinder, Project rootModule, InputPathCache fileCache) {
this.settings = settings;
this.fileSystem = fileSystem;
this.server = server;
json.name("components").beginArray();
// Dump modules
writeJsonModuleComponents(json, rootModule);
- // TODO we need to dump directories
- for (InputFile inputFile : fileCache.all()) {
- String key = ((DeprecatedDefaultInputFile) inputFile).key();
- json
- .beginObject()
- .prop("key", key)
- .prop("path", inputFile.relativePath())
- .prop("moduleKey", StringUtils.substringBeforeLast(key, ":"))
- .prop("status", inputFile.status().name())
- .endObject();
+ for (InputPath inputPath : fileCache.all()) {
+ if (inputPath instanceof InputFile) {
+ InputFile inputFile = (InputFile) inputPath;
+ String key = ((DefaultInputFile) inputFile).key();
+ json
+ .beginObject()
+ .prop("key", key)
+ .prop("path", inputFile.relativePath())
+ .prop("moduleKey", StringUtils.substringBeforeLast(key, ":"))
+ .prop("status", inputFile.status().name())
+ .endObject();
+ } else {
+ InputDir inputDir = (InputDir) inputPath;
+ String key = ((DefaultInputDir) inputDir).key();
+ json
+ .beginObject()
+ .prop("key", key)
+ .prop("path", inputDir.relativePath())
+ .prop("moduleKey", StringUtils.substringBeforeLast(key, ":"))
+ .endObject();
+ }
+
}
json.endArray();
}
import org.sonar.api.measures.FileLinesContext;
import org.sonar.api.measures.FileLinesContextFactory;
import org.sonar.api.resources.Resource;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
public class DefaultFileLinesContextFactory implements FileLinesContextFactory {
private final AnalyzerMeasureCache measureCache;
private final MetricFinder metricFinder;
private final ProjectDefinition def;
- private InputFileCache fileCache;
+ private InputPathCache fileCache;
- public DefaultFileLinesContextFactory(InputFileCache fileCache, FileSystem fs, MetricFinder metricFinder, AnalyzerMeasureCache measureCache,
+ public DefaultFileLinesContextFactory(InputPathCache fileCache, FileSystem fs, MetricFinder metricFinder, AnalyzerMeasureCache measureCache,
ProjectDefinition def) {
this.fileCache = fileCache;
this.metricFinder = metricFinder;
@Override
public FileLinesContext createFor(InputFile inputFile) {
- if (fileCache.get(def.getKey(), inputFile.relativePath()) == null) {
+ if (fileCache.getFile(def.getKey(), inputFile.relativePath()) == null) {
throw new IllegalStateException("InputFile is not indexed: " + inputFile);
}
return new DefaultFileLinesContext(metricFinder, measureCache, def.getKey(), inputFile);
import org.sonar.batch.referential.ProjectReferentialsProvider;
import org.sonar.batch.scan.ProjectReactorBuilder;
import org.sonar.batch.scan.ProjectSettings;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
AnalyzerMeasureCache.class,
// file system
- InputFileCache.class,
+ InputPathCache.class,
PathResolver.class,
// issues
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
-import org.sonar.batch.index.Caches;
-import org.sonar.batch.index.CachesTest;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class InputFileCacheTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- Caches caches;
-
- @Before
- public void start() throws Exception {
- caches = CachesTest.createCacheOnTemp(temp);
- caches.start();
- }
-
- @After
- public void stop() {
- caches.stop();
- }
-
- @Test
- public void should_add_input_file() throws Exception {
- InputFileCache cache = new InputFileCache(caches);
- DefaultInputFile fooFile = new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile("Foo.java"));
- cache.put("struts", fooFile);
- cache.put("struts-core", new DeprecatedDefaultInputFile("src/main/java/Bar.java").setFile(temp.newFile("Bar.java")));
-
- assertThat(cache.get("struts", "src/main/java/Foo.java").relativePath())
- .isEqualTo("src/main/java/Foo.java");
-
- assertThat(cache.byModule("struts")).hasSize(1);
- assertThat(cache.byModule("struts-core")).hasSize(1);
- assertThat(cache.all()).hasSize(2);
- for (InputFile inputFile : cache.all()) {
- assertThat(inputFile.relativePath()).startsWith("src/main/java/");
- }
-
- cache.remove("struts", fooFile);
- assertThat(cache.all()).hasSize(1);
-
- cache.removeModule("struts");
- assertThat(cache.byModule("struts")).hasSize(0);
- assertThat(cache.byModule("struts-core")).hasSize(1);
- assertThat(cache.all()).hasSize(1);
- }
-
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.scan.filesystem;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
+import org.sonar.batch.index.Caches;
+import org.sonar.batch.index.CachesTest;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class InputPathCacheTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ Caches caches;
+
+ @Before
+ public void start() throws Exception {
+ caches = CachesTest.createCacheOnTemp(temp);
+ caches.start();
+ }
+
+ @After
+ public void stop() {
+ caches.stop();
+ }
+
+ @Test
+ public void should_add_input_file() throws Exception {
+ InputPathCache cache = new InputPathCache(caches);
+ DefaultInputFile fooFile = new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile("Foo.java"));
+ cache.put("struts", fooFile);
+ cache.put("struts-core", new DeprecatedDefaultInputFile("src/main/java/Bar.java").setFile(temp.newFile("Bar.java")));
+
+ assertThat(cache.getFile("struts", "src/main/java/Foo.java").relativePath())
+ .isEqualTo("src/main/java/Foo.java");
+
+ assertThat(cache.filesByModule("struts")).hasSize(1);
+ assertThat(cache.filesByModule("struts-core")).hasSize(1);
+ assertThat(cache.all()).hasSize(2);
+ for (InputFile inputFile : cache.all()) {
+ assertThat(inputFile.relativePath()).startsWith("src/main/java/");
+ }
+
+ cache.remove("struts", fooFile);
+ assertThat(cache.all()).hasSize(1);
+
+ cache.removeModule("struts");
+ assertThat(cache.filesByModule("struts")).hasSize(0);
+ assertThat(cache.filesByModule("struts-core")).hasSize(1);
+ assertThat(cache.all()).hasSize(1);
+ }
+
+}
import org.sonar.batch.bootstrap.AnalysisMode;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.scan.filesystem.InputFileCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.core.user.DefaultUser;
import java.io.File;
DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("src/main/java/org/apache/struts/Action.java");
inputFile.setKey("struts:src/main/java/org/apache/struts/Action.java");
inputFile.setStatus(InputFile.Status.CHANGED);
- InputFileCache fileCache = mock(InputFileCache.class);
+ InputPathCache fileCache = mock(InputPathCache.class);
when(fileCache.all()).thenReturn(Arrays.<InputFile>asList(inputFile));
Project rootModule = new Project("struts");
Project moduleA = new Project("struts-core");
@CheckForNull
InputFile inputFile(FilePredicate predicate);
+ /**
+ * Returns {@link InputDir} matching the current {@link File}.
+ * @return null if directory is not indexed.
+ * @throw {@link IllegalArgumentException} is File is null or not a directory.
+ *
+ * @since 4.5
+ */
+ @CheckForNull
+ InputDir inputDir(File dir);
+
/**
* Input files matching the given attributes. Return all the files if the parameter
* <code>attributes</code> is empty.
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import java.io.File;
+
+/**
+ * Layer over {@link java.io.File} for directories.
+ *
+ * @since 4.5
+ */
+public interface InputDir extends InputPath {
+
+ /**
+ * Path relative to module base directory. Path is unique and identifies directory
+ * within given <code>{@link FileSystem}</code>. File separator is the forward
+ * slash ('/'), even on Microsoft Windows.
+ * <p/>
+ * Returns <code>src/main/java/com</code> if module base dir is
+ * <code>/path/to/module</code> and if directory is
+ * <code>/path/to/module/src/main/java/com</code>.
+ * <p/>
+ * Relative path is not null and is normalized ('foo/../foo' is replaced by 'foo').
+ */
+ @Override
+ String relativePath();
+
+ /**
+ * Normalized absolute path. File separator is forward slash ('/'), even on Microsoft Windows.
+ * <p/>
+ * This is not canonical path. Symbolic links are not resolved. For example if /project/src links
+ * to /tmp/src and basedir is /project, then this method returns /project/src. Use
+ * {@code file().getCanonicalPath()} to resolve symbolic link.
+ */
+ @Override
+ String absolutePath();
+
+ /**
+ * The underlying absolute {@link java.io.File}
+ */
+ @Override
+ File file();
+
+}
package org.sonar.api.batch.fs;
import java.io.File;
-import java.io.Serializable;
/**
* This layer over {@link java.io.File} adds information for code analyzers.
*
* @since 4.2
*/
-public interface InputFile extends Serializable {
+public interface InputFile extends InputPath {
enum Type {
MAIN, TEST
* <p/>
* Relative path is not null and is normalized ('foo/../foo' is replaced by 'foo').
*/
+ @Override
String relativePath();
/**
* to /tmp/src and basedir is /project, then this method returns /project/src/index.php. Use
* {@code file().getCanonicalPath()} to resolve symbolic link.
*/
+ @Override
String absolutePath();
/**
* The underlying absolute {@link java.io.File}
*/
+ @Override
File file();
/**
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * Layer over {@link java.io.File} for files or directories.
+ *
+ * @since 4.5
+ */
+public interface InputPath extends Serializable {
+
+ /**
+ * @see InputFile#relativePath()
+ * @see InputDir#relativePath()
+ */
+ String relativePath();
+
+ /**
+ * @see InputFile#absolutePath()
+ * @see InputDir#absolutePath()
+ */
+ String absolutePath();
+
+ /**
+ * @see InputFile#file()
+ * @see InputDir#file()
+ */
+ File file();
+
+}
*/
package org.sonar.api.batch.fs.internal;
+import org.sonar.api.utils.PathUtils;
+
import com.google.common.base.Preconditions;
import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FilePredicates;
import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import javax.annotation.CheckForNull;
return result;
}
+ @Override
+ public InputDir inputDir(File dir) {
+ doPreloadFiles();
+ return cache.inputDir(PathUtils.sanitize(new RelativeP));
+ }
+
public static Collection<InputFile> filter(Iterable<InputFile> target, FilePredicate predicate) {
Collection<InputFile> result = new ArrayList<InputFile>();
for (InputFile element : target) {
@CheckForNull
protected abstract InputFile inputFile(RelativePathPredicate predicate);
+ @CheckForNull
+ protected abstract InputDir inputDir(String relativePath);
+
protected abstract void doAdd(InputFile inputFile);
final void add(InputFile inputFile) {
*/
private static class MapCache extends Cache {
private final Map<String, InputFile> fileMap = new HashMap<String, InputFile>();
+ private final Map<String, InputDir> dirMap = new HashMap<String, InputDir>();
@Override
public Iterable<InputFile> inputFiles() {
return fileMap.get(predicate.path());
}
+ @Override
+ protected InputDir inputDir(String relativePath) {
+ return dirMap.get(relativePath);
+ }
+
@Override
protected void doAdd(InputFile inputFile) {
fileMap.put(inputFile.relativePath(), inputFile);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.sonar.api.batch.fs.InputDir;
+import org.sonar.api.utils.PathUtils;
+
+import javax.annotation.CheckForNull;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * @since 4.5
+ */
+public class DefaultInputDir implements InputDir, Serializable {
+
+ private final String relativePath;
+ private String absolutePath;
+ private String key;
+
+ public DefaultInputDir(String relativePath) {
+ this.relativePath = PathUtils.sanitize(relativePath);
+ }
+
+ @Override
+ public String relativePath() {
+ return relativePath;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not call {@link #setFile(java.io.File)}
+ * previously.
+ */
+ @Override
+ @CheckForNull
+ public String absolutePath() {
+ return absolutePath;
+ }
+
+ @Override
+ public File file() {
+ if (absolutePath == null) {
+ throw new IllegalStateException("Can not return the java.io.File because absolute path is not set (see method setFile(java.io.File))");
+ }
+ return new File(absolutePath);
+ }
+
+ /**
+ * Component key. It's marked as nullable just for the unit tests that
+ * do not previously call {@link #setKey(String)}.
+ */
+ @CheckForNull
+ public String key() {
+ return key;
+ }
+
+ public DefaultInputDir setAbsolutePath(String s) {
+ this.absolutePath = PathUtils.sanitize(s);
+ return this;
+ }
+
+ public DefaultInputDir setFile(File file) {
+ setAbsolutePath(file.getAbsolutePath());
+ return this;
+ }
+
+ public DefaultInputDir setKey(String s) {
+ this.key = s;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DefaultInputDir)) {
+ return false;
+ }
+
+ DefaultInputDir that = (DefaultInputDir) o;
+ return relativePath.equals(that.relativePath);
+ }
+
+ @Override
+ public int hashCode() {
+ return relativePath.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "[relative=" + relativePath + ", abs=" + absolutePath + "]";
+ }
+}