]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8622 Lazily generate metadata for input files
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 11 Jan 2017 16:49:34 +0000 (17:49 +0100)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Fri, 27 Jan 2017 15:26:30 +0000 (16:26 +0100)
109 files changed:
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CpdTokenizerSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/XooTokenizerTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java
sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/IndexedFile.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputFilePredicate.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/FileHashes.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicates.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ExclusionFilters.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactory.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultHighlightable.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultSymbolizable.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/source/HighlightableBuilder.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/source/LinesSensor.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/source/SymbolizableBuilder.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/deprecated/JavaCpdBlockIndexerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuableFactoryTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ComponentIndexerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ExclusionFiltersTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactoryTest.java [deleted file]
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java [deleted file]
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputPathCacheTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/ConsoleReportTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorOptimizerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/coverage/CoverageExclusionsTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/source/CodeColorizersTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultHighlightableTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultSymbolizableTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DeprecatedDefaultSymbolTableTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/source/HighlightableBuilderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/source/SymbolizableBuilderTest.java

index 0b8c81f6c810f1fb02038aa4a9ad72ded50b1ba1..a5e7ccb92fc9c6bcbada6f592dce4ee47417a9c4 100644 (file)
@@ -27,7 +27,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 
@@ -60,7 +61,7 @@ public class ItCoverageSensorTest {
 
   @Test
   public void testNoExecutionIfNoCoverageFile() {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").build();
     context.fileSystem().add(inputFile);
     sensor.execute(context);
   }
@@ -69,7 +70,7 @@ public class ItCoverageSensorTest {
   public void testLineHitNoConditions() throws IOException {
     File coverage = new File(baseDir, "src/foo.xoo.itcoverage");
     FileUtils.write(coverage, "1:3\n\n#comment");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo").setLines(10);
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setModuleBaseDir(baseDir.toPath()).setLanguage("xoo").setLines(10).build();
     context.fileSystem().add(inputFile);
 
     sensor.execute(context);
@@ -81,7 +82,7 @@ public class ItCoverageSensorTest {
   public void testLineHitAndConditions() throws IOException {
     File coverage = new File(baseDir, "src/foo.xoo.itcoverage");
     FileUtils.write(coverage, "1:3:4:2");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo").setLines(10);
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setModuleBaseDir(baseDir.toPath()).setLanguage("xoo").setLines(10).build();
     context.fileSystem().add(inputFile);
 
     sensor.execute(context);
index 825760416e38685f784b44e9999960b31f89d75c..622553d96e2f6358a0ee30d3feff3bbbf9a7fdab 100644 (file)
@@ -27,7 +27,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 
@@ -60,7 +61,7 @@ public class OverallCoverageSensorTest {
 
   @Test
   public void testNoExecutionIfNoCoverageFile() {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
     context.fileSystem().add(inputFile);
     sensor.execute(context);
   }
@@ -69,7 +70,7 @@ public class OverallCoverageSensorTest {
   public void testLineHitNoConditions() throws IOException {
     File coverage = new File(baseDir, "src/foo.xoo.overallcoverage");
     FileUtils.write(coverage, "1:3\n\n#comment");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo").setLines(10);
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).setLines(10).build();
     context.fileSystem().add(inputFile);
 
     sensor.execute(context);
@@ -81,7 +82,7 @@ public class OverallCoverageSensorTest {
   public void testLineHitAndConditions() throws IOException {
     File coverage = new File(baseDir, "src/foo.xoo.overallcoverage");
     FileUtils.write(coverage, "1:3:4:2");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo").setLines(10);
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).setLines(10).build();
     context.fileSystem().add(inputFile);
 
     sensor.execute(context);
index 129e430f0c6f7472623bd53c5f2d96e0ef62fd84..744fbb7615109b5e71e31df16d5f001a183dcfe6 100644 (file)
@@ -27,7 +27,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 
@@ -60,7 +61,7 @@ public class UtCoverageSensorTest {
 
   @Test
   public void testNoExecutionIfNoCoverageFile() {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
     context.fileSystem().add(inputFile);
     sensor.execute(context);
   }
@@ -69,7 +70,7 @@ public class UtCoverageSensorTest {
   public void testLineHitNoConditions() throws IOException {
     File coverage = new File(baseDir, "src/foo.xoo.coverage");
     FileUtils.write(coverage, "1:3\n\n#comment");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo").setLines(10);
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).setLines(10).build();
     context.fileSystem().add(inputFile);
 
     sensor.execute(context);
@@ -81,7 +82,7 @@ public class UtCoverageSensorTest {
   public void testLineHitAndConditions() throws IOException {
     File coverage = new File(baseDir, "src/foo.xoo.coverage");
     FileUtils.write(coverage, "1:3:4:2");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo").setLines(10);
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).setLines(10).build();
     context.fileSystem().add(inputFile);
 
     sensor.execute(context);
index ff32959310627abc815e540f5298059cd3377ed7..b258916d8fa89d3aedfe967443f67da94dc01c14 100644 (file)
@@ -27,7 +27,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 
@@ -76,9 +77,11 @@ public class CpdTokenizerSensorTest {
   private void createSourceFile(String content) throws IOException {
     File sourceFile = new File(baseDir, "src/foo.xoo");
     FileUtils.write(sourceFile, content);
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo")
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo")
       .setLanguage("xoo")
-      .initMetadata(content);
+      .initMetadata(content)
+      .setModuleBaseDir(baseDir.toPath())
+      .build();
     context.fileSystem().add(inputFile);
   }
 
index cfd8be118eb7eda0a4cd30d4782b0535fe12b4b6..9a5649ef6889dac7b89a22b04b00410e90e97b99 100644 (file)
@@ -46,7 +46,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
@@ -86,7 +87,7 @@ public class MeasureSensorTest {
 
   @Test
   public void testNoExecutionIfNoMeasureFile() {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").build();
     context.fileSystem().add(inputFile);
     sensor.execute(context);
   }
@@ -95,7 +96,7 @@ public class MeasureSensorTest {
   public void testExecution() throws IOException {
     File measures = new File(baseDir, "src/foo.xoo.measures");
     FileUtils.write(measures, "ncloc:12\nbranch_coverage:5.3\nsqale_index:300\nbool:true\n\n#comment");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
     context.fileSystem().add(inputFile);
 
     Metric<Boolean> booleanMetric = new Metric.Builder("bool", "Bool", Metric.ValueType.BOOL)
@@ -118,7 +119,7 @@ public class MeasureSensorTest {
   public void failIfMetricNotFound() throws IOException {
     File measures = new File(baseDir, "src/foo.xoo.measures");
     FileUtils.write(measures, "unknow:12\n\n#comment");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
     context.fileSystem().add(inputFile);
 
     thrown.expect(IllegalStateException.class);
index f988760c5dbd8031c9eb2f4c53f1de4d88094cef..fc1040e31459db8d95821eff264a0ce5372b1ecd 100644 (file)
@@ -24,8 +24,9 @@ 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.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.component.ResourcePerspectives;
@@ -66,7 +67,7 @@ public class SymbolReferencesSensorTest {
 
   @Test
   public void testNoExecutionIfNoSymbolFile() {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
     fileSystem.add(inputFile);
     sensor.execute(context);
   }
@@ -75,7 +76,7 @@ public class SymbolReferencesSensorTest {
   public void testExecution() throws IOException {
     File symbol = new File(baseDir, "src/foo.xoo.symbol");
     FileUtils.write(symbol, "1:4,7\n12:15,23:33\n\n#comment");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
     fileSystem.add(inputFile);
     Symbolizable symbolizable = mock(Symbolizable.class);
     when(perspectives.as(Symbolizable.class, inputFile)).thenReturn(symbolizable);
index f46573a953498c990066cbf3f1080c4be01f15bf..0164f1a04f4823eab8444a5d58140f95bd565777 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 import org.sonar.api.component.ResourcePerspectives;
@@ -62,7 +63,10 @@ public class SyntaxHighlightingSensorTest {
 
   @Test
   public void testNoExecutionIfNoSyntaxFile() {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo")
+      .setLanguage("xoo")
+      .setModuleBaseDir(baseDir.toPath())
+      .build();
     context.fileSystem().add(inputFile);
     sensor.execute(context);
   }
@@ -71,8 +75,11 @@ public class SyntaxHighlightingSensorTest {
   public void testExecution() throws IOException {
     File symbol = new File(baseDir, "src/foo.xoo.highlighting");
     FileUtils.write(symbol, "1:4:k\n12:15:cppd\n\n#comment");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo")
-      .initMetadata(" xoo\nazertyazer\nfoo");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo")
+      .setLanguage("xoo")
+      .setModuleBaseDir(baseDir.toPath())
+      .initMetadata(" xoo\nazertyazer\nfoo")
+      .build();
     context.fileSystem().add(inputFile);
 
     Highlightable highlightable = mock(Highlightable.class);
index a5741a255f03f2309d0259a18d2306eb8c2970da..fb45788e5922692a9d8777cb60a77bbb1b389ce3 100644 (file)
@@ -29,6 +29,7 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.config.Settings;
 
@@ -63,7 +64,10 @@ public class XooTokenizerTest {
   public void testExecution() throws IOException {
     File source = new File(baseDir, "src/foo.xoo");
     FileUtils.write(source, "token1 token2 token3\ntoken4");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo")
+      .setLanguage("xoo")
+      .setModuleBaseDir(baseDir.toPath())
+      .build();
     fileSystem.add(inputFile);
 
     XooTokenizer tokenizer = new XooTokenizer(fileSystem);
index d39b66e80f9b89bd497c3c19f87b4c8359f59ad2..4810e5b5e16e13e816fc2f11bca88005ce585db3 100644 (file)
@@ -33,6 +33,7 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultTextPointer;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.error.AnalysisError;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 
@@ -65,10 +66,12 @@ public class AnalysisErrorSensorTest {
     createErrorFile(baseDir);
 
     int[] offsets = {10, 20, 30, 40};
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo")
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo")
       .setLanguage("xoo")
       .setOriginalLineOffsets(offsets)
-      .setLines(4);
+      .setModuleBaseDir(baseDir)
+      .setLines(4)
+      .build();
     context = SensorContextTester.create(baseDir);
     context.fileSystem().add(inputFile);
 
index 263eb23f62514702b523c258a1203a4d4d228d8b..e6fc184ce7f68c373be993def0bdb62cf107d92a 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.SonarQubeSide;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
@@ -51,8 +52,10 @@ public class OneIssuePerLineSensorTest {
 
   @Test
   public void testRule() throws IOException {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY)
-      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.xoo")
+      .setLanguage(Xoo.KEY)
+      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n")
+      .build();
 
     SensorContextTester context = SensorContextTester.create(temp.newFolder());
     context.fileSystem().add(inputFile);
@@ -66,8 +69,10 @@ public class OneIssuePerLineSensorTest {
 
   @Test
   public void testForceSeverity() throws IOException {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY)
-      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.xoo")
+      .setLanguage(Xoo.KEY)
+      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n")
+      .build();
 
     SensorContextTester context = SensorContextTester.create(temp.newFolder());
     context.fileSystem().add(inputFile);
@@ -83,8 +88,10 @@ public class OneIssuePerLineSensorTest {
 
   @Test
   public void testProvideGap() throws IOException {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY)
-      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.xoo")
+      .setLanguage(Xoo.KEY)
+      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n")
+      .build();
 
     SensorContextTester context = SensorContextTester.create(temp.newFolder());
     context.fileSystem().add(inputFile);
@@ -100,8 +107,10 @@ public class OneIssuePerLineSensorTest {
 
   @Test
   public void testProvideGap_before_5_5() throws IOException {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY)
-      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.xoo")
+      .setLanguage(Xoo.KEY)
+      .initMetadata("a\nb\nc\nd\ne\nf\ng\nh\ni\n")
+      .build();
 
     SensorContextTester context = SensorContextTester.create(temp.newFolder());
     context.fileSystem().add(inputFile);
index 67b5cff3891480c87b1d9afbd142dc688d25cd68..f7930896fb89b732bbbd9d4e160f8d7a3215ec76 100644 (file)
@@ -28,6 +28,7 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.scm.BlameCommand.BlameInput;
 import org.sonar.api.batch.scm.BlameCommand.BlameOutput;
 import org.sonar.api.batch.scm.BlameLine;
@@ -68,7 +69,10 @@ public class XooBlameCommandTest {
     FileUtils.write(source, "sample content");
     File scm = new File(baseDir, "src/foo.xoo.scm");
     FileUtils.write(scm, "123,julien,2014-12-12\n234,julien,2014-12-24");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage(Xoo.KEY);
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo")
+      .setLanguage(Xoo.KEY)
+      .setModuleBaseDir(baseDir.toPath())
+      .build();
     fs.add(inputFile);
 
     BlameOutput result = mock(BlameOutput.class);
index e9818a55d3748ff4135a976286db1c418fde95ac..7e206f8053a126a746a0716b36feb3a003539ff3 100644 (file)
@@ -23,11 +23,12 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.resources.Directory;
 import org.sonar.api.resources.Project;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class ComponentKeysTest {
   @Rule
@@ -41,7 +42,8 @@ public class ComponentKeysTest {
     Directory dir = Directory.create("src/org/foo");
     assertThat(ComponentKeys.createEffectiveKey(project, dir)).isEqualTo("my_project:src/org/foo");
 
-    InputFile file = new DefaultInputFile("foo", "foo/Bar.php");
+    InputFile file = mock(InputFile.class);
+    when(file.relativePath()).thenReturn("foo/Bar.php");
     assertThat(ComponentKeys.createEffectiveKey("my_project", file)).isEqualTo("my_project:foo/Bar.php");
   }
 
index 4007b74d145df2b00ba66ec31cc7626bb592c9c8..045b2fd5319ed5ea7a4865a3a0311b5c05954cea 100644 (file)
@@ -29,6 +29,6 @@ public interface FilePredicate {
   /**
    * Test if provided file is valid for this predicate
    */
-  boolean apply(InputFile inputFile);
+  boolean apply(IndexedFile inputFile);
 
 }
index 33b22cb44023d6a665008f0280c3c8a846bbdc50..72614539fad84ebc0e50114129158de6d689a068 100644 (file)
@@ -108,8 +108,6 @@ public interface FilePredicates {
 
   FilePredicate hasLanguages(String... languages);
 
-  FilePredicate hasStatus(InputFile.Status status);
-
   FilePredicate hasType(InputFile.Type type);
 
   FilePredicate not(FilePredicate p);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/IndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/IndexedFile.java
new file mode 100644 (file)
index 0000000..8938159
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import javax.annotation.CheckForNull;
+
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputPath;
+
+/**
+ * @since 6.3 
+ */
+public interface IndexedFile extends InputPath {
+  /**
+   * Path relative to module base directory. Path is unique and identifies file
+   * within given <code>{@link FileSystem}</code>. File separator is the forward
+   * slash ('/'), even on Microsoft Windows.
+   * <br>
+   * Returns <code>src/main/java/com/Foo.java</code> if module base dir is
+   * <code>/path/to/module</code> and if file is
+   * <code>/path/to/module/src/main/java/com/Foo.java</code>.
+   * <br>
+   * 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.
+   * <br>
+   * 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/index.php. Use
+   * {@code file().getCanonicalPath()} to resolve symbolic link.
+   */
+  @Override
+  String absolutePath();
+
+  /**
+   * The underlying absolute {@link java.io.File}. It should not be used to read the file in the filesystem.
+   * @see #contents()
+   * @see #inputStream()
+   */
+  @Override
+  File file();
+
+  /**
+   * The underlying absolute {@link Path}.
+   * It should not be used to read the file in the filesystem.
+   * @see #contents()
+   * @see #inputStream()
+   * @since 5.1
+   */
+  @Override
+  Path path();
+
+  /**
+   * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file.
+   */
+  @CheckForNull
+  String language();
+
+  /**
+   * Does it contain main or test code ?
+   */
+  InputFile.Type type();
+
+  /**
+   * Creates a stream of the file's contents. Depending on the runtime context, the source might be a file in a physical or virtual filesystem.
+   * Typically, it won't be buffered. <b>The stream must be closed by the caller</b>.
+   * Note that there is a default implementation.
+   * @since 6.2
+   */
+  default InputStream inputStream() throws IOException {
+    return Files.newInputStream(path());
+  }
+}
index 923575d7fee5fdefb9985c16562ce074d4eccb0d..299fc0064063caac875ec29fc5cc02e3d255f895 100644 (file)
@@ -41,7 +41,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
  *
  * @since 4.2
  */
-public interface InputFile extends InputPath {
+public interface InputFile extends IndexedFile, InputPath {
 
   enum Type {
     MAIN, TEST
@@ -100,11 +100,13 @@ public interface InputFile extends InputPath {
    * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file.
    */
   @CheckForNull
+  @Override
   String language();
 
   /**
    * Does it contain main or test code ?
    */
+  @Override
   Type type();
 
   /**
@@ -113,6 +115,7 @@ public interface InputFile extends InputPath {
    * Note that there is a default implementation.
    * @since 6.2
    */
+  @Override
   default InputStream inputStream() throws IOException {
     return Files.newInputStream(path());
   }
index 740e8dd68cc96a1225b6bbc4cb8f60b3a24786d6..49f0654a797a9b4957d04004471ec6b1c085cf5c 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.batch.ScannerSide;
  */
 @ScannerSide
 @ExtensionPoint
+@FunctionalInterface
 public interface InputFileFilter {
 
   boolean accept(InputFile f);
index 2e5362c194330c0ee63ac62d6331db5c8a7a926e..b6e549d28ada27142aeafbd5700e4c8433194b8f 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.api.batch.fs.internal;
 
 import org.sonar.api.batch.fs.FileSystem.Index;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.utils.PathUtils;
@@ -43,7 +44,7 @@ class AbsolutePathPredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     return path.equals(f.absolutePath());
   }
 
index e7afc7600a33797c0e8d4147d8119066aedcb821..e000fd1a1b67f6013090a8c9635221fadb36048a 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.api.batch.fs.internal;
 import com.google.common.annotations.VisibleForTesting;
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FileSystem.Index;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 
 import java.util.ArrayList;
@@ -60,7 +61,7 @@ class AndPredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     for (OptimizedFilePredicate predicate : predicates) {
       if (!predicate.apply(f)) {
         return false;
index b0b384c004d62788f79607c47aaf954590ec6071..864fde37b8e495f1a1c8a3518a115fc07dbe7fe6 100644 (file)
@@ -145,11 +145,6 @@ public class DefaultFilePredicates implements FilePredicates {
     return or(list);
   }
 
-  @Override
-  public FilePredicate hasStatus(InputFile.Status status) {
-    return new StatusPredicate(status);
-  }
-
   @Override
   public FilePredicate hasType(InputFile.Type type) {
     return new TypePredicate(type);
index c7339ed1b2be833196d9d8317af27433435afb36..b6a8d3aaa7ed603a9dd73f8b503ece33fa877513 100644 (file)
@@ -32,6 +32,8 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import java.util.stream.StreamSupport;
+
 import javax.annotation.Nullable;
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FilePredicates;
@@ -52,7 +54,7 @@ public class DefaultFileSystem implements FileSystem {
   private Path workDir;
   private Charset encoding;
   protected final FilePredicates predicates;
-  private FilePredicate defaultPredicate;
+  private InputFilePredicate defaultPredicate;
 
   /**
    * Only for testing
@@ -107,7 +109,7 @@ public class DefaultFileSystem implements FileSystem {
     return this;
   }
 
-  public DefaultFileSystem setDefaultPredicate(@Nullable FilePredicate predicate) {
+  public DefaultFileSystem setDefaultPredicate(@Nullable InputFilePredicate predicate) {
     this.defaultPredicate = predicate;
     return this;
   }
@@ -155,11 +157,12 @@ public class DefaultFileSystem implements FileSystem {
   @Override
   public Iterable<InputFile> inputFiles(FilePredicate predicate) {
     doPreloadFiles();
-    FilePredicate combinedPredicate = predicate;
+    Iterable<InputFile> iterable = OptimizedFilePredicateAdapter.create(predicate).get(cache);
     if (defaultPredicate != null) {
-      combinedPredicate = predicates().and(defaultPredicate, predicate);
+      return StreamSupport.stream(iterable.spliterator(), false)
+        .filter(defaultPredicate::apply)::iterator;
     }
-    return OptimizedFilePredicateAdapter.create(combinedPredicate).get(cache);
+    return iterable;
   }
 
   @Override
@@ -183,15 +186,7 @@ public class DefaultFileSystem implements FileSystem {
     return cache.inputDir(relativePath);
   }
 
-  /**
-   * Adds InputFile to the list and registers its language, if present.
-   * Synchronized because PersistIt Exchange is not concurrent
-   */
-  public synchronized DefaultFileSystem add(DefaultInputFile inputFile) {
-    if (this.baseDir == null) {
-      throw new IllegalStateException("Please set basedir on filesystem before adding files");
-    }
-    inputFile.setModuleBaseDir(this.baseDir);
+  public DefaultFileSystem add(InputFile inputFile) {
     cache.add(inputFile);
     String language = inputFile.language();
     if (language != null) {
@@ -200,22 +195,14 @@ public class DefaultFileSystem implements FileSystem {
     return this;
   }
 
-  /**
-   * Adds InputDir to the list.
-   * Synchronized because PersistIt Exchange is not concurrent
-   */
-  public synchronized DefaultFileSystem add(DefaultInputDir inputDir) {
-    if (this.baseDir == null) {
-      throw new IllegalStateException("Please set basedir on filesystem before adding dirs");
-    }
-    inputDir.setModuleBaseDir(this.baseDir);
+  public DefaultFileSystem add(DefaultInputDir inputDir) {
     cache.add(inputDir);
     return this;
   }
 
   /**
    * Adds a language to the list. To be used only for unit tests that need to use {@link #languages()} without
-   * using {@link #add(DefaultInputFile)}.
+   * using {@link #add(InputFile)}.
    */
   public DefaultFileSystem addLanguages(String language, String... others) {
     languages.add(language);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java
new file mode 100644 (file)
index 0000000..e3a1107
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 java.io.File;
+import java.nio.file.Path;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.utils.PathUtils;
+
+public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile {
+  private final String relativePath;
+  private final String moduleKey;
+  private final Path moduleBaseDir;
+  private String language;
+  private final Type type;
+
+  public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath) {
+    this(moduleKey, moduleBaseDir, relativePath, Type.MAIN);
+  }
+
+  public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath, Type type) {
+    this.moduleKey = moduleKey;
+    this.relativePath = PathUtils.sanitize(relativePath);
+    this.moduleBaseDir = moduleBaseDir.normalize();
+    this.type = type;
+  }
+
+  public DefaultIndexedFile setLanguage(@Nullable String language) {
+    this.language = language;
+    return this;
+  }
+
+  @Override
+  public String relativePath() {
+    return relativePath;
+  }
+
+  @Override
+  public String absolutePath() {
+    return PathUtils.sanitize(path().toString());
+  }
+
+  @Override
+  public File file() {
+    return path().toFile();
+  }
+
+  @Override
+  public Path path() {
+    return moduleBaseDir.resolve(relativePath);
+  }
+
+  @CheckForNull
+  @Override
+  public String language() {
+    return language;
+  }
+
+  @Override
+  public Type type() {
+    return type;
+  }
+
+  /**
+   * Component key.
+   */
+  @Override
+  public String key() {
+    return new StringBuilder().append(moduleKey).append(":").append(relativePath).toString();
+  }
+
+  public String moduleKey() {
+    return moduleKey;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+
+    if (!(o instanceof DefaultIndexedFile)) {
+      return false;
+    }
+
+    DefaultIndexedFile that = (DefaultIndexedFile) o;
+    return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath);
+  }
+
+  @Override
+  public int hashCode() {
+    return moduleKey.hashCode() + relativePath.hashCode() * 13;
+  }
+
+  @Override
+  public String toString() {
+    return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", basedir=" + moduleBaseDir + "]";
+  }
+
+  @Override
+  public boolean isFile() {
+    return true;
+  }
+}
index a3d4de2865433c1218b1926f3334e7147d838cde..b6c644e9cb629e8753b2cac9bc26776d79aed85f 100644 (file)
@@ -21,91 +21,67 @@ package org.sonar.api.batch.fs.internal;
 
 import com.google.common.base.Preconditions;
 import java.io.File;
-import java.io.StringReader;
 import java.nio.charset.Charset;
 import java.nio.file.Path;
 import java.util.Arrays;
+import java.util.function.Function;
+
 import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextPointer;
 import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.FileMetadata.Metadata;
-import org.sonar.api.utils.PathUtils;
 
 /**
  * @since 4.2
  */
 public class DefaultInputFile extends DefaultInputComponent implements InputFile {
-
-  private final String relativePath;
-  private final String moduleKey;
-  private Path moduleBaseDir;
-  private String language;
-  private Type type = Type.MAIN;
+  private final DefaultIndexedFile indexedFile;
+  private final Function<DefaultInputFile, Metadata> metadataGenerator;
   private Status status;
-  private int lines = -1;
   private Charset charset;
-  private int lastValidOffset = -1;
-  private String hash;
-  private int nonBlankLines;
-  private int[] originalLineOffsets;
+  private Metadata metadata;
 
-  public DefaultInputFile(String moduleKey, String relativePath) {
-    this.moduleKey = moduleKey;
-    this.relativePath = PathUtils.sanitize(relativePath);
+  public DefaultInputFile(DefaultIndexedFile indexedFile, Function<DefaultInputFile, Metadata> metadataGenerator) {
+    this.indexedFile = indexedFile;
+    this.metadataGenerator = metadataGenerator;
+    this.metadata = null;
+  }
+
+  private void checkMetadata() {
+    if (metadata == null) {
+      setMetadata(metadataGenerator.apply(this));
+    }
   }
 
   @Override
   public String relativePath() {
-    return relativePath;
+    return indexedFile.relativePath();
   }
 
   @Override
   public String absolutePath() {
-    return PathUtils.sanitize(path().toString());
+    return indexedFile.absolutePath();
   }
 
   @Override
   public File file() {
-    return path().toFile();
+    return indexedFile.file();
   }
 
   @Override
   public Path path() {
-    if (moduleBaseDir == null) {
-      throw new IllegalStateException("Can not return the java.nio.file.Path because module baseDir is not set (see method setModuleBaseDir(java.io.File))");
-    }
-    return moduleBaseDir.resolve(relativePath);
+    return indexedFile.path();
   }
 
   @CheckForNull
   @Override
   public String language() {
-    return language;
+    return indexedFile.language();
   }
 
   @Override
   public Type type() {
-    return type;
-  }
-
-  /**
-   * {@link #setStatus(org.sonar.api.batch.fs.InputFile.Status)}
-   */
-  @Override
-  public Status status() {
-    return status;
-  }
-
-  @Override
-  public int lines() {
-    return lines;
-  }
-
-  @Override
-  public boolean isEmpty() {
-    return lastValidOffset == 0;
+    return indexedFile.type();
   }
 
   /**
@@ -113,119 +89,88 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
    */
   @Override
   public String key() {
-    return new StringBuilder().append(moduleKey).append(":").append(relativePath).toString();
+    return indexedFile.key();
   }
 
   public String moduleKey() {
-    return moduleKey;
+    return indexedFile.moduleKey();
   }
 
   @Override
-  public Charset charset() {
-    return charset;
-  }
-
-  /**
-   * For testing purpose. Will be automaticall set when file is added to {@link DefaultFileSystem}
-   */
-  public DefaultInputFile setModuleBaseDir(Path moduleBaseDir) {
-    this.moduleBaseDir = moduleBaseDir.normalize();
-    return this;
+  public int hashCode() {
+    return indexedFile.hashCode();
   }
 
-  public DefaultInputFile setLanguage(@Nullable String language) {
-    this.language = language;
-    return this;
+  @Override
+  public String toString() {
+    return indexedFile.toString();
   }
 
-  public DefaultInputFile setType(Type type) {
-    this.type = type;
-    return this;
+  /**
+   * {@link #setStatus(org.sonar.api.batch.fs.InputFile.Status)}
+   */
+  @Override
+  public Status status() {
+    checkMetadata();
+    return status;
   }
 
-  public DefaultInputFile setStatus(Status status) {
-    this.status = status;
-    return this;
+  @Override
+  public int lines() {
+    checkMetadata();
+    return metadata.lines();
   }
 
-  public DefaultInputFile setLines(int lines) {
-    this.lines = lines;
-    return this;
+  @Override
+  public boolean isEmpty() {
+    checkMetadata();
+    return metadata.lastValidOffset() == 0;
   }
 
-  public DefaultInputFile setCharset(Charset charset) {
-    this.charset = charset;
-    return this;
+  @Override
+  public Charset charset() {
+    checkMetadata();
+    return charset;
   }
 
   public int lastValidOffset() {
-    Preconditions.checkState(lastValidOffset >= 0, "InputFile is not properly initialized. Please set 'lastValidOffset' property.");
-    return lastValidOffset;
-  }
-
-  public DefaultInputFile setLastValidOffset(int lastValidOffset) {
-    this.lastValidOffset = lastValidOffset;
-    return this;
+    checkMetadata();
+    Preconditions.checkState(metadata.lastValidOffset() >= 0, "InputFile is not properly initialized.");
+    return metadata.lastValidOffset();
   }
 
   /**
    * Digest hash of the file.
    */
   public String hash() {
-    return hash;
+    checkMetadata();
+    return metadata.hash();
   }
 
   public int nonBlankLines() {
-    return nonBlankLines;
+    checkMetadata();
+    return metadata.nonBlankLines();
   }
 
   public int[] originalLineOffsets() {
-    Preconditions.checkState(originalLineOffsets != null, "InputFile is not properly initialized. Please set 'originalLineOffsets' property.");
-    Preconditions.checkState(originalLineOffsets.length == lines, "InputFile is not properly initialized. 'originalLineOffsets' property length should be equal to 'lines'");
-    return originalLineOffsets;
-  }
-
-  public DefaultInputFile setHash(String hash) {
-    this.hash = hash;
-    return this;
-  }
-
-  public DefaultInputFile setNonBlankLines(int nonBlankLines) {
-    this.nonBlankLines = nonBlankLines;
-    return this;
-  }
-
-  public DefaultInputFile setOriginalLineOffsets(int[] originalLineOffsets) {
-    this.originalLineOffsets = originalLineOffsets;
-    return this;
+    checkMetadata();
+    Preconditions.checkState(metadata.originalLineOffsets() != null, "InputFile is not properly initialized.");
+    Preconditions.checkState(metadata.originalLineOffsets().length == metadata.lines(),
+      "InputFile is not properly initialized. 'originalLineOffsets' property length should be equal to 'lines'");
+    return metadata.originalLineOffsets();
   }
 
   @Override
   public TextPointer newPointer(int line, int lineOffset) {
+    checkMetadata();
     DefaultTextPointer textPointer = new DefaultTextPointer(line, lineOffset);
     checkValid(textPointer, "pointer");
     return textPointer;
   }
 
-  private void checkValid(TextPointer pointer, String owner) {
-    Preconditions.checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line());
-    Preconditions.checkArgument(pointer.line() <= this.lines, "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, lines);
-    Preconditions.checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset());
-    int lineLength = lineLength(pointer.line());
-    Preconditions.checkArgument(pointer.lineOffset() <= lineLength,
-      "%s is not a valid line offset for %s. File %s has %s character(s) at line %s", pointer.lineOffset(), owner, this, lineLength, pointer.line());
-  }
-
-  private int lineLength(int line) {
-    return lastValidGlobalOffsetForLine(line) - originalLineOffsets()[line - 1];
-  }
-
-  private int lastValidGlobalOffsetForLine(int line) {
-    return line < this.lines ? (originalLineOffsets()[line] - 1) : lastValidOffset();
-  }
-
   @Override
   public TextRange newRange(TextPointer start, TextPointer end) {
+    checkMetadata();
     checkValid(start, "start pointer");
     checkValid(end, "end pointer");
     return newRangeValidPointers(start, end, false);
@@ -233,6 +178,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
 
   @Override
   public TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset) {
+    checkMetadata();
     TextPointer start = newPointer(startLine, startLineOffset);
     TextPointer end = newPointer(endLine, endLineOffset);
     return newRangeValidPointers(start, end, false);
@@ -240,30 +186,28 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
 
   @Override
   public TextRange selectLine(int line) {
+    checkMetadata();
     TextPointer startPointer = newPointer(line, 0);
     TextPointer endPointer = newPointer(line, lineLength(line));
     return newRangeValidPointers(startPointer, endPointer, true);
   }
 
   public void validate(TextRange range) {
+    checkMetadata();
     checkValid(range.start(), "start pointer");
     checkValid(range.end(), "end pointer");
   }
 
-  private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) {
-    Preconditions.checkArgument(acceptEmptyRange ? (start.compareTo(end) <= 0) : (start.compareTo(end) < 0),
-      "Start pointer %s should be before end pointer %s", start, end);
-    return new DefaultTextRange(start, end);
-  }
-
   /**
    * Create Range from global offsets. Used for backward compatibility with older API.
    */
   public TextRange newRange(int startOffset, int endOffset) {
+    checkMetadata();
     return newRangeValidPointers(newPointer(startOffset), newPointer(endOffset), false);
   }
 
   public TextPointer newPointer(int globalOffset) {
+    checkMetadata();
     Preconditions.checkArgument(globalOffset >= 0, "%s is not a valid offset for a file", globalOffset);
     Preconditions.checkArgument(globalOffset <= lastValidOffset(), "%s is not a valid offset for file %s. Max offset is %s", globalOffset, this, lastValidOffset());
     int line = findLine(globalOffset);
@@ -271,24 +215,46 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
     return new DefaultTextPointer(line, globalOffset - startLineOffset);
   }
 
-  private int findLine(int globalOffset) {
-    return Math.abs(Arrays.binarySearch(originalLineOffsets(), globalOffset) + 1);
+  public DefaultInputFile setStatus(Status status) {
+    this.status = status;
+    return this;
   }
 
-  public DefaultInputFile initMetadata(Metadata metadata) {
-    this.setLines(metadata.lines);
-    this.setLastValidOffset(metadata.lastValidOffset);
-    this.setNonBlankLines(metadata.nonBlankLines);
-    this.setHash(metadata.hash);
-    this.setOriginalLineOffsets(metadata.originalLineOffsets);
+  public DefaultInputFile setCharset(Charset charset) {
+    this.charset = charset;
     return this;
   }
 
-  /**
-   * For testing purpose
-   */
-  public DefaultInputFile initMetadata(String content) {
-    return initMetadata(new FileMetadata().readMetadata(new StringReader(content)));
+  private void checkValid(TextPointer pointer, String owner) {
+    Preconditions.checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line());
+    Preconditions.checkArgument(pointer.line() <= this.metadata.lines(), "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, metadata.lines());
+    Preconditions.checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset());
+    int lineLength = lineLength(pointer.line());
+    Preconditions.checkArgument(pointer.lineOffset() <= lineLength,
+      "%s is not a valid line offset for %s. File %s has %s character(s) at line %s", pointer.lineOffset(), owner, this, lineLength, pointer.line());
+  }
+
+  private int lineLength(int line) {
+    return lastValidGlobalOffsetForLine(line) - originalLineOffsets()[line - 1];
+  }
+
+  private int lastValidGlobalOffsetForLine(int line) {
+    return line < this.metadata.lines() ? (originalLineOffsets()[line] - 1) : lastValidOffset();
+  }
+
+  private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) {
+    Preconditions.checkArgument(acceptEmptyRange ? (start.compareTo(end) <= 0) : (start.compareTo(end) < 0),
+      "Start pointer %s should be before end pointer %s", start, end);
+    return new DefaultTextRange(start, end);
+  }
+
+  private int findLine(int globalOffset) {
+    return Math.abs(Arrays.binarySearch(originalLineOffsets(), globalOffset) + 1);
+  }
+
+  private DefaultInputFile setMetadata(Metadata metadata) {
+    this.metadata = metadata;
+    return this;
   }
 
   @Override
@@ -303,17 +269,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
     }
 
     DefaultInputFile that = (DefaultInputFile) o;
-    return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath);
-  }
-
-  @Override
-  public int hashCode() {
-    return moduleKey.hashCode() + relativePath.hashCode() * 13;
-  }
-
-  @Override
-  public String toString() {
-    return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", basedir=" + moduleBaseDir + "]";
+    return this.moduleKey().equals(that.moduleKey()) && this.relativePath().equals(that.relativePath());
   }
 
   @Override
index 3fac4b9e6ef4c858cc31042da03bce08cb8894d4..1acaf7b2df301e1ef294f50a9d8846e27dada0d6 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.api.batch.fs.internal;
 
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FileSystem.Index;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 
 import java.util.Collections;
@@ -30,7 +31,7 @@ class FalsePredicate extends AbstractFilePredicate {
   static final FilePredicate FALSE = new FalsePredicate();
 
   @Override
-  public boolean apply(InputFile inputFile) {
+  public boolean apply(IndexedFile inputFile) {
     return false;
   }
 
index 9a196396462fc23c600cb497ae8bd33c5d725f4a..64d4205080c88b7eded37117a7882e0ab23337af 100644 (file)
@@ -41,6 +41,7 @@ import org.apache.commons.io.ByteOrderMark;
 import org.apache.commons.io.input.BOMInputStream;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 
@@ -351,22 +352,6 @@ public class FileMetadata {
     }
   }
 
-  public static class Metadata {
-    final int lines;
-    final int nonBlankLines;
-    final String hash;
-    final int[] originalLineOffsets;
-    final int lastValidOffset;
-
-    private Metadata(int lines, int nonBlankLines, String hash, int[] originalLineOffsets, int lastValidOffset) {
-      this.lines = lines;
-      this.nonBlankLines = nonBlankLines;
-      this.hash = hash;
-      this.originalLineOffsets = originalLineOffsets;
-      this.lastValidOffset = lastValidOffset;
-    }
-  }
-
   @FunctionalInterface
   public interface LineHashConsumer {
 
@@ -377,7 +362,7 @@ public class FileMetadata {
   /**
    * Compute a MD5 hash of each line of the file after removing of all blank chars
    */
-  public static void computeLineHashesForIssueTracking(DefaultInputFile f, LineHashConsumer consumer) {
+  public static void computeLineHashesForIssueTracking(InputFile f, LineHashConsumer consumer) {
     readFile(f.file(), f.charset(), new LineHashComputer(consumer, f.file()));
   }
 }
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputFilePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputFilePredicate.java
new file mode 100644 (file)
index 0000000..eacd05b
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.InputFile;
+
+@FunctionalInterface
+public interface InputFilePredicate {
+  boolean apply(InputFile inputFile);
+}
index b7f7c78fd4c0fcf3820b1f4e15bb39abe230a10e..52930c6e2b6bdd18b53585933b40290849b986ca 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.sonar.api.batch.fs.internal;
 
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.IndexedFile;
 
 /**
  * @since 4.2
@@ -32,7 +32,7 @@ class LanguagePredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     return language.equals(f.language());
   }
 }
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java
new file mode 100644 (file)
index 0000000..3788024
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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;
+
+public class Metadata {
+  private final int lines;
+  private final int nonBlankLines;
+  private final String hash;
+  private final int[] originalLineOffsets;
+  private final int lastValidOffset;
+
+  public Metadata(int lines, int nonBlankLines, String hash, int[] originalLineOffsets, int lastValidOffset) {
+    this.lines = lines;
+    this.nonBlankLines = nonBlankLines;
+    this.hash = hash;
+    this.originalLineOffsets = originalLineOffsets;
+    this.lastValidOffset = lastValidOffset;
+  }
+
+  public int lines() {
+    return lines;
+  }
+
+  public int nonBlankLines() {
+    return nonBlankLines;
+  }
+
+  public String hash() {
+    return hash;
+  }
+
+  public int[] originalLineOffsets() {
+    return originalLineOffsets;
+  }
+
+  public int lastValidOffset() {
+    return lastValidOffset;
+  }
+
+}
index 2a179713f9b6e40979c0a18e4c2cdb97ffc7870a..d51f79d2e13557abb5d11aeec0d819be696f69e0 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.api.batch.fs.internal;
 
 import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.IndexedFile;
 
 /**
  * @since 4.2
@@ -34,7 +34,7 @@ class NotPredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     return !predicate.apply(f);
   }
 
index 636ac426067b217c0643f6dd94e511ec4132deda..35fa0a183f350a22c92a4dbe43c8c02df743e3ce 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.api.batch.fs.internal;
 
 import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.IndexedFile;
 
 class OptimizedFilePredicateAdapter extends AbstractFilePredicate {
 
@@ -31,7 +31,7 @@ class OptimizedFilePredicateAdapter extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile inputFile) {
+  public boolean apply(IndexedFile inputFile) {
     return unoptimizedPredicate.apply(inputFile);
   }
 
index 644c33b822436dc56d92f46cf92695dce9713b10..e539d05a83d991a8e944971eba11e46a89d5db69 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.api.batch.fs.internal;
 
 import com.google.common.annotations.VisibleForTesting;
 import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.IndexedFile;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -56,7 +56,7 @@ class OrPredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     for (FilePredicate predicate : predicates) {
       if (predicate.apply(f)) {
         return true;
index 010601ac39519e1a02d66fb32011321f5917c965..5d73f9ceb4a1fe27e3b98920fa18ebed423e66b4 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.api.batch.fs.internal;
 
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.utils.WildcardPattern;
 
 public abstract class PathPattern {
@@ -32,9 +32,9 @@ public abstract class PathPattern {
     this.pattern = WildcardPattern.create(pattern);
   }
 
-  public abstract boolean match(InputFile inputFile);
+  public abstract boolean match(IndexedFile inputFile);
 
-  public abstract boolean match(InputFile inputFile, boolean caseSensitiveFileExtension);
+  public abstract boolean match(IndexedFile inputFile, boolean caseSensitiveFileExtension);
 
   public static PathPattern create(String s) {
     String trimmed = StringUtils.trim(s);
@@ -58,12 +58,12 @@ public abstract class PathPattern {
     }
 
     @Override
-    public boolean match(InputFile inputFile) {
+    public boolean match(IndexedFile inputFile) {
       return match(inputFile, true);
     }
 
     @Override
-    public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
+    public boolean match(IndexedFile inputFile, boolean caseSensitiveFileExtension) {
       String path = inputFile.absolutePath();
       if (!caseSensitiveFileExtension) {
         String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
@@ -90,12 +90,12 @@ public abstract class PathPattern {
     }
 
     @Override
-    public boolean match(InputFile inputFile) {
+    public boolean match(IndexedFile inputFile) {
       return match(inputFile, true);
     }
 
     @Override
-    public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
+    public boolean match(IndexedFile inputFile, boolean caseSensitiveFileExtension) {
       String path = inputFile.relativePath();
       if (!caseSensitiveFileExtension) {
         String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
index 86cd285f74c5b11cdcbf02b9f2dd8c946c28d343..45766537a8b6627f491e21a592bcc4137ced3a90 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.api.batch.fs.internal;
 
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 
 /**
@@ -33,7 +34,7 @@ class PathPatternPredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     return pattern.match(f);
   }
 
index 155a8b6a3ab58d98c7de300f0decada3efb55006..f7e727f45b5d433b51799cc42403e6edac722a01 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.api.batch.fs.internal;
 
 import org.sonar.api.batch.fs.FileSystem.Index;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.utils.PathUtils;
 
@@ -42,7 +43,7 @@ public class RelativePathPredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     return path.equals(f.relativePath());
   }
 
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java
deleted file mode 100644 (file)
index daa4b23..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.InputFile;
-
-/**
- * @since 4.2
- */
-class StatusPredicate extends AbstractFilePredicate {
-
-  private final InputFile.Status status;
-
-  StatusPredicate(InputFile.Status status) {
-    this.status = status;
-  }
-
-  @Override
-  public boolean apply(InputFile f) {
-    return status == f.status();
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java
new file mode 100644 (file)
index 0000000..fe4bb6d
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.utils.PathUtils;
+
+/**
+ * @since 4.2
+ */
+public class TestInputFileBuilder {
+  private final String relativePath;
+  private final String moduleKey;
+  private Path moduleBaseDir;
+  private String language;
+  private InputFile.Type type = InputFile.Type.MAIN;
+  private InputFile.Status status;
+  private int lines = -1;
+  private Charset charset;
+  private int lastValidOffset = -1;
+  private String hash;
+  private int nonBlankLines;
+  private int[] originalLineOffsets;
+
+  public TestInputFileBuilder(String moduleKey, String relativePath) {
+    this.moduleKey = moduleKey;
+    this.moduleBaseDir = Paths.get(moduleKey);
+    this.relativePath = PathUtils.sanitize(relativePath);
+  }
+
+  public TestInputFileBuilder setModuleBaseDir(Path moduleBaseDir) {
+    this.moduleBaseDir = moduleBaseDir.normalize();
+    return this;
+  }
+
+  public TestInputFileBuilder setLanguage(@Nullable String language) {
+    this.language = language;
+    return this;
+  }
+
+  public TestInputFileBuilder setType(InputFile.Type type) {
+    this.type = type;
+    return this;
+  }
+
+  public TestInputFileBuilder setStatus(InputFile.Status status) {
+    this.status = status;
+    return this;
+  }
+
+  public TestInputFileBuilder setLines(int lines) {
+    this.lines = lines;
+    return this;
+  }
+
+  public TestInputFileBuilder setCharset(Charset charset) {
+    this.charset = charset;
+    return this;
+  }
+
+  public TestInputFileBuilder setLastValidOffset(int lastValidOffset) {
+    this.lastValidOffset = lastValidOffset;
+    return this;
+  }
+
+  public TestInputFileBuilder setHash(String hash) {
+    this.hash = hash;
+    return this;
+  }
+
+  public TestInputFileBuilder setNonBlankLines(int nonBlankLines) {
+    this.nonBlankLines = nonBlankLines;
+    return this;
+  }
+
+  public TestInputFileBuilder setOriginalLineOffsets(int[] originalLineOffsets) {
+    this.originalLineOffsets = originalLineOffsets;
+    return this;
+  }
+
+  public TestInputFileBuilder setMetadata(Metadata metadata) {
+    this.setLines(metadata.lines());
+    this.setLastValidOffset(metadata.lastValidOffset());
+    this.setNonBlankLines(metadata.nonBlankLines());
+    this.setHash(metadata.hash());
+    this.setOriginalLineOffsets(metadata.originalLineOffsets());
+    return this;
+  }
+
+  public TestInputFileBuilder initMetadata(String content) {
+    return setMetadata(new FileMetadata().readMetadata(new StringReader(content)));
+  }
+
+  public DefaultInputFile build() {
+    DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type);
+    indexedFile.setLanguage(language);
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> new Metadata(lines, nonBlankLines, hash, originalLineOffsets, lastValidOffset));
+    inputFile.setStatus(status);
+    inputFile.setCharset(charset);
+    return inputFile;
+  }
+}
index c8ca4d9163bb31ba188e54ddae4bd4559aab0c86..c7a58946749685380a52e0c1899892fbfccc2439 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.api.batch.fs.internal;
 
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FileSystem.Index;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 
 class TruePredicate extends AbstractFilePredicate {
@@ -28,7 +29,7 @@ class TruePredicate extends AbstractFilePredicate {
   static final FilePredicate TRUE = new TruePredicate();
 
   @Override
-  public boolean apply(InputFile inputFile) {
+  public boolean apply(IndexedFile inputFile) {
     return true;
   }
 
index 36fefb2fd295ac703a1239111d44cd5f99759968..c3d9fbf0bc1f4d94c6a0f7d4e7512a8e1bc855a2 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.api.batch.fs.internal;
 
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 
 /**
@@ -33,7 +34,7 @@ class TypePredicate extends AbstractFilePredicate {
   }
 
   @Override
-  public boolean apply(InputFile f) {
+  public boolean apply(IndexedFile f) {
     return type == f.type();
   }
 
index fc84bd2fc5e3a195ee266bb355e5fd133e2e9cfb..a32e6423196f304671ee0594528f9c3d2cfde66c 100644 (file)
@@ -24,7 +24,6 @@ import java.util.Collections;
 import java.util.SortedMap;
 import javax.annotation.Nullable;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.coverage.CoverageType;
 import org.sonar.api.batch.sensor.coverage.NewCoverage;
 import org.sonar.api.batch.sensor.internal.DefaultStorable;
@@ -35,7 +34,7 @@ import static com.google.common.base.Preconditions.checkState;
 
 public class DefaultCoverage extends DefaultStorable implements NewCoverage {
 
-  private DefaultInputFile inputFile;
+  private InputFile inputFile;
   private CoverageType type;
   private int totalCoveredLines = 0;
   private int totalConditions = 0;
@@ -54,7 +53,7 @@ public class DefaultCoverage extends DefaultStorable implements NewCoverage {
 
   @Override
   public DefaultCoverage onFile(InputFile inputFile) {
-    this.inputFile = (DefaultInputFile) inputFile;
+    this.inputFile = inputFile;
     return this;
   }
 
index 16d8be19e08e811c76c64cb0befa5b0b2086c766..cdec0c7971abed16ea2af71bd04febf2396ad2de 100644 (file)
@@ -25,7 +25,6 @@ import java.util.List;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.PathPattern;
 import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
 import org.sonar.api.batch.sensor.internal.DefaultStorable;
@@ -37,7 +36,7 @@ public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens {
 
   private final Settings settings;
   private final ImmutableList.Builder<TokensLine> result = ImmutableList.builder();
-  private DefaultInputFile inputFile;
+  private InputFile inputFile;
   private int startLine = Integer.MIN_VALUE;
   private int startIndex = 0;
   private int currentIndex = 0;
@@ -53,7 +52,7 @@ public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens {
   @Override
   public DefaultCpdTokens onFile(InputFile inputFile) {
     Preconditions.checkNotNull(inputFile, "file can't be null");
-    this.inputFile = (DefaultInputFile) inputFile;
+    this.inputFile = inputFile;
     String[] cpdExclusions = settings.getStringArray(CoreProperties.CPD_EXCLUSIONS);
     for (PathPattern cpdExclusion : PathPattern.create(cpdExclusions)) {
       if (cpdExclusion.match(inputFile)) {
index 5ce491477cf1dc5940a3c9110818e27f91f97273..e06847c27e3de456927f1a13dec13c42ff8657d0 100644 (file)
@@ -25,10 +25,12 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Collections;
 
@@ -39,16 +41,21 @@ public class DefaultFilePredicatesTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
-  DefaultInputFile javaFile;
+  private Path moduleBasePath;
+
+  @Before
+  public void setUp() throws IOException {
+    moduleBasePath = temp.newFolder().toPath();
+  }
+
+  IndexedFile javaFile;
   FilePredicates predicates;
 
   @Before
   public void before() throws IOException {
     predicates = new DefaultFilePredicates(temp.newFolder().toPath());
-    javaFile = new DefaultInputFile("foo", "src/main/java/struts/Action.java")
-      .setModuleBaseDir(temp.newFolder().toPath())
-      .setLanguage("java")
-      .setStatus(InputFile.Status.ADDED);
+    javaFile = new DefaultIndexedFile("foo", moduleBasePath, "src/main/java/struts/Action.java")
+      .setLanguage("java");
   }
 
   @Test
@@ -150,12 +157,6 @@ public class DefaultFilePredicatesTest {
     assertThat(predicates.hasLanguages(Collections.<String>emptyList()).apply(javaFile)).isTrue();
   }
 
-  @Test
-  public void has_status() {
-    assertThat(predicates.hasStatus(InputFile.Status.ADDED).apply(javaFile)).isTrue();
-    assertThat(predicates.hasStatus(InputFile.Status.CHANGED).apply(javaFile)).isFalse();
-  }
-
   @Test
   public void has_type() {
     assertThat(predicates.hasType(InputFile.Type.MAIN).apply(javaFile)).isTrue();
index 81d517ab71f0b08fe69b7d489ae23731ca50db33..5656d232821adaac6bfff22345c1534c80d2dc37 100644 (file)
@@ -81,12 +81,12 @@ public class DefaultFileSystemTest {
   public void files() {
     assertThat(fs.inputFiles(fs.predicates().all())).isEmpty();
 
-    fs.add(new DefaultInputFile("foo", "src/Foo.php").setLanguage("php"));
-    fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java"));
-    fs.add(new DefaultInputFile("foo", "src/Baz.java").setLanguage("java"));
+    fs.add(new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build());
+    fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build());
+    fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build());
 
     // no language
-    fs.add(new DefaultInputFile("foo", "src/readme.txt"));
+    fs.add(new TestInputFileBuilder("foo", "src/readme.txt").build());
 
     assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNotNull();
     assertThat(fs.inputFile(fs.predicates().hasRelativePath("does/not/exist"))).isNull();
@@ -118,15 +118,15 @@ public class DefaultFileSystemTest {
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("expected one element");
 
-    fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java"));
-    fs.add(new DefaultInputFile("foo", "src/Baz.java").setLanguage("java"));
+    fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build());
+    fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build());
 
     fs.inputFile(fs.predicates().all());
   }
 
   @Test
   public void input_file_supports_non_indexed_predicates() {
-    fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java"));
+    fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build());
 
     // it would fail if more than one java file
     assertThat(fs.inputFile(fs.predicates().hasLanguage("java"))).isNotNull();
index 5fd96320fec09f7ddc63835500ab10751cdcd9db..ae1aed402ce3b99363a97fc398830142e22eabb8 100644 (file)
@@ -24,9 +24,11 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.StringReader;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.stream.Collectors;
 
 import org.junit.Rule;
@@ -37,6 +39,7 @@ import org.sonar.api.batch.fs.TextRange;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
 
 public class DefaultInputFileTest {
 
@@ -46,12 +49,11 @@ public class DefaultInputFileTest {
   @Test
   public void test() throws Exception {
     Path baseDir = temp.newFolder().toPath();
-    DefaultInputFile inputFile = new DefaultInputFile("ABCDE", "src/Foo.php")
-      .setModuleBaseDir(baseDir)
-      .setLines(42)
-      .setLanguage("php")
+
+    Metadata metadata = new Metadata(42, 42, "", new int[0], 0);
+    DefaultIndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST).setLanguage("php");
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> metadata)
       .setStatus(InputFile.Status.ADDED)
-      .setType(InputFile.Type.TEST)
       .setCharset(StandardCharsets.ISO_8859_1);
 
     assertThat(inputFile.relativePath()).isEqualTo("src/Foo.php");
@@ -71,13 +73,12 @@ public class DefaultInputFileTest {
     Path testFile = baseDir.resolve("src").resolve("Foo.php");
     Files.createDirectories(testFile.getParent());
     Files.write(testFile, "test string".getBytes(StandardCharsets.UTF_8));
-    DefaultInputFile inputFile = new DefaultInputFile("ABCDE", "src/Foo.php")
-      .setModuleBaseDir(baseDir)
-      .setLines(42)
-      .setLanguage("php")
-      .setStatus(InputFile.Status.ADDED)
-      .setType(InputFile.Type.TEST)
-      .setCharset(StandardCharsets.ISO_8859_1);
+    Metadata metadata = new Metadata(42, 30, "", new int[0], 0);
+
+    DefaultInputFile inputFile = new DefaultInputFile(new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST)
+      .setLanguage("php"), f -> metadata)
+        .setStatus(InputFile.Status.ADDED)
+        .setCharset(StandardCharsets.ISO_8859_1);
 
     assertThat(inputFile.contents()).isEqualTo("test string");
     try (InputStream inputStream = inputFile.inputStream()) {
@@ -89,9 +90,9 @@ public class DefaultInputFileTest {
 
   @Test
   public void test_equals_and_hashcode() throws Exception {
-    DefaultInputFile f1 = new DefaultInputFile("ABCDE", "src/Foo.php");
-    DefaultInputFile f1a = new DefaultInputFile("ABCDE", "src/Foo.php");
-    DefaultInputFile f2 = new DefaultInputFile("ABCDE", "src/Bar.php");
+    DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> mock(Metadata.class));
+    DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> mock(Metadata.class));
+    DefaultInputFile f2 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Bar.php"), (f) -> mock(Metadata.class));
 
     assertThat(f1).isEqualTo(f1);
     assertThat(f1).isEqualTo(f1a);
@@ -105,16 +106,14 @@ public class DefaultInputFileTest {
 
   @Test
   public void test_toString() throws Exception {
-    DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php");
-    assertThat(file.toString()).isEqualTo("[moduleKey=ABCDE, relative=src/Foo.php, basedir=null]");
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> mock(Metadata.class));
+    assertThat(file.toString()).isEqualTo("[moduleKey=ABCDE, relative=src/Foo.php, basedir=module]");
   }
 
   @Test
   public void checkValidPointer() {
-    DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php");
-    file.setLines(2);
-    file.setOriginalLineOffsets(new int[] {0, 10});
-    file.setLastValidOffset(15);
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
     assertThat(file.newPointer(1, 0).line()).isEqualTo(1);
     assertThat(file.newPointer(1, 0).lineOffset()).isEqualTo(0);
     // Don't fail
@@ -132,7 +131,7 @@ public class DefaultInputFileTest {
       file.newPointer(3, 1);
       fail();
     } catch (Exception e) {
-      assertThat(e).hasMessage("3 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 2 line(s)");
+      assertThat(e).hasMessage("3 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 2 line(s)");
     }
     try {
       file.newPointer(1, -1);
@@ -144,16 +143,14 @@ public class DefaultInputFileTest {
       file.newPointer(1, 10);
       fail();
     } catch (Exception e) {
-      assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 9 character(s) at line 1");
+      assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 9 character(s) at line 1");
     }
   }
 
   @Test
   public void checkValidPointerUsingGlobalOffset() {
-    DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php");
-    file.setLines(2);
-    file.setOriginalLineOffsets(new int[] {0, 10});
-    file.setLastValidOffset(15);
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
     assertThat(file.newPointer(0).line()).isEqualTo(1);
     assertThat(file.newPointer(0).lineOffset()).isEqualTo(0);
 
@@ -177,14 +174,15 @@ public class DefaultInputFileTest {
       file.newPointer(16);
       fail();
     } catch (Exception e) {
-      assertThat(e).hasMessage("16 is not a valid offset for file [moduleKey=ABCDE, relative=src/Foo.php, basedir=null]. Max offset is 15");
+      assertThat(e).hasMessage("16 is not a valid offset for file [moduleKey=ABCDE, relative=src/Foo.php, basedir=module]. Max offset is 15");
     }
   }
 
   @Test
   public void checkValidRange() {
-    DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php");
-    file.initMetadata("bla bla a\nabcde");
+    Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde"));
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+
     assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 1)).start().line()).isEqualTo(1);
     // Don't fail
     file.newRange(file.newPointer(1, 0), file.newPointer(1, 1));
@@ -202,14 +200,15 @@ public class DefaultInputFileTest {
       file.newRange(file.newPointer(1, 0), file.newPointer(1, 10));
       fail();
     } catch (Exception e) {
-      assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 9 character(s) at line 1");
+      assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 9 character(s) at line 1");
     }
   }
 
   @Test
   public void selectLine() {
-    DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php");
-    file.initMetadata("bla bla a\nabcde\n\nabc");
+    Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde\n\nabc"));
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+
     assertThat(file.selectLine(1).start().line()).isEqualTo(1);
     assertThat(file.selectLine(1).start().lineOffset()).isEqualTo(0);
     assertThat(file.selectLine(1).end().line()).isEqualTo(1);
@@ -225,16 +224,14 @@ public class DefaultInputFileTest {
       file.selectLine(5);
       fail();
     } catch (Exception e) {
-      assertThat(e).hasMessage("5 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 4 line(s)");
+      assertThat(e).hasMessage("5 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 4 line(s)");
     }
   }
 
   @Test
   public void checkValidRangeUsingGlobalOffset() {
-    DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php");
-    file.setLines(2);
-    file.setOriginalLineOffsets(new int[] {0, 10});
-    file.setLastValidOffset(15);
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
     TextRange newRange = file.newRange(10, 13);
     assertThat(newRange.start().line()).isEqualTo(2);
     assertThat(newRange.start().lineOffset()).isEqualTo(0);
@@ -244,10 +241,8 @@ public class DefaultInputFileTest {
 
   @Test
   public void testRangeOverlap() {
-    DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php");
-    file.setLines(2);
-    file.setOriginalLineOffsets(new int[] {0, 10});
-    file.setLastValidOffset(15);
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
     // Don't fail
     assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)))).isTrue();
     assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isTrue();
index 0b8fd1ebf79b660c88b1384608a92799adbb54cf..daa153f72d3241cbf946e0d2af0adf1d05a081dc 100644 (file)
@@ -53,12 +53,12 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.touch(tempFile);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(1);
-    assertThat(metadata.nonBlankLines).isEqualTo(0);
-    assertThat(metadata.hash).isNotEmpty();
-    assertThat(metadata.originalLineOffsets).containsOnly(0);
-    assertThat(metadata.lastValidOffset).isEqualTo(0);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(1);
+    assertThat(metadata.nonBlankLines()).isEqualTo(0);
+    assertThat(metadata.hash()).isNotEmpty();
+    assertThat(metadata.originalLineOffsets()).containsOnly(0);
+    assertThat(metadata.lastValidOffset()).isEqualTo(0);
   }
 
   @Test
@@ -66,12 +66,12 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\r\nbar\r\nbaz", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(3);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10);
-    assertThat(metadata.lastValidOffset).isEqualTo(13);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(3);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 5, 10);
+    assertThat(metadata.lastValidOffset()).isEqualTo(13);
   }
 
   @Test
@@ -79,10 +79,10 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "marker´s\n", Charset.forName("cp1252"));
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(2);
-    assertThat(metadata.hash).isEqualTo(md5Hex("marker\ufffds\n"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 9);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(2);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("marker\ufffds\n"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 9);
   }
 
   @Test
@@ -90,22 +90,22 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(4);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10, 18);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(4);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 5, 10, 18);
   }
 
   @Test
   public void non_ascii_utf_16() throws Exception {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_16, true);
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_16);
-    assertThat(metadata.lines).isEqualTo(4);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n".getBytes(StandardCharsets.UTF_8)));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10, 18);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_16);
+    assertThat(metadata.lines()).isEqualTo(4);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n".getBytes(StandardCharsets.UTF_8)));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 5, 10, 18);
   }
 
   @Test
@@ -113,12 +113,12 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\nbar\nbaz", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(3);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8);
-    assertThat(metadata.lastValidOffset).isEqualTo(11);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(3);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8);
+    assertThat(metadata.lastValidOffset()).isEqualTo(11);
   }
 
   @Test
@@ -126,12 +126,12 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\nbar\nbaz\n", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(4);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz\n"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8, 12);
-    assertThat(metadata.lastValidOffset).isEqualTo(12);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(4);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8, 12);
+    assertThat(metadata.lastValidOffset()).isEqualTo(12);
   }
 
   @Test
@@ -139,12 +139,12 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\rbar\rbaz", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(3);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8);
-    assertThat(metadata.lastValidOffset).isEqualTo(11);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(3);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8);
+    assertThat(metadata.lastValidOffset()).isEqualTo(11);
   }
 
   @Test
@@ -152,12 +152,12 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\rbar\rbaz\r", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(4);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz\n"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8, 12);
-    assertThat(metadata.lastValidOffset).isEqualTo(12);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(4);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8, 12);
+    assertThat(metadata.lastValidOffset()).isEqualTo(12);
   }
 
   @Test
@@ -165,11 +165,11 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\nbar\r\nbaz\n", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(4);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz\n"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 9, 13);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(4);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 9, 13);
   }
 
   @Test
@@ -177,11 +177,11 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\n\n\nbar", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(4);
-    assertThat(metadata.nonBlankLines).isEqualTo(2);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\n\n\nbar"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 5, 6);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(4);
+    assertThat(metadata.nonBlankLines()).isEqualTo(2);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\n\n\nbar"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 5, 6);
   }
 
   @Test
@@ -189,11 +189,11 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "foo\nbar\r\nbaz", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(3);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 9);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(3);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 9);
   }
 
   @Test
@@ -201,11 +201,11 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "\nfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(4);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("\nfoo\nbar\nbaz"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 1, 5, 10);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(4);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("\nfoo\nbar\nbaz"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 1, 5, 10);
   }
 
   @Test
@@ -213,11 +213,11 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "\uFEFFfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true);
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(3);
-    assertThat(metadata.nonBlankLines).isEqualTo(3);
-    assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz"));
-    assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 9);
+    Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(3);
+    assertThat(metadata.nonBlankLines()).isEqualTo(3);
+    assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz"));
+    assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 9);
   }
 
   @Test
@@ -225,9 +225,10 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, " foo\nb ar\r\nbaz \t", StandardCharsets.UTF_8, true);
 
-    DefaultInputFile f = new DefaultInputFile("foo", tempFile.getName());
-    f.setModuleBaseDir(tempFile.getParentFile().toPath());
-    f.setCharset(StandardCharsets.UTF_8);
+    DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName())
+      .setModuleBaseDir(tempFile.getParentFile().toPath())
+      .setCharset(StandardCharsets.UTF_8)
+      .build();
     FileMetadata.computeLineHashesForIssueTracking(f, new LineHashConsumer() {
 
       @Override
@@ -254,9 +255,10 @@ public class FileMetadataTest {
     File tempFile = temp.newFile();
     FileUtils.write(tempFile, "", StandardCharsets.UTF_8, true);
 
-    DefaultInputFile f = new DefaultInputFile("foo", tempFile.getName());
-    f.setModuleBaseDir(tempFile.getParentFile().toPath());
-    f.setCharset(StandardCharsets.UTF_8);
+    DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName())
+      .setModuleBaseDir(tempFile.getParentFile().toPath())
+      .setCharset(StandardCharsets.UTF_8)
+      .build();
     FileMetadata.computeLineHashesForIssueTracking(f, new LineHashConsumer() {
 
       @Override
@@ -295,9 +297,9 @@ public class FileMetadataTest {
     File file2 = temp.newFile();
     FileUtils.write(file2, "foo\nbar", StandardCharsets.UTF_8, true);
 
-    String hash1 = new FileMetadata().readMetadata(file1, StandardCharsets.UTF_8).hash;
-    String hash1a = new FileMetadata().readMetadata(file1a, StandardCharsets.UTF_8).hash;
-    String hash2 = new FileMetadata().readMetadata(file2, StandardCharsets.UTF_8).hash;
+    String hash1 = new FileMetadata().readMetadata(file1, StandardCharsets.UTF_8).hash();
+    String hash1a = new FileMetadata().readMetadata(file1a, StandardCharsets.UTF_8).hash();
+    String hash2 = new FileMetadata().readMetadata(file2, StandardCharsets.UTF_8).hash();
     assertThat(hash1).isEqualTo(hash1a);
     assertThat(hash1).isNotEqualTo(hash2);
   }
@@ -306,10 +308,10 @@ public class FileMetadataTest {
   public void binary_file_with_unmappable_character() throws Exception {
     File woff = new File(this.getClass().getResource("glyphicons-halflings-regular.woff").toURI());
 
-    FileMetadata.Metadata metadata = new FileMetadata().readMetadata(woff, StandardCharsets.UTF_8);
-    assertThat(metadata.lines).isEqualTo(135);
-    assertThat(metadata.nonBlankLines).isEqualTo(133);
-    assertThat(metadata.hash).isNotEmpty();
+    Metadata metadata = new FileMetadata().readMetadata(woff, StandardCharsets.UTF_8);
+    assertThat(metadata.lines()).isEqualTo(135);
+    assertThat(metadata.nonBlankLines()).isEqualTo(133);
+    assertThat(metadata.hash()).isNotEmpty();
 
     assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains("Invalid character encountered in file");
     assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains(
index 82f9542844eb37b3210f65d86a417782da40d442..f6111ea24e41dfd06e1f6b072d3642fb566f2598 100644 (file)
  */
 package org.sonar.api.batch.fs.internal;
 
+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.IndexedFile;
 
+import java.io.IOException;
 import java.nio.file.Path;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -31,33 +33,38 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class PathPatternTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
+  private Path moduleBasePath;
+
+  @Before
+  public void setUp() throws IOException {
+    moduleBasePath = temp.newFolder().toPath();
+  }
 
   @Test
   public void match_relative_path() {
     PathPattern pattern = PathPattern.create("**/*Foo.java");
     assertThat(pattern.toString()).isEqualTo("**/*Foo.java");
 
-    InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.java");
-    assertThat(pattern.match(inputFile)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.java");
+    assertThat(pattern.match(indexedFile)).isTrue();
 
     // case sensitive by default
-    inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA");
-    assertThat(pattern.match(inputFile)).isFalse();
+    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA");
+    assertThat(pattern.match(indexedFile)).isFalse();
 
-    inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java");
-    assertThat(pattern.match(inputFile)).isFalse();
+    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java");
+    assertThat(pattern.match(indexedFile)).isFalse();
   }
 
   @Test
   public void match_relative_path_and_insensitive_file_extension() throws Exception {
     PathPattern pattern = PathPattern.create("**/*Foo.java");
 
-    Path moduleBaseDir = temp.newFolder().toPath();
-    InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setModuleBaseDir(moduleBaseDir);
-    assertThat(pattern.match(inputFile, false)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA");
+    assertThat(pattern.match(indexedFile, false)).isTrue();
 
-    inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java").setModuleBaseDir(moduleBaseDir);
-    assertThat(pattern.match(inputFile, false)).isFalse();
+    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java");
+    assertThat(pattern.match(indexedFile, false)).isFalse();
   }
 
   @Test
@@ -65,16 +72,15 @@ public class PathPatternTest {
     PathPattern pattern = PathPattern.create("file:**/src/main/**Foo.java");
     assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java");
 
-    Path moduleBaseDir = temp.newFolder().toPath();
-    InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.java").setModuleBaseDir(moduleBaseDir);
-    assertThat(pattern.match(inputFile)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.java");
+    assertThat(pattern.match(indexedFile)).isTrue();
 
     // case sensitive by default
-    inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setModuleBaseDir(moduleBaseDir);
-    assertThat(pattern.match(inputFile)).isFalse();
+    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA");
+    assertThat(pattern.match(indexedFile)).isFalse();
 
-    inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java").setModuleBaseDir(moduleBaseDir);
-    assertThat(pattern.match(inputFile)).isFalse();
+    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java");
+    assertThat(pattern.match(indexedFile)).isFalse();
   }
 
   @Test
@@ -82,12 +88,11 @@ public class PathPatternTest {
     PathPattern pattern = PathPattern.create("file:**/src/main/**Foo.java");
     assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java");
 
-    Path moduleBaseDir = temp.newFolder().toPath();
-    InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setModuleBaseDir(moduleBaseDir);
-    assertThat(pattern.match(inputFile, false)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA");
+    assertThat(pattern.match(indexedFile, false)).isTrue();
 
-    inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.JAVA").setModuleBaseDir(moduleBaseDir);
-    assertThat(pattern.match(inputFile, false)).isFalse();
+    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.JAVA");
+    assertThat(pattern.match(indexedFile, false)).isFalse();
   }
 
   @Test
index c5772e3b3499b948fa074ec2a2c9824caa681bd4..e28256d28498e4ab569f1ccd334a0a493eb6bcd9 100644 (file)
@@ -20,7 +20,8 @@
 package org.sonar.api.batch.sensor.cpd.internal;
 
 import org.junit.Test;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.config.Settings;
 import org.sonar.api.config.MapSettings;
@@ -34,11 +35,11 @@ import static org.mockito.Mockito.verifyZeroInteractions;
 
 public class DefaultCpdTokensTest {
 
-  private static final DefaultInputFile INPUT_FILE = new DefaultInputFile("foo", "src/Foo.java")
+  private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java")
     .setLines(2)
-    .setLanguage("java")
     .setOriginalLineOffsets(new int[] {0, 50})
-    .setLastValidOffset(100);
+    .setLastValidOffset(100)
+    .build();
 
   @Test
   public void save_no_tokens() {
@@ -145,7 +146,7 @@ public class DefaultCpdTokensTest {
       tokens.addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo");
       fail("Expected exception");
     } catch (Exception e) {
-      assertThat(e).hasMessage("Tokens of file [moduleKey=foo, relative=src/Foo.java, basedir=null] should be provided in order.\n" +
+      assertThat(e).hasMessage("Tokens of file [moduleKey=foo, relative=src/Foo.java, basedir=foo] should be provided in order.\n" +
         "Previous token: Range[from [line=1, lineOffset=6] to [line=1, lineOffset=10]]\n" +
         "Last token: Range[from [line=1, lineOffset=2] to [line=1, lineOffset=5]]");
     }
index cb67b294f5444d4f05576dabb45ff8f942c432eb..4be93eb9c5d671bbd8f3bcfd60e03b090e214a09 100644 (file)
@@ -29,8 +29,8 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextPointer;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultTextPointer;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.error.NewAnalysisError;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -46,7 +46,7 @@ public class DefaultAnalysisErrorTest {
 
   @Before
   public void setUp() {
-    inputFile = new DefaultInputFile("module1", "src/File.java");
+    inputFile = new TestInputFileBuilder("module1", "src/File.java").build();
     textPointer = new DefaultTextPointer(5, 2);
     storage = mock(SensorStorage.class);
   }
index bd3766962f4ca3f8d1cd12c6938cd53a5ae66bd6..2aea77143a7d6d1c65cf2c6e7c118749a1a21178 100644 (file)
@@ -24,10 +24,11 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultTextPointer;
 import org.sonar.api.batch.fs.internal.DefaultTextRange;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -38,10 +39,11 @@ import static org.sonar.api.batch.sensor.highlighting.TypeOfText.KEYWORD;
 
 public class DefaultHighlightingTest {
 
-  private static final DefaultInputFile INPUT_FILE = new DefaultInputFile("foo", "src/Foo.java")
+  private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java")
     .setLines(2)
     .setOriginalLineOffsets(new int[] {0, 50})
-    .setLastValidOffset(100);
+    .setLastValidOffset(100)
+    .build();
 
   private Collection<SyntaxHighlightingRule> highlightingRules;
 
index 4acdbc92dc24e00a8ed885f3402ac2490e7bb51e..fb95b4690161d0fdcf79c84a0a124f9d29d7e902 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.api.batch.sensor.internal;
 
 import java.io.File;
-import java.io.StringReader;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -31,7 +30,7 @@ import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.fs.internal.DefaultTextPointer;
-import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.sensor.error.AnalysisError;
@@ -93,12 +92,12 @@ public class SensorContextTesterTest {
     assertThat(tester.allIssues()).isEmpty();
     NewIssue newIssue = tester.newIssue();
     newIssue
-      .at(newIssue.newLocation().on(new DefaultInputFile("foo", "src/Foo.java")))
+      .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build()))
       .forRule(RuleKey.of("repo", "rule"))
       .save();
     newIssue = tester.newIssue();
     newIssue
-      .at(newIssue.newLocation().on(new DefaultInputFile("foo", "src/Foo.java")))
+      .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build()))
       .forRule(RuleKey.of("repo", "rule"))
       .save();
     assertThat(tester.allIssues()).hasSize(2);
@@ -109,7 +108,7 @@ public class SensorContextTesterTest {
     assertThat(tester.allAnalysisErrors()).isEmpty();
     NewAnalysisError newAnalysisError = tester.newAnalysisError();
 
-    InputFile file = new DefaultInputFile("foo", "src/Foo.java");
+    InputFile file = new TestInputFileBuilder("foo", "src/Foo.java").build();
     newAnalysisError.onFile(file)
       .message("error")
       .at(new DefaultTextPointer(5, 2))
@@ -129,14 +128,14 @@ public class SensorContextTesterTest {
     assertThat(tester.measures("foo:src/Foo.java")).isEmpty();
     assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull();
     tester.<Integer>newMeasure()
-      .on(new DefaultInputFile("foo", "src/Foo.java"))
+      .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
       .forMetric(CoreMetrics.NCLOC)
       .withValue(2)
       .save();
     assertThat(tester.measures("foo:src/Foo.java")).hasSize(1);
     assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
     tester.<Integer>newMeasure()
-      .on(new DefaultInputFile("foo", "src/Foo.java"))
+      .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
       .forMetric(CoreMetrics.LINES)
       .withValue(4)
       .save();
@@ -155,12 +154,12 @@ public class SensorContextTesterTest {
   @Test(expected = SonarException.class)
   public void duplicateMeasures() {
     tester.<Integer>newMeasure()
-      .on(new DefaultInputFile("foo", "src/Foo.java"))
+      .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
       .forMetric(CoreMetrics.NCLOC)
       .withValue(2)
       .save();
     tester.<Integer>newMeasure()
-      .on(new DefaultInputFile("foo", "src/Foo.java"))
+      .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
       .forMetric(CoreMetrics.NCLOC)
       .withValue(2)
       .save();
@@ -170,7 +169,7 @@ public class SensorContextTesterTest {
   public void testHighlighting() {
     assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).isEmpty();
     tester.newHighlighting()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
       .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION)
       .highlight(8, 10, TypeOfText.CONSTANT)
       .highlight(9, 10, TypeOfText.COMMENT)
@@ -182,11 +181,11 @@ public class SensorContextTesterTest {
   @Test(expected = UnsupportedOperationException.class)
   public void duplicateHighlighting() {
     tester.newHighlighting()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
       .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION)
       .save();
     tester.newHighlighting()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
       .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION)
       .save();
   }
@@ -196,7 +195,7 @@ public class SensorContextTesterTest {
     assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull();
 
     NewSymbolTable symbolTable = tester.newSymbolTable()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))));
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build());
     symbolTable
       .newSymbol(1, 8, 1, 10);
 
@@ -216,14 +215,14 @@ public class SensorContextTesterTest {
   @Test(expected = UnsupportedOperationException.class)
   public void duplicateSymbolReferences() {
     NewSymbolTable symbolTable = tester.newSymbolTable()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))));
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build());
     symbolTable
       .newSymbol(1, 8, 1, 10);
 
     symbolTable.save();
 
     symbolTable = tester.newSymbolTable()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))));
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build());
     symbolTable
       .newSymbol(1, 8, 1, 10);
 
@@ -237,7 +236,7 @@ public class SensorContextTesterTest {
 
     exception.expect(IllegalStateException.class);
     tester.newCoverage()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
       .lineHits(0, 3);
   }
 
@@ -248,7 +247,7 @@ public class SensorContextTesterTest {
     exception.expect(IllegalStateException.class);
 
     tester.newCoverage()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
       .lineHits(4, 3);
   }
 
@@ -257,7 +256,7 @@ public class SensorContextTesterTest {
     assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull();
     assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull();
     tester.newCoverage()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build())
       .lineHits(1, 2)
       .lineHits(2, 3)
       .save();
@@ -267,12 +266,12 @@ public class SensorContextTesterTest {
 
   public void multipleCoverage() {
     tester.newCoverage()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build())
       .lineHits(1, 2)
       .conditions(3, 4, 2)
       .save();
     tester.newCoverage()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build())
       .lineHits(1, 2)
       .conditions(3, 4, 3)
       .save();
@@ -286,7 +285,9 @@ public class SensorContextTesterTest {
     assertThat(tester.conditions("foo:src/Foo.java", 1)).isNull();
     assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isNull();
     tester.newCoverage()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasd\nasdas\nasdfas"))))
+      .onFile(new TestInputFileBuilder("foo", "src/Foo.java")
+        .initMetadata("annot dsf fds foo bar\nasd\nasdas\nasdfas")
+        .build())
       .conditions(1, 4, 2)
       .save();
     assertThat(tester.conditions("foo:src/Foo.java", 1)).isEqualTo(4);
@@ -296,7 +297,9 @@ public class SensorContextTesterTest {
   @Test
   public void testCpdTokens() {
     assertThat(tester.cpdTokens("foo:src/Foo.java")).isNull();
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("public class Foo {\n\n}")));
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
+      .initMetadata("public class Foo {\n\n}")
+      .build();
     tester.newCpdTokens()
       .onFile(inputFile)
       .addToken(inputFile.newRange(0, 6), "public")
@@ -313,7 +316,9 @@ public class SensorContextTesterTest {
 
   @Test(expected = UnsupportedOperationException.class)
   public void duplicateCpdTokens() {
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("public class Foo {\n\n}")));
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
+      .initMetadata("public class Foo {\n\n}")
+      .build();
     tester.newCpdTokens()
       .onFile(inputFile)
       .addToken(inputFile.newRange(0, 6), "public")
index 2f54035a1eed5b1e6481a93da0e573d65944354c..967b8b8e9d74d19362ea2d7d614e6eb547690ea7 100644 (file)
  */
 package org.sonar.api.batch.sensor.issue.internal;
 
-import java.io.StringReader;
 import org.apache.commons.lang.StringUtils;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -34,7 +33,9 @@ public class DefaultIssueLocationTest {
   @Rule
   public ExpectedException thrown = ExpectedException.none();
 
-  private DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php").initMetadata(new FileMetadata().readMetadata(new StringReader("Foo\nBar\n")));
+  private InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php")
+    .initMetadata("Foo\nBar\n")
+    .build();
 
   @Test
   public void not_allowed_to_call_on_twice() {
index 6b380a0c6b70186d3de24a0897c7f22b3bb9f913..72a8d672473da234249ea0de9e4a6839b4cc333d 100644 (file)
  */
 package org.sonar.api.batch.sensor.issue.internal;
 
-import java.io.StringReader;
 import org.junit.Test;
 import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.rule.RuleKey;
@@ -35,7 +34,9 @@ import static org.mockito.Mockito.verify;
 
 public class DefaultIssueTest {
 
-  private DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php").initMetadata(new FileMetadata().readMetadata(new StringReader("Foo\nBar\n")));
+  private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php")
+    .initMetadata("Foo\nBar\n")
+    .build();
 
   @Test
   public void build_file_issue() {
index 15023eb803cc0b09cfd5c06516a75b241b974f1a..8443c8b401f9f69ecc045c15f184eeb25deac542 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.measures.CoreMetrics;
 
@@ -41,10 +42,10 @@ public class DefaultMeasureTest {
     SensorStorage storage = mock(SensorStorage.class);
     DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(storage)
       .forMetric(CoreMetrics.LINES)
-      .on(new DefaultInputFile("foo", "src/Foo.php"))
+      .on(new TestInputFileBuilder("foo", "src/Foo.php").build())
       .withValue(3);
 
-    assertThat(newMeasure.inputComponent()).isEqualTo(new DefaultInputFile("foo", "src/Foo.php"));
+    assertThat(newMeasure.inputComponent()).isEqualTo(new TestInputFileBuilder("foo", "src/Foo.php").build());
     assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES);
     assertThat(newMeasure.value()).isEqualTo(3);
 
@@ -77,7 +78,7 @@ public class DefaultMeasureTest {
     thrown.expectMessage("on() already called");
     new DefaultMeasure<Integer>()
       .on(new DefaultInputModule("foo"))
-      .on(new DefaultInputFile("foo", "src/Foo.php"))
+      .on(new TestInputFileBuilder("foo", "src/Foo.php").build())
       .withValue(3)
       .save();
   }
index ee7ba4c0b205ecb74540eecd2ced686b23879ee0..65706305e79d2d7a3b8b41c397bb4fb2f1466f95 100644 (file)
@@ -25,8 +25,9 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -34,10 +35,11 @@ import static org.mockito.Mockito.mock;
 
 public class DefaultSymbolTableTest {
 
-  private static final DefaultInputFile INPUT_FILE = new DefaultInputFile("foo", "src/Foo.java")
+  private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java")
     .setLines(2)
     .setOriginalLineOffsets(new int[] {0, 50})
-    .setLastValidOffset(100);
+    .setLastValidOffset(100)
+    .build();
 
   private Map<TextRange, Set<TextRange>> referencesPerSymbol;
 
index bac3c9b688864e02b60c9836b8fce45ce8925367..0cec7c50bd1e8273a9c9ffa9502e5dd9553ba1e5 100644 (file)
@@ -24,7 +24,7 @@ import com.google.common.collect.Multimap;
 import java.util.Collection;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.lang.ObjectUtils;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.FileMetadata;
 
 /**
@@ -50,7 +50,7 @@ public final class FileHashes {
     return new FileHashes(hashes, linesByHash);
   }
 
-  public static FileHashes create(DefaultInputFile f) {
+  public static FileHashes create(InputFile f) {
     final byte[][] hashes = new byte[f.lines()][];
     FileMetadata.computeLineHashesForIssueTracking(f,
       (lineIdx, hash) -> hashes[lineIdx - 1] = hash);
index b0183caa188abb53ff9181df9e957a64ba7d8ce1..e83785cf44b056b5013ab77980697d4d27e49005 100644 (file)
@@ -30,6 +30,7 @@ import java.util.Map;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.rule.ActiveRule;
@@ -128,7 +129,7 @@ public class LocalIssueTracking {
 
   private boolean shouldCopyServerIssues(BatchComponent component) {
     if (!mode.scanAllFiles() && component.isFile()) {
-      DefaultInputFile inputFile = (DefaultInputFile) component.inputComponent();
+      InputFile inputFile = (InputFile) component.inputComponent();
       if (inputFile.status() == Status.SAME) {
         return true;
       }
index 7c569227b1436e6f48ecbdd4b63c8ecb8510fcd1..06c4893d6ea609d5327112122c6c6a095bad544e 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.scanner.report;
 import org.apache.commons.io.ByteOrderMark;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.input.BOMInputStream;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.scanner.index.BatchComponent;
 import org.sonar.scanner.index.BatchComponentCache;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
@@ -49,7 +49,7 @@ public class SourcePublisher implements ReportPublisherStep {
         continue;
       }
 
-      DefaultInputFile inputFile = (DefaultInputFile) resource.inputComponent();
+      InputFile inputFile = (InputFile) resource.inputComponent();
       File iofile = writer.getSourceFile(resource.batchId());
       int line = 0;
       try (FileOutputStream output = new FileOutputStream(iofile); BOMInputStream bomIn = new BOMInputStream(new FileInputStream(inputFile.file()),
index 1033130b96168260e8d9c9837a35b4a4b3986dcf..fa31b9c74195dd31b3abeca91b1caf4096cdfd0f 100644 (file)
@@ -64,7 +64,8 @@ import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
 import org.sonar.scanner.scan.filesystem.ExclusionFilters;
 import org.sonar.scanner.scan.filesystem.FileIndexer;
 import org.sonar.scanner.scan.filesystem.FileSystemLogger;
-import org.sonar.scanner.scan.filesystem.InputFileBuilderFactory;
+import org.sonar.scanner.scan.filesystem.IndexedFileBuilderProvider;
+import org.sonar.scanner.scan.filesystem.MetadataGeneratorProvider;
 import org.sonar.scanner.scan.filesystem.LanguageDetectionFactory;
 import org.sonar.scanner.scan.filesystem.ModuleFileSystemInitializer;
 import org.sonar.scanner.scan.filesystem.ModuleInputFileCache;
@@ -122,11 +123,12 @@ public class ModuleScanContainer extends ComponentContainer {
       ModuleInputFileCache.class,
       FileExclusions.class,
       ExclusionFilters.class,
-      InputFileBuilderFactory.class,
+      new MetadataGeneratorProvider(),
       FileMetadata.class,
       StatusDetectionFactory.class,
       LanguageDetectionFactory.class,
       FileIndexer.class,
+      new IndexedFileBuilderProvider(),
       ComponentIndexer.class,
       LanguageVerifier.class,
       FileSystemLogger.class,
index 77e1bc39827a66dd0006814ce5d1d38266c5fae3..713ca7a3d89baef557e1415629c41d5a3cbdedbd 100644 (file)
@@ -19,9 +19,8 @@
  */
 package org.sonar.scanner.scan.filesystem;
 
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.internal.AbstractFilePredicate;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 
 /**
  * Additional {@link org.sonar.api.batch.fs.FilePredicate}s that are
@@ -41,8 +40,8 @@ class AdditionalFilePredicates {
     }
 
     @Override
-    public boolean apply(InputFile f) {
-      return key.equals(((DefaultInputFile) f).key());
+    public boolean apply(IndexedFile f) {
+      return key.equals(f.key());
     }
   }
 
index fc2c46cfb6fc895410fe81e61ec9dfbde0b4eb5f..03b9fb9285ec32affe4fa505052339be4b5271c7 100644 (file)
@@ -26,12 +26,12 @@ import java.nio.charset.Charset;
 import java.util.List;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.MessageException;
 import org.sonar.scanner.analysis.DefaultAnalysisMode;
+import org.sonar.scanner.repository.ProjectRepositories;
 
 /**
  * @since 3.5
@@ -46,22 +46,26 @@ public class DefaultModuleFileSystem extends DefaultFileSystem {
   private List<File> testDirsOrFiles = Lists.newArrayList();
   private ComponentIndexer componentIndexer;
   private boolean initialized;
+  private Charset charset = null;
 
   public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, Project project,
-    Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode) {
+    Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode,
+    ProjectRepositories projectRepositories) {
     super(initializer.baseDir(), moduleInputFileCache);
-    setFields(project, settings, indexer, initializer, componentIndexer, mode);
+    setFields(project, settings, indexer, initializer, componentIndexer, mode, projectRepositories);
   }
 
   @VisibleForTesting
   public DefaultModuleFileSystem(Project project,
-    Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode) {
+    Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode,
+    ProjectRepositories projectRepositories) {
     super(initializer.baseDir().toPath());
-    setFields(project, settings, indexer, initializer, componentIndexer, mode);
+    setFields(project, settings, indexer, initializer, componentIndexer, mode, projectRepositories);
   }
 
   private void setFields(Project project,
-    Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode) {
+    Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode,
+    ProjectRepositories projectRepositories) {
     this.componentIndexer = componentIndexer;
     this.moduleKey = project.getKey();
     this.settings = settings;
@@ -72,7 +76,7 @@ public class DefaultModuleFileSystem extends DefaultFileSystem {
 
     // filter the files sensors have access to
     if (!mode.scanAllFiles()) {
-      setDefaultPredicate(predicates.not(predicates.hasStatus(Status.SAME)));
+      setDefaultPredicate(new SameInputFilePredicate(projectRepositories, moduleKey));
     }
   }
 
@@ -94,12 +98,13 @@ public class DefaultModuleFileSystem extends DefaultFileSystem {
 
   @Override
   public Charset encoding() {
-    final Charset charset;
-    String encoding = settings.getString(CoreProperties.ENCODING_PROPERTY);
-    if (StringUtils.isNotEmpty(encoding)) {
-      charset = Charset.forName(StringUtils.trim(encoding));
-    } else {
-      charset = Charset.defaultCharset();
+    if (charset == null) {
+      String encoding = settings.getString(CoreProperties.ENCODING_PROPERTY);
+      if (StringUtils.isNotEmpty(encoding)) {
+        charset = Charset.forName(StringUtils.trim(encoding));
+      } else {
+        charset = Charset.defaultCharset();
+      }
     }
     return charset;
   }
index 2d7975e7ea3820e234682e5c7ed840b8316b55bf..e0dfdd1c5dd7993a0ce42ef5343cfa8880d85112 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.commons.lang.ArrayUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.PathPattern;
 import org.sonar.api.scan.filesystem.FileExclusions;
@@ -67,7 +68,7 @@ public class ExclusionFilters {
     }
   }
 
-  public boolean accept(InputFile inputFile, InputFile.Type type) {
+  public boolean accept(IndexedFile indexedFile, InputFile.Type type) {
     PathPattern[] inclusionPatterns;
     PathPattern[] exclusionPatterns;
     if (InputFile.Type.MAIN == type) {
@@ -83,7 +84,7 @@ public class ExclusionFilters {
     if (inclusionPatterns.length > 0) {
       boolean matchInclusion = false;
       for (PathPattern pattern : inclusionPatterns) {
-        matchInclusion |= pattern.match(inputFile);
+        matchInclusion |= pattern.match(indexedFile);
       }
       if (!matchInclusion) {
         return false;
@@ -91,7 +92,7 @@ public class ExclusionFilters {
     }
     if (exclusionPatterns.length > 0) {
       for (PathPattern pattern : exclusionPatterns) {
-        if (pattern.match(inputFile)) {
+        if (pattern.match(indexedFile)) {
           return false;
         }
       }
index 13aa962ccca90b53c2467415bac6b5527167a84b..595773f62b536a76ed798850f0b45d78963d6e76 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.scanner.scan.filesystem;
 
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.FileSystemLoopException;
@@ -30,26 +29,23 @@ import java.nio.file.Files;
 import java.nio.file.LinkOption;
 import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.ScannerSide;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputFile.Type;
-import org.sonar.api.batch.fs.InputFileFilter;
+import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
 import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.api.batch.fs.InputFileFilter;
 import org.sonar.api.utils.MessageException;
 import org.sonar.scanner.util.ProgressReport;
 
@@ -63,21 +59,22 @@ public class FileIndexer {
   private final InputFileFilter[] filters;
   private final boolean isAggregator;
   private final ExclusionFilters exclusionFilters;
-  private final InputFileBuilderFactory inputFileBuilderFactory;
 
   private ProgressReport progressReport;
-  private ExecutorService executorService;
-  private List<Future<Void>> tasks;
+  private IndexedFileBuilder indexedFileBuilder;
+  private MetadataGenerator metadataGenerator;
 
-  public FileIndexer(ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory, ProjectDefinition def, InputFileFilter[] filters) {
+  public FileIndexer(ExclusionFilters exclusionFilters, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def,
+    InputFileFilter[] filters) {
+    this.indexedFileBuilder = indexedFileBuilder;
+    this.metadataGenerator = inputFileBuilder;
     this.filters = filters;
     this.exclusionFilters = exclusionFilters;
-    this.inputFileBuilderFactory = inputFileBuilderFactory;
     this.isAggregator = !def.getSubProjects().isEmpty();
   }
 
-  public FileIndexer(ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory, ProjectDefinition def) {
-    this(exclusionFilters, inputFileBuilderFactory, def, new InputFileFilter[0]);
+  public FileIndexer(ExclusionFilters exclusionFilters, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def) {
+    this(exclusionFilters, indexedFileBuilder, inputFileBuilder, def, new InputFileFilter[0]);
   }
 
   void index(DefaultModuleFileSystem fileSystem) {
@@ -91,14 +88,8 @@ public class FileIndexer {
 
     Progress progress = new Progress();
 
-    InputFileBuilder inputFileBuilder = inputFileBuilderFactory.create(fileSystem);
-    int threads = Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
-    executorService = Executors.newFixedThreadPool(threads, new ThreadFactoryBuilder().setNameFormat("FileIndexer-%d").build());
-    tasks = new ArrayList<>();
-    indexFiles(fileSystem, progress, inputFileBuilder, fileSystem.sources(), InputFile.Type.MAIN);
-    indexFiles(fileSystem, progress, inputFileBuilder, fileSystem.tests(), InputFile.Type.TEST);
-
-    waitForTasksToComplete();
+    indexFiles(fileSystem, progress, fileSystem.sources(), InputFile.Type.MAIN);
+    indexFiles(fileSystem, progress, fileSystem.tests(), InputFile.Type.TEST);
 
     progressReport.stop(progress.count() + " files indexed");
 
@@ -107,27 +98,13 @@ public class FileIndexer {
     }
   }
 
-  private void waitForTasksToComplete() {
-    executorService.shutdown();
-    for (Future<Void> task : tasks) {
-      try {
-        task.get();
-      } catch (ExecutionException e) {
-        // Unwrap ExecutionException
-        throw e.getCause() instanceof RuntimeException ? (RuntimeException) e.getCause() : new IllegalStateException(e.getCause());
-      } catch (InterruptedException e) {
-        throw new IllegalStateException(e);
-      }
-    }
-  }
-
-  private void indexFiles(DefaultModuleFileSystem fileSystem, Progress progress, InputFileBuilder inputFileBuilder, List<File> sources, InputFile.Type type) {
+  private void indexFiles(DefaultModuleFileSystem fileSystem, Progress progress, List<File> sources, InputFile.Type type) {
     try {
       for (File dirOrFile : sources) {
         if (dirOrFile.isDirectory()) {
-          indexDirectory(inputFileBuilder, fileSystem, progress, dirOrFile, type);
+          indexDirectory(fileSystem, progress, dirOrFile, type);
         } else {
-          indexFile(inputFileBuilder, fileSystem, progress, dirOrFile.toPath(), type);
+          indexFile(fileSystem, progress, dirOrFile.toPath(), type);
         }
       }
     } catch (IOException e) {
@@ -135,57 +112,45 @@ public class FileIndexer {
     }
   }
 
-  private void indexDirectory(final InputFileBuilder inputFileBuilder, final DefaultModuleFileSystem fileSystem, final Progress status,
-    final File dirToIndex, final InputFile.Type type) throws IOException {
+  private void indexDirectory(final DefaultModuleFileSystem fileSystem, final Progress status, final File dirToIndex, final InputFile.Type type) throws IOException {
     Files.walkFileTree(dirToIndex.toPath().normalize(), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
-      new IndexFileVisitor(inputFileBuilder, fileSystem, status, type));
+      new IndexFileVisitor(fileSystem, status, type));
   }
 
-  private void indexFile(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress progress, Path sourceFile, InputFile.Type type) throws IOException {
+  private void indexFile(DefaultModuleFileSystem fileSystem, Progress progress, Path sourceFile, InputFile.Type type) throws IOException {
     // get case of real file without resolving link
     Path realFile = sourceFile.toRealPath(LinkOption.NOFOLLOW_LINKS);
-    DefaultInputFile inputFile = inputFileBuilder.create(realFile.toFile());
-    if (inputFile != null) {
-      // Set basedir on input file prior to adding it to the FS since exclusions filters may require the absolute path
-      inputFile.setModuleBaseDir(fileSystem.baseDirPath());
-      if (exclusionFilters.accept(inputFile, type)) {
-        indexFile(inputFileBuilder, fileSystem, progress, inputFile, type);
+    DefaultIndexedFile indexedFile = indexedFileBuilder.create(realFile, type, fileSystem.baseDirPath());
+    if (indexedFile != null) {
+      if (exclusionFilters.accept(indexedFile, type)) {
+        InputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.readMetadata(f, fileSystem.encoding()));
+        if (accept(inputFile)) {
+          fileSystem.add(inputFile);
+        }
+        indexParentDir(fileSystem, indexedFile);
+        progress.markAsIndexed(indexedFile);
+        LOG.debug("'{}' indexed {} with language '{}'", indexedFile.relativePath(), type == Type.TEST ? "as test " : "", indexedFile.language());
       } else {
         progress.increaseExcludedByPatternsCount();
       }
     }
   }
 
-  private void indexFile(final InputFileBuilder inputFileBuilder, final DefaultModuleFileSystem fs,
-    final Progress status, final DefaultInputFile inputFile, final InputFile.Type type) {
-
-    tasks.add(executorService.submit(() -> {
-      DefaultInputFile completedInputFile = inputFileBuilder.completeAndComputeMetadata(inputFile, type);
-      if (completedInputFile != null && accept(completedInputFile)) {
-        LOG.debug("'{}' indexed {}with language '{}' and charset '{}'",
-          inputFile.relativePath(),
-          type == Type.TEST ? "as test " : "",
-          inputFile.language(),
-          inputFile.charset());
-        fs.add(completedInputFile);
-        status.markAsIndexed(completedInputFile);
-        File parentDir = completedInputFile.file().getParentFile();
-        String relativePath = new PathResolver().relativePath(fs.baseDir(), parentDir);
-        if (relativePath != null) {
-          DefaultInputDir inputDir = new DefaultInputDir(fs.moduleKey(), relativePath);
-          fs.add(inputDir);
-        }
-      }
-      return null;
-    }));
-
+  private void indexParentDir(DefaultModuleFileSystem fileSystem, IndexedFile indexedFile) {
+    File parentDir = indexedFile.file().getParentFile();
+    String relativePath = new PathResolver().relativePath(fileSystem.baseDir(), parentDir);
+    if (relativePath != null) {
+      DefaultInputDir inputDir = new DefaultInputDir(fileSystem.moduleKey(), relativePath);
+      inputDir.setModuleBaseDir(fileSystem.baseDirPath());
+      fileSystem.add(inputDir);
+    }
   }
 
-  private boolean accept(InputFile inputFile) {
+  private boolean accept(InputFile indexedFile) {
     // InputFileFilter extensions
     for (InputFileFilter filter : filters) {
-      if (!filter.accept(inputFile)) {
-        LOG.debug("'{}' excluded by {}", inputFile.relativePath(), filter.getClass().getName());
+      if (!filter.accept(indexedFile)) {
+        LOG.debug("'{}' excluded by {}", indexedFile.relativePath(), filter.getClass().getName());
         return false;
       }
     }
@@ -193,13 +158,11 @@ public class FileIndexer {
   }
 
   private class IndexFileVisitor implements FileVisitor<Path> {
-    private InputFileBuilder inputFileBuilder;
     private DefaultModuleFileSystem fileSystem;
     private Progress status;
     private Type type;
 
-    IndexFileVisitor(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress status, InputFile.Type type) {
-      this.inputFileBuilder = inputFileBuilder;
+    IndexFileVisitor(DefaultModuleFileSystem fileSystem, Progress status, InputFile.Type type) {
       this.fileSystem = fileSystem;
       this.status = status;
       this.type = type;
@@ -221,7 +184,7 @@ public class FileIndexer {
     @Override
     public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
       if (!Files.isHidden(file)) {
-        indexFile(inputFileBuilder, fileSystem, status, file, type);
+        indexFile(fileSystem, status, file, type);
       }
       return FileVisitResult.CONTINUE;
     }
@@ -246,7 +209,7 @@ public class FileIndexer {
     private final Set<Path> indexed = new HashSet<>();
     private int excludedByPatternsCount = 0;
 
-    synchronized void markAsIndexed(InputFile inputFile) {
+    synchronized void markAsIndexed(IndexedFile inputFile) {
       if (indexed.contains(inputFile.path())) {
         throw MessageException.of("File " + inputFile + " can't be indexed twice. Please check that inclusion/exclusion patterns produce "
           + "disjoint sets for main and test files");
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java
new file mode 100644 (file)
index 0000000..352065d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import java.nio.file.Path;
+
+import javax.annotation.CheckForNull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
+import org.sonar.api.config.Settings;
+import org.sonar.api.scan.filesystem.PathResolver;
+
+public class IndexedFileBuilder {
+  private static final Logger LOG = LoggerFactory.getLogger(IndexedFileBuilder.class);
+  private final String moduleKey;
+  private final PathResolver pathResolver;
+  private final LanguageDetection langDetection;
+  private final Settings settings;
+
+  IndexedFileBuilder(String moduleKey, PathResolver pathResolver, Settings settings, LanguageDetection langDetection) {
+    this.moduleKey = moduleKey;
+    this.pathResolver = pathResolver;
+    this.settings = settings;
+    this.langDetection = langDetection;
+  }
+
+  @CheckForNull
+  DefaultIndexedFile create(Path file, InputFile.Type type, Path moduleBaseDir) {
+    String relativePath = pathResolver.relativePath(moduleBaseDir, file);
+    if (relativePath == null) {
+      LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", file.toAbsolutePath(), moduleBaseDir);
+      return null;
+    }
+    DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type);
+    String language = langDetection.language(indexedFile);
+    if (language == null && !settings.getBoolean(CoreProperties.IMPORT_UNKNOWN_FILES_KEY)) {
+      LOG.debug("'{}' language is not supported by any analyzer. Skipping it.", relativePath);
+      return null;
+    }
+
+    indexedFile.setLanguage(language);
+    return indexedFile;
+  }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java
new file mode 100644 (file)
index 0000000..c892bf9
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import org.picocontainer.injectors.ProviderAdapter;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.config.Settings;
+import org.sonar.api.scan.filesystem.PathResolver;
+
+public class IndexedFileBuilderProvider extends ProviderAdapter {
+
+  public IndexedFileBuilder provide(ProjectDefinition def, PathResolver pathResolver, Settings settings, LanguageDetectionFactory langDetectionFactory) {
+    return new IndexedFileBuilder(def.getKeyWithBranch(), pathResolver, settings, langDetectionFactory.create());
+  }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java
deleted file mode 100644 (file)
index 0cdf970..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.scan.filesystem;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import javax.annotation.CheckForNull;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.FileMetadata;
-import org.sonar.api.config.Settings;
-import org.sonar.api.scan.filesystem.PathResolver;
-
-class InputFileBuilder {
-
-  private static final Logger LOG = LoggerFactory.getLogger(InputFileBuilder.class);
-
-  @VisibleForTesting
-  static final Charset UTF_32BE = Charset.forName("UTF-32BE");
-
-  @VisibleForTesting
-  static final Charset UTF_32LE = Charset.forName("UTF-32LE");
-
-  private final String moduleKey;
-  private final PathResolver pathResolver;
-  private final LanguageDetection langDetection;
-  private final StatusDetection statusDetection;
-  private final DefaultModuleFileSystem fs;
-  private final Settings settings;
-  private final FileMetadata fileMetadata;
-
-  InputFileBuilder(String moduleKey, PathResolver pathResolver, LanguageDetection langDetection,
-    StatusDetection statusDetection, DefaultModuleFileSystem fs, Settings settings, FileMetadata fileMetadata) {
-    this.moduleKey = moduleKey;
-    this.pathResolver = pathResolver;
-    this.langDetection = langDetection;
-    this.statusDetection = statusDetection;
-    this.fs = fs;
-    this.settings = settings;
-    this.fileMetadata = fileMetadata;
-  }
-
-  String moduleKey() {
-    return moduleKey;
-  }
-
-  PathResolver pathResolver() {
-    return pathResolver;
-  }
-
-  LanguageDetection langDetection() {
-    return langDetection;
-  }
-
-  StatusDetection statusDetection() {
-    return statusDetection;
-  }
-
-  FileSystem fs() {
-    return fs;
-  }
-
-  @CheckForNull
-  DefaultInputFile create(File file) {
-    String relativePath = pathResolver.relativePath(fs.baseDir(), file);
-    if (relativePath == null) {
-      LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", file.getAbsolutePath(), fs.baseDir());
-      return null;
-    }
-    return new DefaultInputFile(moduleKey, relativePath);
-  }
-
-  /**
-   * Optimization to not compute InputFile metadata if the file is excluded from analysis.
-   */
-  @CheckForNull
-  DefaultInputFile completeAndComputeMetadata(DefaultInputFile inputFile, InputFile.Type type) {
-    inputFile.setType(type);
-    inputFile.setModuleBaseDir(fs.baseDir().toPath());
-
-    String lang = langDetection.language(inputFile);
-    if (lang == null && !settings.getBoolean(CoreProperties.IMPORT_UNKNOWN_FILES_KEY)) {
-      // Return fast to skip costly metadata computation
-      LOG.debug("'{}' language is not supported by any analyzer. Skipping it.", inputFile.relativePath());
-      return null;
-    }
-    inputFile.setLanguage(lang);
-
-    Charset charset = detectCharset(inputFile.file(), fs.encoding());
-    inputFile.setCharset(charset);
-
-    inputFile.initMetadata(fileMetadata.readMetadata(inputFile.file(), charset));
-
-    inputFile.setStatus(statusDetection.status(inputFile.moduleKey(), inputFile.relativePath(), inputFile.hash()));
-
-    return inputFile;
-  }
-
-  /**
-   * @return charset detected from BOM in given file or given defaultCharset
-   * @throws IllegalStateException if an I/O error occurs
-   */
-  private static Charset detectCharset(File file, Charset defaultCharset) {
-    try (FileInputStream inputStream = new FileInputStream(file)) {
-      byte[] bom = new byte[4];
-      int n = inputStream.read(bom, 0, bom.length);
-      if ((n >= 3) && (bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
-        return StandardCharsets.UTF_8;
-      } else if ((n >= 4) && (bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
-        return UTF_32BE;
-      } else if ((n >= 4) && (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
-        return UTF_32LE;
-      } else if ((n >= 2) && (bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
-        return StandardCharsets.UTF_16BE;
-      } else if ((n >= 2) && (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
-        return StandardCharsets.UTF_16LE;
-      } else {
-        return defaultCharset;
-      }
-    } catch (IOException e) {
-      throw new IllegalStateException("Unable to read file " + file.getAbsolutePath(), e);
-    }
-  }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactory.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactory.java
deleted file mode 100644 (file)
index 3104845..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.scan.filesystem;
-
-import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.fs.internal.FileMetadata;
-import org.sonar.api.config.Settings;
-import org.sonar.api.scan.filesystem.PathResolver;
-
-@ScannerSide
-public class InputFileBuilderFactory {
-
-  private final String moduleKey;
-  private final PathResolver pathResolver;
-  private final LanguageDetectionFactory langDetectionFactory;
-  private final StatusDetectionFactory statusDetectionFactory;
-  private final Settings settings;
-  private final FileMetadata fileMetadata;
-
-  public InputFileBuilderFactory(ProjectDefinition def, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory,
-    StatusDetectionFactory statusDetectionFactory, Settings settings, FileMetadata fileMetadata) {
-    this.fileMetadata = fileMetadata;
-    this.moduleKey = def.getKeyWithBranch();
-    this.pathResolver = pathResolver;
-    this.langDetectionFactory = langDetectionFactory;
-    this.statusDetectionFactory = statusDetectionFactory;
-    this.settings = settings;
-  }
-
-  InputFileBuilder create(DefaultModuleFileSystem fs) {
-    return new InputFileBuilder(moduleKey, pathResolver, langDetectionFactory.create(), statusDetectionFactory.create(), fs, settings, fileMetadata);
-  }
-}
index 10708b1d392e9bf0aaba8035c24a9b54f3a1da0a..b83402a77332d497588d1c10cd07d8c6718916cd 100644 (file)
@@ -30,7 +30,7 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
 import org.sonar.api.batch.fs.internal.PathPattern;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.MessageException;
@@ -88,7 +88,7 @@ class LanguageDetection {
   }
 
   @CheckForNull
-  String language(InputFile inputFile) {
+  String language(DefaultIndexedFile inputFile) {
     String detectedLanguage = null;
     for (String languageKey : languagesToConsider) {
       if (isCandidateForLanguage(inputFile, languageKey)) {
@@ -113,7 +113,7 @@ class LanguageDetection {
     return null;
   }
 
-  private boolean isCandidateForLanguage(InputFile inputFile, String languageKey) {
+  private boolean isCandidateForLanguage(DefaultIndexedFile inputFile, String languageKey) {
     PathPattern[] patterns = patternsByLanguage.get(languageKey);
     if (patterns != null) {
       for (PathPattern pathPattern : patterns) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
new file mode 100644 (file)
index 0000000..5468bd7
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.fs.internal.Metadata;
+
+class MetadataGenerator {
+  private static final Logger LOG = LoggerFactory.getLogger(MetadataGenerator.class);
+  @VisibleForTesting
+  static final Charset UTF_32BE = Charset.forName("UTF-32BE");
+
+  @VisibleForTesting
+  static final Charset UTF_32LE = Charset.forName("UTF-32LE");
+
+  private final StatusDetection statusDetection;
+  private final FileMetadata fileMetadata;
+
+  MetadataGenerator(StatusDetection statusDetection, FileMetadata fileMetadata) {
+    this.statusDetection = statusDetection;
+    this.fileMetadata = fileMetadata;
+  }
+
+  /**
+   * @return charset detected from BOM in given file or given defaultCharset
+   * @throws IllegalStateException if an I/O error occurs
+   */
+  private static Charset detectCharset(File file, Charset defaultCharset) {
+    try (FileInputStream inputStream = new FileInputStream(file)) {
+      byte[] bom = new byte[4];
+      int n = inputStream.read(bom, 0, bom.length);
+      if ((n >= 3) && (bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
+        return StandardCharsets.UTF_8;
+      } else if ((n >= 4) && (bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
+        return UTF_32BE;
+      } else if ((n >= 4) && (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
+        return UTF_32LE;
+      } else if ((n >= 2) && (bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
+        return StandardCharsets.UTF_16BE;
+      } else if ((n >= 2) && (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
+        return StandardCharsets.UTF_16LE;
+      } else {
+        return defaultCharset;
+      }
+    } catch (IOException e) {
+      throw new IllegalStateException("Unable to read file " + file.getAbsolutePath(), e);
+    }
+  }
+
+  public Metadata readMetadata(final DefaultInputFile inputFile, Charset defaultEncoding) {
+    try {
+      Charset charset = detectCharset(inputFile.file(), defaultEncoding);
+      inputFile.setCharset(charset);
+      Metadata metadata = fileMetadata.readMetadata(inputFile.file(), charset);
+      inputFile.setStatus(statusDetection.status(inputFile.moduleKey(), inputFile.relativePath(), metadata.hash()));
+      LOG.debug("'{}' generated metadata {} with and charset '{}'",
+        inputFile.relativePath(), inputFile.type() == Type.TEST ? "as test " : "", charset);
+      return metadata;
+    } catch (Exception e) {
+      throw new IllegalStateException(e);
+    }
+  }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java
new file mode 100644 (file)
index 0000000..13bfd48
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import org.picocontainer.injectors.ProviderAdapter;
+import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.internal.FileMetadata;
+
+@ScannerSide
+public class MetadataGeneratorProvider extends ProviderAdapter {
+  public MetadataGenerator provide(StatusDetectionFactory statusDetectionFactory, FileMetadata fileMetadata) {
+    return new MetadataGenerator(statusDetectionFactory.create(), fileMetadata);
+  }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java
new file mode 100644 (file)
index 0000000..5ec4130
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.InputFilePredicate;
+import org.sonar.scanner.repository.FileData;
+import org.sonar.scanner.repository.ProjectRepositories;
+
+public class SameInputFilePredicate implements InputFilePredicate {
+  private static final Logger LOG = LoggerFactory.getLogger(SameInputFilePredicate.class);
+  private final ProjectRepositories projectRepositories;
+  private final String moduleKey;
+
+  public SameInputFilePredicate(ProjectRepositories projectRepositories, String moduleKey) {
+    this.projectRepositories = projectRepositories;
+    this.moduleKey = moduleKey;
+  }
+
+  @Override
+  public boolean apply(InputFile inputFile) {
+    FileData fileDataPerPath = projectRepositories.fileData(moduleKey, inputFile.relativePath());
+    if (fileDataPerPath == null) {
+      // ADDED
+      return true;
+    }
+    String previousHash = fileDataPerPath.hash();
+    if (StringUtils.isEmpty(previousHash)) {
+      // ADDED
+      return true;
+    }
+
+    // this will trigger computation of metadata
+    String hash = ((DefaultInputFile) inputFile).hash();
+    if (StringUtils.equals(hash, previousHash)) {
+      // SAME
+      LOG.debug("'{}' filtering unmodified file", inputFile.relativePath());
+      return false;
+    }
+
+    // CHANGED
+    return true;
+  }
+
+}
index 218754a197d010f45bcb3893fe14bb3685c7339e..8beba97adae615c0e018386f439ab292e54e4bdd 100644 (file)
@@ -33,7 +33,6 @@ import java.util.stream.Stream;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.measure.Metric;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
@@ -353,7 +352,7 @@ public class DefaultSensorStorage implements SensorStorage {
   @Override
   public void store(DefaultHighlighting highlighting) {
     ScannerReportWriter writer = reportPublisher.getWriter();
-    DefaultInputFile inputFile = (DefaultInputFile) highlighting.inputFile();
+    InputFile inputFile = highlighting.inputFile();
     int componentRef = componentCache.get(inputFile).batchId();
     if (writer.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, componentRef)) {
       throw new UnsupportedOperationException("Trying to save highlighting twice for the same file is not supported: " + inputFile.absolutePath());
index 357ae80d80117f3317b90846910d5ceebec66ade..5d9795f042da61d26591e012170504ad81c5818b 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.scanner.source;
 
 import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
@@ -32,11 +32,11 @@ import org.sonar.api.source.Highlightable;
 public class DefaultHighlightable implements Highlightable {
 
   private static final HighlightingBuilder NO_OP_BUILDER = new NoOpHighlightingBuilder();
-  private final DefaultInputFile inputFile;
+  private final InputFile inputFile;
   private final SensorStorage sensorStorage;
   private final AnalysisMode analysisMode;
 
-  public DefaultHighlightable(DefaultInputFile inputFile, SensorStorage sensorStorage, AnalysisMode analysisMode) {
+  public DefaultHighlightable(InputFile inputFile, SensorStorage sensorStorage, AnalysisMode analysisMode) {
     this.inputFile = inputFile;
     this.sensorStorage = sensorStorage;
     this.analysisMode = analysisMode;
index f14604292d7c11b600ce896ab02d5dc91c9aaf3c..e2b6f3b43914dd836fbc32780822e31a63f0e7ff 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.scanner.source;
 import java.util.Collections;
 import java.util.List;
 import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.source.Symbol;
 import org.sonar.api.source.Symbolizable;
@@ -95,11 +95,11 @@ public class DefaultSymbolizable implements Symbolizable {
     }
   }
 
-  private final DefaultInputFile inputFile;
+  private final InputFile inputFile;
   private final DefaultSensorStorage sensorStorage;
   private final AnalysisMode analysisMode;
 
-  public DefaultSymbolizable(DefaultInputFile inputFile, DefaultSensorStorage sensorStorage, AnalysisMode analysisMode) {
+  public DefaultSymbolizable(InputFile inputFile, DefaultSensorStorage sensorStorage, AnalysisMode analysisMode) {
     this.inputFile = inputFile;
     this.sensorStorage = sensorStorage;
     this.analysisMode = analysisMode;
index da793d3e9815ad6d3e3664b194911078c536192e..e1e598408e857451af8ff0a063d132e72cbba4da 100644 (file)
@@ -23,7 +23,6 @@ import javax.annotation.CheckForNull;
 import org.sonar.api.batch.AnalysisMode;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.source.Highlightable;
 import org.sonar.scanner.deprecated.perspectives.PerspectiveBuilder;
@@ -44,7 +43,7 @@ public class HighlightableBuilder extends PerspectiveBuilder<Highlightable> {
   public Highlightable loadPerspective(Class<Highlightable> perspectiveClass, InputComponent component) {
     if (component.isFile()) {
       InputFile path = (InputFile) component;
-      return new DefaultHighlightable((DefaultInputFile) path, sensorStorage, analysisMode);
+      return new DefaultHighlightable(path, sensorStorage, analysisMode);
     }
     return null;
   }
index 6017d05ca7e643668a5ab6c88c744e24dbefc3a5..726eec05aa314c0057db58e26088560b15ee134c 100644 (file)
@@ -30,7 +30,7 @@ import org.sonar.api.batch.sensor.SensorDescriptor;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.measures.CoreMetrics;
 
-@Phase(name = Phase.Name.PRE)
+@Phase(name = Phase.Name.POST)
 public final class LinesSensor implements Sensor {
 
   @Override
index 947670bf769b7c0fc5dd3af015f3f168805960d2..d85fff4faea4f635f2388d37ede06d2b38f82111 100644 (file)
@@ -23,7 +23,6 @@ import javax.annotation.CheckForNull;
 import org.sonar.api.batch.AnalysisMode;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.source.Symbolizable;
 import org.sonar.scanner.deprecated.perspectives.PerspectiveBuilder;
 import org.sonar.scanner.sensor.DefaultSensorStorage;
@@ -44,7 +43,7 @@ public class SymbolizableBuilder extends PerspectiveBuilder<Symbolizable> {
   public Symbolizable loadPerspective(Class<Symbolizable> perspectiveClass, InputComponent component) {
     if (component.isFile()) {
       InputFile path = (InputFile) component;
-      return new DefaultSymbolizable((DefaultInputFile) path, sensorStorage, analysisMode);
+      return new DefaultSymbolizable(path, sensorStorage, analysisMode);
     }
     return null;
   }
index 37d74deeb2474d9920e8ded1c78162a7e4effb74..0eedca4075549b352fc14e42b5647a7ea6a218a1 100644 (file)
@@ -24,7 +24,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
@@ -78,7 +78,7 @@ public class DefaultFileLinesContextTest {
     when(metricFinder.<String>findByKey(CoreMetrics.EXECUTABLE_LINES_DATA_KEY)).thenReturn(CoreMetrics.EXECUTABLE_LINES_DATA);
     when(metricFinder.<String>findByKey(CoreMetrics.COMMENT_LINES_DATA_KEY)).thenReturn(CoreMetrics.COMMENT_LINES_DATA);
     measureCache = mock(MeasureCache.class);
-    fileLineMeasures = new DefaultFileLinesContext(sensorContextTester, new DefaultInputFile("foo", "src/foo.php").initMetadata("Foo\nbar\nbiz"), metricFinder,
+    fileLineMeasures = new DefaultFileLinesContext(sensorContextTester, new TestInputFileBuilder("foo", "src/foo.php").initMetadata("Foo\nbar\nbiz").build(), metricFinder,
       measureCache);
   }
 
@@ -95,13 +95,13 @@ public class DefaultFileLinesContextTest {
 
   @Test
   public void validateLineGreaterThanZero() {
-    thrown.expectMessage("Line number should be positive for file [moduleKey=foo, relative=src/foo.php, basedir=null].");
+    thrown.expectMessage("Line number should be positive for file [moduleKey=foo, relative=src/foo.php, basedir=foo].");
     fileLineMeasures.setIntValue(HITS_METRIC_KEY, 0, 2);
   }
 
   @Test
   public void validateLineLowerThanLineCount() {
-    thrown.expectMessage("Line 4 is out of range for file [moduleKey=foo, relative=src/foo.php, basedir=null]. File has 3 lines");
+    thrown.expectMessage("Line 4 is out of range for file [moduleKey=foo, relative=src/foo.php, basedir=foo]. File has 3 lines");
     fileLineMeasures.setIntValue(HITS_METRIC_KEY, 4, 2);
   }
 
index ccf34b15f1867641530c923b2162d56acf4aba55..15545a45716e38edf97e4cfd7b98c8a73fa9647c 100644 (file)
@@ -31,8 +31,8 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 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.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
@@ -102,9 +102,10 @@ public class CpdExecutorTest {
   private BatchComponent createComponent(String relativePath, int lines) {
     org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("relativePath").setEffectiveKey("foo:" + relativePath);
     return componentCache.add(sampleFile, null)
-      .setInputComponent(new DefaultInputFile("foo", relativePath)
+      .setInputComponent(new TestInputFileBuilder("foo", relativePath)
         .setModuleBaseDir(baseDir.toPath())
-        .setLines(lines));
+        .setLines(lines)
+        .build());
   }
 
   @Test
index f43120e5c841753f38c517f26d70ccf7e9222d3f..779083189148e8e517d80696f951ce30ddb87bea 100644 (file)
@@ -33,8 +33,9 @@ import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.config.Settings;
 import org.sonar.api.config.MapSettings;
 import org.sonar.duplications.block.Block;
@@ -58,7 +59,7 @@ public class JavaCpdBlockIndexerTest {
 
   private Settings settings;
   private JavaCpdBlockIndexer engine;
-  private DefaultInputFile file;
+  private InputFile file;
 
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
@@ -69,7 +70,7 @@ public class JavaCpdBlockIndexerTest {
 
     File baseDir = temp.newFolder();
     DefaultFileSystem fs = new DefaultFileSystem(baseDir);
-    file = new DefaultInputFile("foo", "src/ManyStatements.java").setLanguage(JAVA);
+    file = new TestInputFileBuilder("foo", "src/ManyStatements.java").setLanguage(JAVA).build();
     fs.add(file);
     BatchComponentCache batchComponentCache = new BatchComponentCache();
     batchComponentCache.add(org.sonar.api.resources.File.create("src/Foo.java").setEffectiveKey("foo:src/ManyStatements.java"), null).setInputComponent(file);
index fb41e6b2ad9c38e481acf02ca55b9893f5bd10e7..bf3eb736cf4ae4ccdd8d6709916b58c5a0c0e8e5 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -216,9 +217,10 @@ public class GenericCoverageReportParserTest {
   }
 
   private DefaultInputFile setupFile(String path) {
-    return new DefaultInputFile(context.module().key(), path)
+    return new TestInputFileBuilder(context.module().key(), path)
       .setLanguage("bla")
       .setType(InputFile.Type.TEST)
-      .initMetadata("1\n2\n3\n4\n5\n6");
+      .initMetadata("1\n2\n3\n4\n5\n6")
+      .build();
   }
 }
index 3ee34b3f4f09bac379cae8ff6d812c15bec39e60..f9c44a658ddbd21a0ed424680d5e71250e448447 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 import org.sonar.api.test.MutableTestCase;
 import org.sonar.api.test.MutableTestPlan;
@@ -142,10 +143,11 @@ public class GenericTestExecutionReportParserTest {
   }
 
   private DefaultInputFile setupFile(String path) {
-    return new DefaultInputFile(context.module().key(), path)
+    return new TestInputFileBuilder(context.module().key(), path)
       .setLanguage("bla")
       .setType(InputFile.Type.TEST)
-      .initMetadata("1\n2\n3\n4\n5\n6");
+      .initMetadata("1\n2\n3\n4\n5\n6")
+      .build();
   }
 
   private MutableTestPlan mockMutableTestPlan(MutableTestCase testCase) {
index 996e506685655680fa6a83f560ac8f1879c13100..1cbed75f3e5b073841505fb05c5044e0aabcc2b1 100644 (file)
@@ -20,8 +20,8 @@
 package org.sonar.scanner.issue;
 
 import org.junit.Test;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.issue.Issuable;
 import org.sonar.scanner.DefaultProjectTree;
 import org.sonar.scanner.sensor.DefaultSensorContext;
@@ -37,7 +37,7 @@ public class IssuableFactoryTest {
   @Test
   public void file_should_be_issuable() {
     IssuableFactory factory = new IssuableFactory(mock(DefaultSensorContext.class));
-    Issuable issuable = factory.loadPerspective(Issuable.class, new DefaultInputFile("foo", "src/Foo.java"));
+    Issuable issuable = factory.loadPerspective(Issuable.class, new TestInputFileBuilder("foo", "src/Foo.java").build());
 
     assertThat(issuable).isNotNull();
     assertThat(issuable.issues()).isEmpty();
index 61ac1a0fadd0a2fb3fef93c32ed2a26124a39ace..d2f75e47d620daa158f7ff03d6b7478b2c2e172d 100644 (file)
@@ -26,7 +26,7 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.rule.internal.RulesBuilder;
 import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
@@ -67,7 +67,7 @@ public class ModuleIssuesTest {
   ModuleIssues moduleIssues;
 
   BatchComponentCache componentCache = new BatchComponentCache();
-  InputFile file = new DefaultInputFile("foo", "src/Foo.php").initMetadata("Foo\nBar\nBiz\n");
+  InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").initMetadata("Foo\nBar\nBiz\n").build();
   ReportPublisher reportPublisher = mock(ReportPublisher.class, RETURNS_DEEP_STUBS);
 
   @Before
index f0b9ef844f5671a310ce94023c3fc3752b9b4d5d..07b19afa3578c1be9abb2bf67914906870ac69ab 100644 (file)
@@ -30,7 +30,7 @@ import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
 import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
 import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
@@ -102,11 +102,15 @@ public class IssueExclusionsLoaderTest {
   @Test
   public void shouldAnalyzeProject() throws IOException {
     File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
-    fs.add(new DefaultInputFile("polop", "src/main/java/Foo.java")
-      .setType(InputFile.Type.MAIN));
+    fs.add(new TestInputFileBuilder("polop", "src/main/java/Foo.java")
+      .setModuleBaseDir(baseDir.toPath())
+      .setType(InputFile.Type.MAIN)
+      .build());
     File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
-    fs.add(new DefaultInputFile("polop", "src/test/java/FooTest.java")
-      .setType(InputFile.Type.TEST));
+    fs.add(new TestInputFileBuilder("polop", "src/test/java/FooTest.java")
+      .setModuleBaseDir(baseDir.toPath())
+      .setType(InputFile.Type.TEST)
+      .build());
 
     when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
 
@@ -122,12 +126,12 @@ public class IssueExclusionsLoaderTest {
 
   @Test
   public void shouldAnalyseFilesOnlyWhenRegexConfigured() {
-    File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
-    fs.add(new DefaultInputFile("polop", "src/main/java/Foo.java")
-      .setType(InputFile.Type.MAIN));
-    File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
-    fs.add(new DefaultInputFile("polop", "src/test/java/FooTest.java")
-      .setType(InputFile.Type.TEST));
+    fs.add(new TestInputFileBuilder("polop", "src/main/java/Foo.java")
+      .setType(InputFile.Type.MAIN)
+      .build());
+    fs.add(new TestInputFileBuilder("polop", "src/test/java/FooTest.java")
+      .setType(InputFile.Type.TEST)
+      .build());
     when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false);
 
     scanner.execute();
@@ -142,8 +146,10 @@ public class IssueExclusionsLoaderTest {
   @Test
   public void shouldReportFailure() throws IOException {
     File phpFile1 = new File(baseDir, "src/Foo.php");
-    fs.add(new DefaultInputFile("polop", "src/Foo.php")
-      .setType(InputFile.Type.MAIN));
+    fs.add(new TestInputFileBuilder("polop", "src/Foo.php")
+      .setModuleBaseDir(baseDir.toPath())
+      .setType(InputFile.Type.MAIN)
+      .build());
 
     when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
     doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8);
index de4ecaac49678d5c0c5c591f2720deb0e324e1da..b9fd9dda60356072c977a289693fa72497d7ff73 100644 (file)
@@ -27,6 +27,7 @@ import java.util.Map;
 import org.apache.commons.io.FileUtils;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
index 0f6eb6dbdccc0235d19e66700123c239b1782538..abd3a13b8dda5a9f455536b3cf140651539f22f2 100644 (file)
@@ -28,8 +28,8 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.internal.DefaultInputDir;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.resources.Directory;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.DateUtils;
@@ -76,17 +76,17 @@ public class ComponentsPublisherTest {
     org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", FakeJava.INSTANCE, false);
     file.setEffectiveKey("module1:src/Foo.java");
     file.setId(4).setUuid("FILE_UUID");
-    resourceCache.add(file, dir).setInputComponent(new DefaultInputFile("module1", "src/Foo.java").setLines(2));
+    resourceCache.add(file, dir).setInputComponent(new TestInputFileBuilder("module1", "src/Foo.java").setLines(2).build());
 
     org.sonar.api.resources.File fileWithoutLang = org.sonar.api.resources.File.create("src/make", null, false);
     fileWithoutLang.setEffectiveKey("module1:src/make");
     fileWithoutLang.setId(5).setUuid("FILE_WITHOUT_LANG_UUID");
-    resourceCache.add(fileWithoutLang, dir).setInputComponent(new DefaultInputFile("module1", "src/make").setLines(10));
+    resourceCache.add(fileWithoutLang, dir).setInputComponent(new TestInputFileBuilder("module1", "src/make").setLines(10).build());
 
     org.sonar.api.resources.File testFile = org.sonar.api.resources.File.create("test/FooTest.java", FakeJava.INSTANCE, true);
     testFile.setEffectiveKey("module1:test/FooTest.java");
     testFile.setId(6).setUuid("TEST_FILE_UUID");
-    resourceCache.add(testFile, dir).setInputComponent(new DefaultInputFile("module1", "test/FooTest.java").setLines(4));
+    resourceCache.add(testFile, dir).setInputComponent(new TestInputFileBuilder("module1", "test/FooTest.java").setLines(4).build());
 
     ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef);
 
@@ -118,7 +118,7 @@ public class ComponentsPublisherTest {
     assertThat(module1Protobuf.getDescription()).isEqualTo("Module description");
     assertThat(module1Protobuf.getVersion()).isEqualTo("1.0");
   }
-  
+
   @Test
   public void add_components_without_version_and_name() throws IOException {
     ProjectDefinition rootDef = ProjectDefinition.create().setKey("foo");
@@ -141,17 +141,17 @@ public class ComponentsPublisherTest {
     org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", FakeJava.INSTANCE, false);
     file.setEffectiveKey("module1:src/Foo.java");
     file.setId(4).setUuid("FILE_UUID");
-    resourceCache.add(file, dir).setInputComponent(new DefaultInputFile("module1", "src/Foo.java").setLines(2));
+    resourceCache.add(file, dir).setInputComponent(new TestInputFileBuilder("module1", "src/Foo.java").setLines(2).build());
 
     org.sonar.api.resources.File fileWithoutLang = org.sonar.api.resources.File.create("src/make", null, false);
     fileWithoutLang.setEffectiveKey("module1:src/make");
     fileWithoutLang.setId(5).setUuid("FILE_WITHOUT_LANG_UUID");
-    resourceCache.add(fileWithoutLang, dir).setInputComponent(new DefaultInputFile("module1", "src/make").setLines(10));
+    resourceCache.add(fileWithoutLang, dir).setInputComponent(new TestInputFileBuilder("module1", "src/make").setLines(10).build());
 
     org.sonar.api.resources.File testFile = org.sonar.api.resources.File.create("test/FooTest.java", FakeJava.INSTANCE, true);
     testFile.setEffectiveKey("module1:test/FooTest.java");
     testFile.setId(6).setUuid("TEST_FILE_UUID");
-    resourceCache.add(testFile, dir).setInputComponent(new DefaultInputFile("module1", "test/FooTest.java").setLines(4));
+    resourceCache.add(testFile, dir).setInputComponent(new TestInputFileBuilder("module1", "test/FooTest.java").setLines(4).build());
 
     ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef);
 
@@ -214,7 +214,7 @@ public class ComponentsPublisherTest {
     org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", FakeJava.INSTANCE, false);
     file.setEffectiveKey("module1:my_branch:my_branch:src/Foo.java");
     file.setId(4).setUuid("FILE_UUID");
-    resourceCache.add(file, dir).setInputComponent(new DefaultInputFile("module1", "src/Foo.java").setLines(2));
+    resourceCache.add(file, dir).setInputComponent(new TestInputFileBuilder("module1", "src/Foo.java").setLines(2).build());
 
     ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef);
 
index 95757460e101485a0e5b51bde4d2c02a7efc481b..067169696e44d70d9db56c515969b6331b06a282 100644 (file)
@@ -25,8 +25,8 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.resources.Project;
@@ -58,7 +58,7 @@ public class CoveragePublisherTest {
     BatchComponentCache resourceCache = new BatchComponentCache();
     sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
     resourceCache.add(p, null).setInputComponent(new DefaultInputModule("foo"));
-    resourceCache.add(sampleFile, null).setInputComponent(new DefaultInputFile("foo", "src/Foo.php").setLines(5));
+    resourceCache.add(sampleFile, null).setInputComponent(new TestInputFileBuilder("foo", "src/Foo.php").setLines(5).build());
     measureCache = mock(MeasureCache.class);
     when(measureCache.byMetric(anyString(), anyString())).thenReturn(null);
     publisher = new CoveragePublisher(resourceCache, measureCache);
index 190907e001d9daba7d2374390a6bb6f22a3094ff..6ee89c3e5b949b611f43f4293bb9eef743a9d96f 100644 (file)
@@ -28,8 +28,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.resources.Project;
@@ -69,7 +69,7 @@ public class MeasuresPublisherTest {
     BatchComponentCache resourceCache = new BatchComponentCache();
     sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey(FILE_KEY);
     resourceCache.add(p, null).setInputComponent(new DefaultInputModule("foo"));
-    resourceCache.add(sampleFile, null).setInputComponent(new DefaultInputFile("foo", "src/Foo.php"));
+    resourceCache.add(sampleFile, null).setInputComponent(new TestInputFileBuilder("foo", "src/Foo.php").build());
     measureCache = mock(MeasureCache.class);
     when(measureCache.byComponentKey(anyString())).thenReturn(Collections.<DefaultMeasure<?>>emptyList());
     publisher = new MeasuresPublisher(resourceCache, measureCache, mock(TestPlanBuilder.class));
index e16b36173ef4b264729b4b4392e5235b88570dc8..0ecc47a1088220c233638e67fd54954da0f3fd49 100644 (file)
@@ -28,8 +28,8 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.scanner.index.BatchComponentCache;
@@ -61,7 +61,11 @@ public class SourcePublisherTest {
     File baseDir = temp.newFolder();
     sourceFile = new File(baseDir, "src/Foo.php");
     resourceCache.add(sampleFile, null).setInputComponent(
-      new DefaultInputFile("foo", "src/Foo.php").setLines(5).setModuleBaseDir(baseDir.toPath()).setCharset(StandardCharsets.ISO_8859_1));
+      new TestInputFileBuilder("foo", "src/Foo.php")
+      .setLines(5)
+      .setModuleBaseDir(baseDir.toPath())
+      .setCharset(StandardCharsets.ISO_8859_1)
+      .build());
     publisher = new SourcePublisher(resourceCache);
     File outputDir = temp.newFolder();
     writer = new ScannerReportWriter(outputDir);
index 4d4e77f88144b47e0d7d5830a288ab2cd37649a4..38548c7370b99b58ba4394931009b8a515b72ef9 100644 (file)
@@ -21,21 +21,24 @@ package org.sonar.scanner.scan.filesystem;
 
 import org.junit.Test;
 import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
 import org.sonar.scanner.scan.filesystem.AdditionalFilePredicates;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.nio.file.Paths;
+
 public class AdditionalFilePredicatesTest {
 
   @Test
   public void key() {
     FilePredicate predicate = new AdditionalFilePredicates.KeyPredicate("struts:Action.java");
 
-    DefaultInputFile inputFile = new DefaultInputFile("struts", "Action.java");
-    assertThat(predicate.apply(inputFile)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("struts", Paths.get("module"), "Action.java");
+    assertThat(predicate.apply(indexedFile)).isTrue();
 
-    inputFile = new DefaultInputFile("struts", "Filter.java");
-    assertThat(predicate.apply(inputFile)).isFalse();
+    indexedFile = new DefaultIndexedFile("struts", Paths.get("module"), "Filter.java");
+    assertThat(predicate.apply(indexedFile)).isFalse();
   }
 }
index dc09e7942d994c411608429d3c6520ea77c0d3d2..0db12d01f39a20fdc4ae7814739580e46c8b2486 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.resources.AbstractLanguage;
 import org.sonar.api.resources.Directory;
 import org.sonar.api.resources.Languages;
@@ -42,6 +43,7 @@ import org.sonar.scanner.analysis.DefaultAnalysisMode;
 import org.sonar.scanner.index.BatchComponent;
 import org.sonar.scanner.index.BatchComponentCache;
 import org.sonar.scanner.index.DefaultIndex;
+import org.sonar.scanner.repository.ProjectRepositories;
 import org.sonar.scanner.scan.filesystem.ComponentIndexer;
 import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
 import org.sonar.scanner.scan.filesystem.FileIndexer;
@@ -87,7 +89,7 @@ public class ComponentIndexerTest {
   public void should_index_java_files() throws IOException {
     Languages languages = new Languages(FakeJava.INSTANCE);
     ComponentIndexer indexer = createIndexer(languages);
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode, new ProjectRepositories());
     fs.add(newInputFile("src/main/java/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false, Status.ADDED));
     fs.add(newInputFile("src/main/java2/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false, Status.ADDED));
     // should index even if filter is applied
@@ -119,7 +121,7 @@ public class ComponentIndexerTest {
   public void should_index_cobol_files() throws IOException {
     Languages languages = new Languages(cobolLanguage);
     ComponentIndexer indexer = createIndexer(languages);
-    DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode);
+    DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode, new ProjectRepositories());
     fs.add(newInputFile("src/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false, Status.ADDED));
     fs.add(newInputFile("src2/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false, Status.ADDED));
     fs.add(newInputFile("src/test/foo/bar/FooTest.cbl", "", "foo/bar/FooTest.cbl", "cobol", true, Status.ADDED));
@@ -134,10 +136,11 @@ public class ComponentIndexerTest {
   private DefaultInputFile newInputFile(String path, String content, String sourceRelativePath, String languageKey, boolean unitTest, InputFile.Status status) throws IOException {
     File file = new File(baseDir, path);
     FileUtils.write(file, content);
-    return new DefaultInputFile("foo", path)
+    return new TestInputFileBuilder("foo", path)
       .setLanguage(languageKey)
       .setType(unitTest ? InputFile.Type.TEST : InputFile.Type.MAIN)
-      .setStatus(status);
+      .setStatus(status)
+      .build();
   }
 
 }
index 0007577b88c7fd008be4b3d597b6a5b16d678082..748ddbe32c5d971ec63d1bcb0405df9cb0c391e8 100644 (file)
  */
 package org.sonar.scanner.scan.filesystem;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
+
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.IndexedFile;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.config.Settings;
+import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
 import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.Settings;
 import org.sonar.api.scan.filesystem.FileExclusions;
 
-import static org.assertj.core.api.Assertions.assertThat;
-
 public class ExclusionFiltersTest {
 
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
+  private Path moduleBaseDir;
+
+  @Before
+  public void setUp() throws IOException {
+    moduleBaseDir = temp.newFolder().toPath();
+  }
 
   @Test
   public void no_inclusions_nor_exclusions() throws IOException {
     ExclusionFilters filter = new ExclusionFilters(new FileExclusions(new MapSettings()));
     filter.prepare();
 
-    java.io.File file = temp.newFile();
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
-    assertThat(filter.accept(inputFile, InputFile.Type.TEST)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue();
+    assertThat(filter.accept(indexedFile, InputFile.Type.TEST)).isTrue();
   }
 
   @Test
@@ -56,12 +65,11 @@ public class ExclusionFiltersTest {
     ExclusionFilters filter = new ExclusionFilters(new FileExclusions(settings));
     filter.prepare();
 
-    java.io.File file = temp.newFile();
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue();
 
-    inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
+    indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse();
   }
 
   @Test
@@ -72,13 +80,11 @@ public class ExclusionFiltersTest {
 
     filter.prepare();
 
-    java.io.File file = temp.newFile();
-
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
+    IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse();
 
-    inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDto.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
+    indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDto.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue();
   }
 
   @Test
@@ -91,22 +97,20 @@ public class ExclusionFiltersTest {
 
     filter.prepare();
 
-    java.io.File file = temp.newFile();
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
+    IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse();
 
-    inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
+    indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue();
 
     // source exclusions do not apply to tests
-    inputFile = new DefaultInputFile("foo", "src/test/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.TEST)).isTrue();
+    indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/test/java/com/mycompany/FooDao.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.TEST)).isTrue();
   }
 
   @Test
   public void match_exclusion_by_absolute_path() throws IOException {
-    File baseDir = temp.newFile();
-    File excludedFile = new File(baseDir, "src/main/java/org/bar/Bar.java");
+    File excludedFile = new File(moduleBaseDir.toString(), "src/main/java/org/bar/Bar.java");
 
     Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "src/main/java/**/*");
@@ -115,11 +119,11 @@ public class ExclusionFiltersTest {
 
     filter.prepare();
 
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/org/bar/Foo.java").setModuleBaseDir(baseDir.toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
+    IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/org/bar/Foo.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue();
 
-    inputFile = new DefaultInputFile("foo", "src/main/java/org/bar/Bar.java").setModuleBaseDir(baseDir.toPath());
-    assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
+    indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/org/bar/Bar.java");
+    assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse();
   }
 
   @Test
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactoryTest.java
deleted file mode 100644 (file)
index c8346db..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.scan.filesystem;
-
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.fs.internal.FileMetadata;
-import org.sonar.api.config.MapSettings;
-import org.sonar.api.scan.filesystem.PathResolver;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class InputFileBuilderFactoryTest {
-  @Test
-  public void create_builder() {
-    PathResolver pathResolver = new PathResolver();
-    LanguageDetectionFactory langDetectionFactory = mock(LanguageDetectionFactory.class, Mockito.RETURNS_MOCKS);
-    StatusDetectionFactory statusDetectionFactory = mock(StatusDetectionFactory.class, Mockito.RETURNS_MOCKS);
-    DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
-
-    InputFileBuilderFactory factory = new InputFileBuilderFactory(ProjectDefinition.create().setKey("struts"), pathResolver, langDetectionFactory,
-      statusDetectionFactory, new MapSettings(), new FileMetadata());
-    InputFileBuilder builder = factory.create(fs);
-
-    assertThat(builder.langDetection()).isNotNull();
-    assertThat(builder.statusDetection()).isNotNull();
-    assertThat(builder.pathResolver()).isSameAs(pathResolver);
-    assertThat(builder.fs()).isSameAs(fs);
-    assertThat(builder.moduleKey()).isEqualTo("struts");
-  }
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java
deleted file mode 100644 (file)
index d8b01f1..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.scan.filesystem;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.nio.charset.StandardCharsets;
-import org.apache.commons.io.FileUtils;
-import org.junit.Assert;
-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.FileMetadata;
-import org.sonar.api.config.MapSettings;
-import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.utils.PathUtils;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class InputFileBuilderTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  LanguageDetection langDetection = mock(LanguageDetection.class);
-  StatusDetection statusDetection = mock(StatusDetection.class);
-  DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
-
-  @Test
-  public void should_detect_charset_from_BOM() {
-    File basedir = new File("src/test/resources/org/sonar/scanner/scan/filesystem/");
-    when(fs.baseDir()).thenReturn(basedir);
-    when(fs.encoding()).thenReturn(StandardCharsets.US_ASCII);
-    when(langDetection.language(any(InputFile.class))).thenReturn("java");
-    InputFileBuilder builder = new InputFileBuilder("moduleKey", new PathResolver(), langDetection, statusDetection, fs, new MapSettings(), new FileMetadata());
-
-    assertThat(createAndComplete(builder, new File(basedir, "without_BOM.txt")).charset())
-      .isEqualTo(StandardCharsets.US_ASCII);
-    assertThat(createAndComplete(builder, new File(basedir, "UTF-8.txt")).charset())
-      .isEqualTo(StandardCharsets.UTF_8);
-    assertThat(createAndComplete(builder, new File(basedir, "UTF-16BE.txt")).charset())
-      .isEqualTo(StandardCharsets.UTF_16BE);
-    assertThat(createAndComplete(builder, new File(basedir, "UTF-16LE.txt")).charset())
-      .isEqualTo(StandardCharsets.UTF_16LE);
-    assertThat(createAndComplete(builder, new File(basedir, "UTF-32BE.txt")).charset())
-      .isEqualTo(InputFileBuilder.UTF_32BE);
-    assertThat(createAndComplete(builder, new File(basedir, "UTF-32LE.txt")).charset())
-      .isEqualTo(InputFileBuilder.UTF_32LE);
-
-    try {
-      createAndComplete(builder, new File(basedir, "non_existing"));
-      Assert.fail();
-    } catch (IllegalStateException e) {
-      assertThat(e.getMessage()).isEqualTo("Unable to read file " + new File(basedir, "non_existing").getAbsolutePath());
-      assertThat(e.getCause()).isInstanceOf(FileNotFoundException.class);
-    }
-  }
-
-  private static DefaultInputFile createAndComplete(InputFileBuilder builder, File file) {
-    DefaultInputFile inputFile = builder.create(file);
-    builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN);
-    return inputFile;
-  }
-
-  @Test
-  public void complete_input_file() throws Exception {
-    // file system
-    File basedir = temp.newFolder();
-    File srcFile = new File(basedir, "src/main/java/foo/Bar.java");
-    FileUtils.touch(srcFile);
-    FileUtils.write(srcFile, "single line");
-    when(fs.baseDir()).thenReturn(basedir);
-    when(fs.encoding()).thenReturn(StandardCharsets.UTF_8);
-
-    // lang
-    when(langDetection.language(any(InputFile.class))).thenReturn("java");
-
-    // status
-    when(statusDetection.status("foo", "src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a"))
-      .thenReturn(InputFile.Status.ADDED);
-
-    InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
-      langDetection, statusDetection, fs, new MapSettings(), new FileMetadata());
-    DefaultInputFile inputFile = builder.create(srcFile);
-    builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN);
-
-    assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN);
-    assertThat(inputFile.file()).isEqualTo(srcFile.getAbsoluteFile());
-    assertThat(inputFile.absolutePath()).isEqualTo(PathUtils.sanitize(srcFile.getAbsolutePath()));
-    assertThat(inputFile.language()).isEqualTo("java");
-    assertThat(inputFile.key()).isEqualTo("struts:src/main/java/foo/Bar.java");
-    assertThat(inputFile.relativePath()).isEqualTo("src/main/java/foo/Bar.java");
-    assertThat(inputFile.lines()).isEqualTo(1);
-  }
-
-  @Test
-  public void return_null_if_file_outside_basedir() throws Exception {
-    // file system
-    File basedir = temp.newFolder();
-    File otherDir = temp.newFolder();
-    File srcFile = new File(otherDir, "src/main/java/foo/Bar.java");
-    FileUtils.touch(srcFile);
-    when(fs.baseDir()).thenReturn(basedir);
-
-    InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
-      langDetection, statusDetection, fs, new MapSettings(), new FileMetadata());
-    DefaultInputFile inputFile = builder.create(srcFile);
-
-    assertThat(inputFile).isNull();
-  }
-
-  @Test
-  public void return_null_if_language_not_detected() throws Exception {
-    // file system
-    File basedir = temp.newFolder();
-    File srcFile = new File(basedir, "src/main/java/foo/Bar.java");
-    FileUtils.touch(srcFile);
-    FileUtils.write(srcFile, "single line");
-    when(fs.baseDir()).thenReturn(basedir);
-    when(fs.encoding()).thenReturn(StandardCharsets.UTF_8);
-
-    // lang
-    when(langDetection.language(any(InputFile.class))).thenReturn(null);
-
-    InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
-      langDetection, statusDetection, fs, new MapSettings(), new FileMetadata());
-    DefaultInputFile inputFile = builder.create(srcFile);
-    inputFile = builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN);
-
-    assertThat(inputFile).isNull();
-  }
-
-}
index 7d5b242ac0dd64d3ae91b2bb9c0ea7c91d32c712..a08039430a00ea2acbdf91f4968dd755344a8604 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.api.batch.fs.InputFile.Type;
 import org.sonar.api.batch.fs.InputPath;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.scanner.scan.filesystem.InputPathCache;
 import java.nio.charset.StandardCharsets;
 
@@ -49,15 +50,16 @@ public class InputPathCacheTest {
   @Test
   public void should_add_input_file() throws Exception {
     InputPathCache cache = new InputPathCache();
-    DefaultInputFile fooFile = new DefaultInputFile("foo", "src/main/java/Foo.java").setModuleBaseDir(temp.newFolder().toPath());
+    DefaultInputFile fooFile = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setModuleBaseDir(temp.newFolder().toPath()).build();
     cache.put("struts", fooFile);
-    cache.put("struts-core", new DefaultInputFile("foo", "src/main/java/Bar.java")
+    cache.put("struts-core", new TestInputFileBuilder("foo", "src/main/java/Bar.java")
       .setLanguage("bla")
       .setType(Type.MAIN)
       .setStatus(Status.ADDED)
       .setLines(2)
       .setCharset(StandardCharsets.UTF_8)
-      .setModuleBaseDir(temp.newFolder().toPath()));
+      .setModuleBaseDir(temp.newFolder().toPath())
+      .build());
 
     DefaultInputFile loadedFile = (DefaultInputFile) cache.getFile("struts-core", "src/main/java/Bar.java");
     assertThat(loadedFile.relativePath()).isEqualTo("src/main/java/Bar.java");
index 16e66383578f6cc784c75bfcd59e29a2286fa3b2..874351ee3e0ff712bc5cb3878e7e3ee93b53d725 100644 (file)
@@ -26,8 +26,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
 import org.sonar.api.config.Settings;
 import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Language;
@@ -61,23 +60,23 @@ public class LanguageDetectionTest {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("java", "java", "jav"), new MockLanguage("cobol", "cbl", "cob")));
     LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
 
-    assertThat(detection.language(newInputFile("Foo.java"))).isEqualTo("java");
-    assertThat(detection.language(newInputFile("src/Foo.java"))).isEqualTo("java");
-    assertThat(detection.language(newInputFile("Foo.JAVA"))).isEqualTo("java");
-    assertThat(detection.language(newInputFile("Foo.jav"))).isEqualTo("java");
-    assertThat(detection.language(newInputFile("Foo.Jav"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("Foo.java"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("src/Foo.java"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("Foo.JAVA"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("Foo.jav"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("Foo.Jav"))).isEqualTo("java");
 
-    assertThat(detection.language(newInputFile("abc.cbl"))).isEqualTo("cobol");
-    assertThat(detection.language(newInputFile("abc.CBL"))).isEqualTo("cobol");
+    assertThat(detection.language(newIndexedFile("abc.cbl"))).isEqualTo("cobol");
+    assertThat(detection.language(newIndexedFile("abc.CBL"))).isEqualTo("cobol");
 
-    assertThat(detection.language(newInputFile("abc.php"))).isNull();
-    assertThat(detection.language(newInputFile("abc"))).isNull();
+    assertThat(detection.language(newIndexedFile("abc.php"))).isNull();
+    assertThat(detection.language(newIndexedFile("abc"))).isNull();
   }
 
   @Test
   public void should_not_fail_if_no_language() throws Exception {
     LanguageDetection detection = spy(new LanguageDetection(new MapSettings(), new DefaultLanguagesRepository(new Languages())));
-    assertThat(detection.language(newInputFile("Foo.java"))).isNull();
+    assertThat(detection.language(newIndexedFile("Foo.java"))).isNull();
   }
 
   @Test
@@ -85,7 +84,7 @@ public class LanguageDetectionTest {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("abap", "abap", "ABAP")));
 
     LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
-    assertThat(detection.language(newInputFile("abc.abap"))).isEqualTo("abap");
+    assertThat(detection.language(newIndexedFile("abc.abap"))).isEqualTo("abap");
   }
 
   @Test
@@ -96,16 +95,16 @@ public class LanguageDetectionTest {
 
     // No side-effect on non-ABAP projects
     LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
-    assertThat(detection.language(newInputFile("abc"))).isNull();
-    assertThat(detection.language(newInputFile("abc.abap"))).isNull();
-    assertThat(detection.language(newInputFile("abc.java"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("abc"))).isNull();
+    assertThat(detection.language(newIndexedFile("abc.abap"))).isNull();
+    assertThat(detection.language(newIndexedFile("abc.java"))).isEqualTo("java");
 
     Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "abap");
     detection = new LanguageDetection(settings, languages);
-    assertThat(detection.language(newInputFile("abc"))).isEqualTo("abap");
-    assertThat(detection.language(newInputFile("abc.txt"))).isEqualTo("abap");
-    assertThat(detection.language(newInputFile("abc.java"))).isEqualTo("abap");
+    assertThat(detection.language(newIndexedFile("abc"))).isEqualTo("abap");
+    assertThat(detection.language(newIndexedFile("abc.txt"))).isEqualTo("abap");
+    assertThat(detection.language(newIndexedFile("abc.java"))).isEqualTo("abap");
   }
 
   @Test
@@ -115,10 +114,10 @@ public class LanguageDetectionTest {
     Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "java");
     LanguageDetection detection = new LanguageDetection(settings, languages);
-    assertThat(detection.language(newInputFile("abc"))).isNull();
-    assertThat(detection.language(newInputFile("abc.php"))).isNull();
-    assertThat(detection.language(newInputFile("abc.java"))).isEqualTo("java");
-    assertThat(detection.language(newInputFile("src/abc.java"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("abc"))).isNull();
+    assertThat(detection.language(newIndexedFile("abc.php"))).isNull();
+    assertThat(detection.language(newIndexedFile("abc.java"))).isEqualTo("java");
+    assertThat(detection.language(newIndexedFile("src/abc.java"))).isEqualTo("java");
   }
 
   @Test
@@ -137,7 +136,7 @@ public class LanguageDetectionTest {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml")));
     LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
     try {
-      detection.language(newInputFile("abc.xhtml"));
+      detection.language(newIndexedFile("abc.xhtml"));
       fail();
     } catch (MessageException e) {
       assertThat(e.getMessage())
@@ -155,8 +154,8 @@ public class LanguageDetectionTest {
     settings.setProperty("sonar.lang.patterns.xml", "xml/**");
     settings.setProperty("sonar.lang.patterns.web", "web/**");
     LanguageDetection detection = new LanguageDetection(settings, languages);
-    assertThat(detection.language(newInputFile("xml/abc.xhtml"))).isEqualTo("xml");
-    assertThat(detection.language(newInputFile("web/abc.xhtml"))).isEqualTo("web");
+    assertThat(detection.language(newIndexedFile("xml/abc.xhtml"))).isEqualTo("xml");
+    assertThat(detection.language(newIndexedFile("web/abc.xhtml"))).isEqualTo("web");
   }
 
   @Test
@@ -168,10 +167,10 @@ public class LanguageDetectionTest {
 
     LanguageDetection detection = new LanguageDetection(settings, languages);
 
-    assertThat(detection.language(newInputFile("abc.abap"))).isEqualTo("abap");
-    assertThat(detection.language(newInputFile("abc.cobol"))).isEqualTo("cobol");
+    assertThat(detection.language(newIndexedFile("abc.abap"))).isEqualTo("abap");
+    assertThat(detection.language(newIndexedFile("abc.cobol"))).isEqualTo("cobol");
     try {
-      detection.language(newInputFile("abc.txt"));
+      detection.language(newIndexedFile("abc.txt"));
       fail();
     } catch (MessageException e) {
       assertThat(e.getMessage())
@@ -181,9 +180,9 @@ public class LanguageDetectionTest {
     }
   }
 
-  private InputFile newInputFile(String path) throws IOException {
+  private DefaultIndexedFile newIndexedFile(String path) throws IOException {
     File basedir = temp.newFolder();
-    return new DefaultInputFile("foo", path).setModuleBaseDir(basedir.toPath());
+    return new DefaultIndexedFile("foo", basedir.toPath(), path);
   }
 
   static class MockLanguage implements Language {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java
new file mode 100644 (file)
index 0000000..2654293
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.sonar.api.batch.fs.internal.FileMetadata;
+
+import static org.mockito.Mockito.mock;
+
+public class MetadataGeneratorProviderTest {
+  @Test
+  public void create_builder() {
+    StatusDetectionFactory statusDetectionFactory = mock(StatusDetectionFactory.class, Mockito.RETURNS_MOCKS);
+
+    MetadataGeneratorProvider factory = new MetadataGeneratorProvider();
+    MetadataGenerator builder = factory.provide(statusDetectionFactory, new FileMetadata());
+    //TODO
+  }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
new file mode 100644 (file)
index 0000000..17f7f61
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.scan.filesystem;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.fs.internal.Metadata;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.api.utils.PathUtils;
+
+public class MetadataGeneratorTest {
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Mock
+  private StatusDetection statusDetection;
+  @Mock
+  private DefaultModuleFileSystem fs;
+  @Mock
+  private FileMetadata metadata;
+
+  private MetadataGenerator builder;
+
+  @Before
+  public void setUp() {
+    MockitoAnnotations.initMocks(this);
+    builder = new MetadataGenerator(statusDetection, metadata);
+    // TODO
+  }
+  /*
+   * @Test
+   * public void should_detect_charset_from_BOM() {
+   * File basedir = new File("src/test/resources/org/sonar/scanner/scan/filesystem/");
+   * when(fs.baseDir()).thenReturn(basedir);
+   * when(fs.encoding()).thenReturn(StandardCharsets.US_ASCII);
+   * 
+   * assertThat(createAndComplete(builder, new File(basedir, "without_BOM.txt")).charset())
+   * .isEqualTo(StandardCharsets.US_ASCII);
+   * assertThat(createAndComplete(builder, new File(basedir, "UTF-8.txt")).charset())
+   * .isEqualTo(StandardCharsets.UTF_8);
+   * assertThat(createAndComplete(builder, new File(basedir, "UTF-16BE.txt")).charset())
+   * .isEqualTo(StandardCharsets.UTF_16BE);
+   * assertThat(createAndComplete(builder, new File(basedir, "UTF-16LE.txt")).charset())
+   * .isEqualTo(StandardCharsets.UTF_16LE);
+   * assertThat(createAndComplete(builder, new File(basedir, "UTF-32BE.txt")).charset())
+   * .isEqualTo(InputFileBuilder.UTF_32BE);
+   * assertThat(createAndComplete(builder, new File(basedir, "UTF-32LE.txt")).charset())
+   * .isEqualTo(InputFileBuilder.UTF_32LE);
+   * 
+   * try {
+   * createAndComplete(builder, new File(basedir, "non_existing"));
+   * Assert.fail();
+   * } catch (IllegalStateException e) {
+   * assertThat(e.getMessage()).isEqualTo("Unable to read file " + new File(basedir, "non_existing").getAbsolutePath());
+   * assertThat(e.getCause()).isInstanceOf(FileNotFoundException.class);
+   * }
+   * }
+   * 
+   * private static DefaultInputFile createAndComplete(InputFileBuilder builder, File file) {
+   * DefaultInputFile inputFile = new TestInputFileBuilder("module", file.toString())
+   * .setMetadata()
+   * .build();
+   * return inputFile;
+   * }
+   * 
+   * @Test
+   * public void complete_input_file() throws Exception {
+   * // file system
+   * File basedir = temp.newFolder();
+   * File srcFile = new File(basedir, "src/main/java/foo/Bar.java");
+   * FileUtils.touch(srcFile);
+   * FileUtils.write(srcFile, "single line");
+   * when(fs.baseDir()).thenReturn(basedir);
+   * when(fs.encoding()).thenReturn(StandardCharsets.UTF_8);
+   * 
+   * // status
+   * when(statusDetection.status("foo", "src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a"))
+   * .thenReturn(InputFile.Status.ADDED);
+   * 
+   * Metadata metadata = builder.readMetadata(srcFile);
+   * builder.readMetadata(inputFile);
+   * 
+   * assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN);
+   * assertThat(inputFile.file()).isEqualTo(srcFile.getAbsoluteFile());
+   * assertThat(inputFile.absolutePath()).isEqualTo(PathUtils.sanitize(srcFile.getAbsolutePath()));
+   * assertThat(inputFile.language()).isEqualTo("java");
+   * assertThat(inputFile.key()).isEqualTo("struts:src/main/java/foo/Bar.java");
+   * assertThat(inputFile.relativePath()).isEqualTo("src/main/java/foo/Bar.java");
+   * assertThat(inputFile.lines()).isEqualTo(1);
+   * }
+   * 
+   * @Test
+   * public void set_metadata() throws Exception {
+   * DefaultInputFile inputFile = new TestInputFileBuilder("module", "src/main/java/foo/Bar.java").build();
+   * when()
+   * 
+   * Metadata metadata = builder.readMetadata(inputFile);
+   * 
+   * }
+   * 
+   * @Test
+   * public void return_null_if_language_not_detected() throws Exception {
+   * // file system
+   * File basedir = temp.newFolder();
+   * File srcFile = new File(basedir, "src/main/java/foo/Bar.java");
+   * FileUtils.touch(srcFile);
+   * FileUtils.write(srcFile, "single line");
+   * when(fs.baseDir()).thenReturn(basedir);
+   * when(fs.encoding()).thenReturn(StandardCharsets.UTF_8);
+   * 
+   * // lang
+   * when(langDetection.language(any(DefaultIndexedFile.class))).thenReturn(null);
+   * 
+   * InputFileBuilder builder = new InputFileBuilder(statusDetection, fs, new FileMetadata());
+   * DefaultInputFile inputFile = builder.create(srcFile);
+   * inputFile = builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN);
+   * 
+   * assertThat(inputFile).isNull();
+   * }
+   */
+}
index 227934bc39f2d096896fb029b572a76a5c29bc32..eba14f3a7b1698f374aac4b539fdff4c17e5424c 100644 (file)
@@ -26,7 +26,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.config.Settings;
 import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.Severity;
@@ -82,7 +82,7 @@ public class ConsoleReportTest {
   @Test
   public void testNoNewIssue() {
     settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
-    when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
+    when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/Foo.php").build()));
     when(issueCache.all()).thenReturn(Arrays.asList(createIssue(false, null)));
     report.execute();
     assertDeprecated();
@@ -95,7 +95,7 @@ public class ConsoleReportTest {
   @Test
   public void testOneNewIssue() {
     settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
-    when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
+    when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/Foo.php").build()));
     when(issueCache.all()).thenReturn(Arrays.asList(createIssue(true, Severity.BLOCKER)));
     report.execute();
     assertDeprecated();
@@ -109,7 +109,7 @@ public class ConsoleReportTest {
   @Test
   public void testOneNewIssuePerSeverity() {
     settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
-    when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
+    when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/Foo.php").build()));
     when(issueCache.all()).thenReturn(Arrays.asList(
       createIssue(true, Severity.BLOCKER),
       createIssue(true, Severity.CRITICAL),
@@ -128,11 +128,11 @@ public class ConsoleReportTest {
         "        +1 info\n" +
         "\n-------------------------------------------\n\n");
   }
-  
+
   private void assertDeprecated() {
     assertThat(getLogs()).contains("Console report is deprecated");
   }
-  
+
   private void assertNotDeprecated() {
     assertThat(getLogs()).doesNotContain("Console report is deprecated");
   }
index e7109daa410f0a066c248db20f404467c14e26eb..c75da60b841cf0cf8baecac9fcc5a59e81229c0c 100644 (file)
@@ -36,6 +36,7 @@ import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.Rules;
 import org.sonar.api.batch.rule.internal.RulesBuilder;
 import org.sonar.api.config.Settings;
@@ -81,7 +82,7 @@ public class JSONReportTest {
     when(server.getVersion()).thenReturn("3.6");
     userRepository = mock(UserRepositoryLoader.class);
     DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts");
-    DefaultInputFile inputFile = new DefaultInputFile("struts", "src/main/java/org/apache/struts/Action.java");
+    DefaultInputFile inputFile = new TestInputFileBuilder("struts", "src/main/java/org/apache/struts/Action.java").build();
     inputFile.setStatus(InputFile.Status.CHANGED);
     InputPathCache fileCache = mock(InputPathCache.class);
     when(fileCache.allFiles()).thenReturn(Arrays.<InputFile>asList(inputFile));
index 5ee591b3995187fb6a84c39f2d2a21033a77cf3b..02867cc63ee4ba1f85b96681a71d2ff9c305ac70 100644 (file)
@@ -27,7 +27,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.scm.BlameLine;
 import org.sonar.scanner.index.BatchComponent;
 import org.sonar.scanner.index.BatchComponentCache;
@@ -54,25 +54,25 @@ public class DefaultBlameOutputTest {
 
   @Test
   public void shouldNotFailIfNotSameNumberOfLines() {
-    InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(10);
+    InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build();
 
     new DefaultBlameOutput(null, null, Arrays.asList(file)).blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy")));
   }
 
   @Test
   public void shouldFailIfNotExpectedFile() {
-    InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1);
+    InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").build();
 
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("It was not expected to blame file src/main/java/Foo.java");
 
-    new DefaultBlameOutput(null, null, Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/main/java/Foo2.java")))
+    new DefaultBlameOutput(null, null, Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/main/java/Foo2.java").build()))
       .blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy")));
   }
 
   @Test
   public void shouldFailIfNullDate() {
-    InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1);
+    InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(1).build();
 
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("Blame date is null for file src/main/java/Foo.java at line 1");
@@ -83,7 +83,7 @@ public class DefaultBlameOutputTest {
 
   @Test
   public void shouldFailIfNullRevision() {
-    InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1);
+    InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(1).build();
 
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("Blame revision is blank for file src/main/java/Foo.java at line 1");
index 715c779c7e131a353b26f32c80db5853d56268f4..b2ed93632e830462a75053343ac53dcdd00e20d4 100644 (file)
@@ -28,8 +28,8 @@ import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
@@ -93,7 +93,7 @@ public class DefaultSensorStorageTest {
 
   @Test
   public void shouldFailIfUnknownMetric() {
-    InputFile file = new DefaultInputFile("foo", "src/Foo.php");
+    InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build();
 
     thrown.expect(UnsupportedOperationException.class);
     thrown.expectMessage("Unknown metric: lines");
@@ -106,7 +106,7 @@ public class DefaultSensorStorageTest {
 
   @Test
   public void shouldSaveFileMeasureToSensorContext() {
-    InputFile file = new DefaultInputFile("foo", "src/Foo.php");
+    InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build();
 
     ArgumentCaptor<DefaultMeasure> argumentCaptor = ArgumentCaptor.forClass(DefaultMeasure.class);
     Resource sonarFile = File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
@@ -144,8 +144,8 @@ public class DefaultSensorStorageTest {
   @Test(expected = UnsupportedOperationException.class)
   public void duplicateHighlighting() throws Exception {
     Resource sonarFile = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java")
-      .setModuleBaseDir(temp.newFolder().toPath());
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
+      .setModuleBaseDir(temp.newFolder().toPath()).build();
     componentCache.add(sonarFile, null).setInputComponent(inputFile);
     DefaultHighlighting h = new DefaultHighlighting(null)
       .onFile(inputFile);
@@ -156,8 +156,8 @@ public class DefaultSensorStorageTest {
   @Test(expected = UnsupportedOperationException.class)
   public void duplicateSymbolTable() throws Exception {
     Resource sonarFile = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java");
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java")
-      .setModuleBaseDir(temp.newFolder().toPath());
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
+      .setModuleBaseDir(temp.newFolder().toPath()).build();
     componentCache.add(sonarFile, null).setInputComponent(inputFile);
     DefaultSymbolTable st = new DefaultSymbolTable(null)
       .onFile(inputFile);
@@ -173,7 +173,7 @@ public class DefaultSensorStorageTest {
 
   @Test
   public void shouldValidateStrictlyPositiveLine() throws Exception {
-    DefaultInputFile file = new DefaultInputFile("module", "testfile").setModuleBaseDir(temp.newFolder().toPath());
+    InputFile file = new TestInputFileBuilder("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()).build();
     Map<Integer, Integer> map = ImmutableMap.of(0, 3);
     String data = KeyValueFormat.format(map);
 
@@ -184,7 +184,7 @@ public class DefaultSensorStorageTest {
 
   @Test
   public void shouldValidateMaxLine() throws Exception {
-    DefaultInputFile file = new DefaultInputFile("module", "testfile").setModuleBaseDir(temp.newFolder().toPath());
+    InputFile file = new TestInputFileBuilder("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()).build();
     Map<Integer, Integer> map = ImmutableMap.of(11, 3);
     String data = KeyValueFormat.format(map);
 
index 3fac6d4f0e8cb05b13e7bb04a2fac02ec3672163..c5bbf5b0311f240661f63ee85d104037eb102b2c 100644 (file)
@@ -26,7 +26,7 @@ import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
@@ -68,7 +68,7 @@ public class SensorOptimizerTest {
       .onlyOnLanguages("java", "php");
     assertThat(optimizer.shouldExecute(descriptor)).isFalse();
 
-    fs.add(new DefaultInputFile("foo", "src/Foo.java").setLanguage("java"));
+    fs.add(new TestInputFileBuilder("foo", "src/Foo.java").setLanguage("java").build());
     assertThat(optimizer.shouldExecute(descriptor)).isTrue();
   }
 
@@ -78,10 +78,10 @@ public class SensorOptimizerTest {
       .onlyOnFileType(InputFile.Type.MAIN);
     assertThat(optimizer.shouldExecute(descriptor)).isFalse();
 
-    fs.add(new DefaultInputFile("foo", "tests/FooTest.java").setType(InputFile.Type.TEST));
+    fs.add(new TestInputFileBuilder("foo", "tests/FooTest.java").setType(InputFile.Type.TEST).build());
     assertThat(optimizer.shouldExecute(descriptor)).isFalse();
 
-    fs.add(new DefaultInputFile("foo", "src/Foo.java").setType(InputFile.Type.MAIN));
+    fs.add(new TestInputFileBuilder("foo", "src/Foo.java").setType(InputFile.Type.MAIN).build());
     assertThat(optimizer.shouldExecute(descriptor)).isTrue();
   }
 
@@ -92,11 +92,11 @@ public class SensorOptimizerTest {
       .onlyOnFileType(InputFile.Type.MAIN);
     assertThat(optimizer.shouldExecute(descriptor)).isFalse();
 
-    fs.add(new DefaultInputFile("foo", "tests/FooTest.java").setLanguage("java").setType(InputFile.Type.TEST));
-    fs.add(new DefaultInputFile("foo", "src/Foo.cbl").setLanguage("cobol").setType(InputFile.Type.MAIN));
+    fs.add(new TestInputFileBuilder("foo", "tests/FooTest.java").setLanguage("java").setType(InputFile.Type.TEST).build());
+    fs.add(new TestInputFileBuilder("foo", "src/Foo.cbl").setLanguage("cobol").setType(InputFile.Type.MAIN).build());
     assertThat(optimizer.shouldExecute(descriptor)).isFalse();
 
-    fs.add(new DefaultInputFile("foo", "src/Foo.java").setLanguage("java").setType(InputFile.Type.MAIN));
+    fs.add(new TestInputFileBuilder("foo", "src/Foo.java").setLanguage("java").setType(InputFile.Type.MAIN).build());
     assertThat(optimizer.shouldExecute(descriptor)).isTrue();
   }
 
index 68d4080cb9b5fbea68c118eceae58c4716230631..4171333b655edb9a78508429f505a7d8de06ab0d 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.scanner.sensor.coverage;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
@@ -43,7 +43,7 @@ public class CoverageExclusionsTest {
 
   @Test
   public void shouldExcludeFileBasedOnPattern() {
-    InputFile file = new DefaultInputFile("foo", "src/org/polop/File.php");
+    InputFile file = new TestInputFileBuilder("foo", "src/org/polop/File.php").build();
     settings.setProperty("sonar.coverage.exclusions", "src/org/polop/*");
     coverageExclusions.initPatterns();
     assertThat(coverageExclusions.isExcluded(file)).isTrue();
@@ -51,7 +51,7 @@ public class CoverageExclusionsTest {
 
   @Test
   public void shouldNotExcludeFileBasedOnPattern() {
-    InputFile file = new DefaultInputFile("foo", "src/org/polop/File.php");
+    InputFile file = new TestInputFileBuilder("foo", "src/org/polop/File.php").build();
     settings.setProperty("sonar.coverage.exclusions", "src/org/other/*");
     coverageExclusions.initPatterns();
     assertThat(coverageExclusions.isExcluded(file)).isFalse();
index 22f8d2b98dede086e40776b1437b098d8f5f31e7..6a19804649b5f7e5c901d17d548a5c327456129f 100644 (file)
@@ -29,8 +29,8 @@ import org.apache.commons.io.FileUtils;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
@@ -125,8 +125,9 @@ public class CodeColorizersTest {
     File htmlFile = new File(this.getClass().getResource("CodeColorizersTest/package.html").toURI());
     SensorStorage sensorStorage = mock(SensorStorage.class);
     DefaultHighlighting highlighting = new DefaultHighlighting(sensorStorage);
-    highlighting.onFile(new DefaultInputFile("FOO", "package.html")
-      .initMetadata(new FileMetadata().readMetadata(htmlFile, StandardCharsets.UTF_8)));
+    highlighting.onFile(new TestInputFileBuilder("FOO", "package.html")
+      .setMetadata(new FileMetadata().readMetadata(htmlFile, StandardCharsets.UTF_8))
+      .build());
 
     codeColorizers.toSyntaxHighlighting(htmlFile, StandardCharsets.UTF_8, "web", highlighting);
 
index 9f4672a80a87a5292d565cc350f8c62fee81aa62..af830bc9cdbab4497c2c053717054f4089d7d5ad 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.batch.AnalysisMode;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.scanner.source.DefaultHighlightable;
@@ -41,8 +42,9 @@ public class DefaultHighlightableTest {
   @Test
   public void should_store_highlighting_rules() {
     SensorStorage sensorStorage = mock(SensorStorage.class);
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php")
-      .initMetadata("azerty\nbla bla");
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php")
+      .initMetadata("azerty\nbla bla")
+      .build();
     DefaultHighlightable highlightablePerspective = new DefaultHighlightable(inputFile, sensorStorage, mock(AnalysisMode.class));
     highlightablePerspective.newHighlighting().highlight(0, 6, "k").highlight(7, 10, "cppd").done();
 
index 2e199df452db0ec7356c1767b13a3138ef898b04..5c0230035e4451e70824ff5d1b0e45e211c0de5a 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.batch.AnalysisMode;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.source.Symbol;
 import org.sonar.api.source.Symbolizable;
@@ -40,8 +41,8 @@ public class DefaultSymbolizableTest {
   public void should_update_cache_when_done() {
 
     DefaultSensorStorage sensorStorage = mock(DefaultSensorStorage.class);
-    DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php")
-      .initMetadata(Strings.repeat("azerty\n", 20));
+    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php")
+      .initMetadata(Strings.repeat("azerty\n", 20)).build();
 
     DefaultSymbolizable symbolPerspective = new DefaultSymbolizable(inputFile, sensorStorage, mock(AnalysisMode.class));
     Symbolizable.SymbolTableBuilder symbolTableBuilder = symbolPerspective.newSymbolTableBuilder();
index 88f55e1e3f26d9ff0107466379169db4fcef7eec..99188f4d6dd60e485a7e024df2a67f266e3846cb 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.batch.fs.TextRange;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.source.Symbol;
 import org.sonar.api.source.Symbolizable;
@@ -42,8 +43,9 @@ public class DeprecatedDefaultSymbolTableTest {
 
   @Before
   public void prepare() {
-    inputFile = new DefaultInputFile("foo", "src/Foo.php")
-      .initMetadata(Strings.repeat("azerty\n", 20));
+    inputFile = new TestInputFileBuilder("foo", "src/Foo.php")
+      .initMetadata(Strings.repeat("azerty\n", 20))
+      .build();
   }
 
   @Test
index f68fe762e420dd774285d6d2da75540fb12d6cf6..4aafebd77199a6322febd52737ba43b9f1ebe4e1 100644 (file)
@@ -21,8 +21,8 @@ package org.sonar.scanner.source;
 
 import org.junit.Test;
 import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.source.Highlightable;
 
@@ -34,7 +34,7 @@ public class HighlightableBuilderTest {
   @Test
   public void should_load_default_perspective() {
     HighlightableBuilder builder = new HighlightableBuilder(mock(SensorStorage.class), mock(AnalysisMode.class));
-    Highlightable perspective = builder.loadPerspective(Highlightable.class, new DefaultInputFile("foo", "foo.c"));
+    Highlightable perspective = builder.loadPerspective(Highlightable.class, new TestInputFileBuilder("foo", "foo.c").build());
 
     assertThat(perspective).isNotNull().isInstanceOf(DefaultHighlightable.class);
   }
index 9a5e2edbc9fa47f91cf3fb500a0e6e61827ec575..7496ce162d402b520e5cd414bfbc96ad6a1a6cbe 100644 (file)
@@ -21,8 +21,8 @@ package org.sonar.scanner.source;
 
 import org.junit.Test;
 import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.component.Perspective;
 import org.sonar.api.source.Symbolizable;
 import org.sonar.scanner.sensor.DefaultSensorStorage;
@@ -35,7 +35,7 @@ public class SymbolizableBuilderTest {
   @Test
   public void should_load_perspective() {
     SymbolizableBuilder perspectiveBuilder = new SymbolizableBuilder(mock(DefaultSensorStorage.class), mock(AnalysisMode.class));
-    Perspective perspective = perspectiveBuilder.loadPerspective(Symbolizable.class, new DefaultInputFile("foo", "foo.c"));
+    Perspective perspective = perspectiveBuilder.loadPerspective(Symbolizable.class, new TestInputFileBuilder("foo", "foo.c").build());
 
     assertThat(perspective).isInstanceOf(Symbolizable.class);
   }