aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java32
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/AbsolutePathPredicate.java39
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/AndPredicate.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFiles.java)33
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java29
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java152
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java92
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java87
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/InputFileFilter.java)9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/LanguagePredicate.java36
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/NotPredicate.java38
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/OrPredicate.java45
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/PathPatternPredicate.java40
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/RelativePathPredicate.java (renamed from sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFilesTest.java)43
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/StatusPredicate.java38
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/TypePredicate.java39
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/UniqueIndexPredicate.java (renamed from sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFileBuilderTest.java)17
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java225
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java252
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileIndex.java39
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java135
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathIndex.java39
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/package-info.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/package-info.java)2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/package-info.java23
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/FileLinesContextFactory.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java18
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileType.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/InputFile.java98
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java21
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java217
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java89
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java75
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java100
33 files changed, 1503 insertions, 609 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java
index 730a62e14f1..e91b9d76739 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java
@@ -33,6 +33,4 @@ public interface ModuleLanguages extends BatchComponent {
Collection<String> keys();
- Collection<Language> languages();
-
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java
index 42cb48fac6d..da1dcccfe49 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java
@@ -19,6 +19,7 @@
*/
package org.sonar.api.batch;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
@@ -26,7 +27,6 @@ import org.sonar.api.measures.Metric;
import org.sonar.api.resources.ProjectLink;
import org.sonar.api.resources.Resource;
import org.sonar.api.rules.Violation;
-import org.sonar.api.scan.filesystem.InputFile;
import java.util.Collection;
import java.util.Date;
@@ -42,7 +42,6 @@ public interface SensorContext {
* Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.
*
* @return false if the resource is excluded
- * @since 2.6
* @since 4.2 Resource indexing is done by the platform for all physical resources. This method should only be used to index methods/paragraphs (see SONAR-5006)
*/
boolean index(Resource resource);
@@ -53,19 +52,20 @@ public interface SensorContext {
* @param resource the resource to index. Not nullable
* @param parentReference a reference to the parent. If null, the the resource is indexed as a direct child of project.
* @return false if the parent is not indexed or if the resource is excluded
- * @since 2.6
* @since 4.2 Resource indexing is done by the platform for all physical resources. This method should only be used to index methods/paragraphs (see SONAR-5006)
*/
boolean index(Resource resource, Resource parentReference);
/**
* Returns true if the referenced resource is indexed and excluded.
+ *
* @since 2.6
*/
boolean isExcluded(Resource reference);
/**
* Returns true if the referenced resource is indexed.
+ *
* @since 2.6
*/
boolean isIndexed(Resource reference, boolean acceptExcluded);
@@ -143,13 +143,6 @@ public interface SensorContext {
Measure saveMeasure(Resource resource, Metric metric, Double value);
/**
- * Experimental.
- * Add or update a measure on an InputFile.
- * @since 4.2
- */
- Measure saveMeasure(InputFile inputFile, Metric metric, Double value);
-
- /**
* Add or update a measure.
* <p>
* The resource is automatically saved, so there is no need to execute the method saveResource(). Does nothing if the resource is set as
@@ -158,13 +151,6 @@ public interface SensorContext {
*/
Measure saveMeasure(Resource resource, Measure measure);
- /**
- * Experimental.
- * Add or update a measure on an InputFile.
- * @since 4.2
- */
- Measure saveMeasure(InputFile inputFile, Measure measure);
-
// ----------- RULE VIOLATIONS --------------
/**
@@ -203,8 +189,7 @@ public interface SensorContext {
/**
* Save the source code of a file. The file must be have been indexed before.
*
- * @throws org.sonar.api.resources.DuplicatedSourceException
- * if the source has already been set on this resource
+ * @throws org.sonar.api.resources.DuplicatedSourceException if the source has already been set on this resource
* @since 1.10. Returns a boolean since 2.6.
* @deprecated since 4.2 Source import is done by the platform
*/
@@ -249,4 +234,13 @@ public interface SensorContext {
*/
void deleteEvent(Event event);
+ /**
+ * @since 4.2
+ */
+ Measure saveMeasure(InputFile inputFile, Metric metric, Double value);
+
+ /**
+ * @since 4.2
+ */
+ Measure saveMeasure(InputFile inputFile, Measure measure);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/AbsolutePathPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/AbsolutePathPredicate.java
new file mode 100644
index 00000000000..a659ad27f10
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/AbsolutePathPredicate.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.apache.commons.io.FilenameUtils;
+
+/**
+ * @since 4.2
+ */
+class AbsolutePathPredicate implements FilePredicate {
+
+ private final String path;
+
+ AbsolutePathPredicate(String path) {
+ this.path = FilenameUtils.normalize(path, true);
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return path.equals(f.absolutePath());
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFiles.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/AndPredicate.java
index 923cd32b133..f1221c1fe2c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFiles.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/AndPredicate.java
@@ -17,28 +17,29 @@
* 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.scan.filesystem.internal;
+package org.sonar.api.batch.fs;
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.collect.Lists;
-
-import java.io.File;
-import java.util.List;
+import javax.annotation.Nullable;
/**
- * @since 4.0
+ * @since 4.2
*/
-public class InputFiles {
- InputFiles() {
- // static methods only
+class AndPredicate implements FilePredicate {
+
+ private final Iterable<FilePredicate> predicates;
+
+ AndPredicate(@Nullable Iterable<FilePredicate> predicates) {
+ this.predicates = predicates;
}
- public static List<File> toFiles(Iterable<InputFile> inputFiles) {
- List<File> files = Lists.newArrayList();
- for (InputFile inputFile : inputFiles) {
- files.add(inputFile.file());
+ @Override
+ public boolean apply(InputFile f) {
+ for (FilePredicate predicate : predicates) {
+ if (!predicate.apply(f)) {
+ return false;
+ }
}
- return files;
+ return true;
}
+
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java
new file mode 100644
index 00000000000..5cc7b7ae9e1
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java
@@ -0,0 +1,29 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * Determines if a file must be kept in search results. See {@link org.sonar.api.batch.fs.FileSystem}
+ * and {@link org.sonar.api.batch.fs.FilePredicates}.
+ * @since 4.2
+ */
+public interface FilePredicate {
+ boolean apply(InputFile inputFile);
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java
new file mode 100644
index 00000000000..877666c733b
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java
@@ -0,0 +1,152 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import com.google.common.collect.Lists;
+import org.sonar.api.batch.fs.internal.PathPattern;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Factory of {@link org.sonar.api.batch.fs.FilePredicate}
+ *
+ * @since 4.2
+ */
+public class FilePredicates {
+ private static final FilePredicate ALWAYS_TRUE = new AlwaysTruePredicate();
+
+ private FilePredicates() {
+ // only static stuff
+ }
+
+ /**
+ * Returns a predicate that always evaluates to true
+ */
+ public static FilePredicate all() {
+ return ALWAYS_TRUE;
+ }
+
+ /**
+ * Warning - not efficient because absolute path is not indexed yet.
+ */
+ public static FilePredicate hasAbsolutePath(String s) {
+ return new AbsolutePathPredicate(s);
+ }
+
+ /**
+ * TODO document that non-normalized path and Windows-style path are supported
+ */
+ public static FilePredicate hasRelativePath(String s) {
+ return new RelativePathPredicate(s);
+ }
+
+ public static FilePredicate matchesPathPattern(String inclusionPattern) {
+ return new PathPatternPredicate(PathPattern.create(inclusionPattern));
+ }
+
+ public static FilePredicate matchesPathPatterns(String[] inclusionPatterns) {
+ FilePredicate[] predicates = new FilePredicate[inclusionPatterns.length];
+ for (int i = 0; i < inclusionPatterns.length; i++) {
+ predicates[i] = new PathPatternPredicate(PathPattern.create(inclusionPatterns[i]));
+ }
+ return and(predicates);
+ }
+
+ public static FilePredicate doesNotMatchPathPattern(String exclusionPattern) {
+ return not(matchesPathPattern(exclusionPattern));
+ }
+
+ public static FilePredicate doesNotMatchPathPatterns(String[] exclusionPatterns) {
+ return not(matchesPathPatterns(exclusionPatterns));
+ }
+
+ public static FilePredicate hasPath(String s) {
+ File file = new File(s);
+ if (file.isAbsolute()) {
+ return hasAbsolutePath(s);
+ }
+ return hasRelativePath(s);
+ }
+
+ public static FilePredicate is(File ioFile) {
+ if (ioFile.isAbsolute()) {
+ return hasAbsolutePath(ioFile.getAbsolutePath());
+ }
+ return hasRelativePath(ioFile.getPath());
+ }
+
+ public static FilePredicate hasLanguage(String language) {
+ return new LanguagePredicate(language);
+ }
+
+ public static FilePredicate hasLanguages(Collection<String> languages) {
+ List<FilePredicate> list = Lists.newArrayList();
+ for (String language : languages) {
+ list.add(hasLanguage(language));
+ }
+ return or(list);
+ }
+
+ public static FilePredicate hasStatus(InputFile.Status status) {
+ return new StatusPredicate(status);
+ }
+
+ public static FilePredicate hasType(InputFile.Type type) {
+ return new TypePredicate(type);
+ }
+
+ public static FilePredicate not(FilePredicate p) {
+ return new NotPredicate(p);
+ }
+
+ public static FilePredicate or(Iterable<FilePredicate> or) {
+ return new OrPredicate(or);
+ }
+
+ public static FilePredicate or(FilePredicate... or) {
+ return new OrPredicate(Arrays.asList(or));
+ }
+
+ public static FilePredicate or(FilePredicate first, FilePredicate second) {
+ return new OrPredicate(Arrays.asList(first, second));
+ }
+
+ public static FilePredicate and(Iterable<FilePredicate> and) {
+ return new AndPredicate(and);
+ }
+
+ public static FilePredicate and(FilePredicate... and) {
+ return new AndPredicate(Arrays.asList(and));
+ }
+
+ public static FilePredicate and(FilePredicate first, FilePredicate second) {
+ return new AndPredicate(Arrays.asList(first, second));
+ }
+
+ private static class AlwaysTruePredicate implements FilePredicate {
+ @Override
+ public boolean apply(InputFile inputFile) {
+ return true;
+ }
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java
new file mode 100644
index 00000000000..7d285af934f
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java
@@ -0,0 +1,92 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.sonar.api.BatchComponent;
+
+import javax.annotation.CheckForNull;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.Set;
+
+/**
+ * <p>The unit tests needing an instance of FileSystem can use the implementation
+ * {@link org.sonar.api.batch.fs.internal.DefaultFileSystem} and the related {@link org.sonar.api.scan.filesystem.internal.DefaultInputFile}:</p>
+ * <pre>
+ * FileSystem fs = new DefaultFileSystem();
+ * fs.add(new DefaultInputFile("src/foo/bar.php"));
+ * </pre>
+ *
+ * @since 4.2
+ */
+public interface FileSystem extends BatchComponent {
+
+ /**
+ * Absolute base directory of module
+ */
+ File baseDir();
+
+ /**
+ * Default encoding of input files. If it's not defined, then
+ * the platform default encoding is returned
+ */
+ Charset encoding();
+
+ /**
+ * Absolute work directory. It can be used to
+ * store third-party analysis reports.
+ * <p/>
+ * The work directory can be located outside {@link #baseDir()}.
+ */
+ File workDir();
+
+ /**
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ @CheckForNull
+ InputFile inputFile(FilePredicate predicate);
+
+ /**
+ * Input files matching the given attributes. Return all the files if the parameter
+ * <code>attributes</code> is empty.
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ Iterable<InputFile> inputFiles(FilePredicate predicate);
+
+ /**
+ * Returns true if at least one {@link org.sonar.api.batch.fs.InputFile} matches
+ * the given attributes. This method can be faster than checking if {@link #inputFiles(org.sonar.api.batch.fs.FilePredicate...)}
+ * has elements. If the parameter <code>attributes</code> is empty, then returns true
+ * if at least one input file exists.
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ boolean hasFiles(FilePredicate predicate);
+
+ /**
+ * Files matching the given attributes.
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ Iterable<File> files(FilePredicate predicate);
+
+ /**
+ * Languages detected in all the files, whatever their type (main code or test)
+ */
+ Set<String> languages();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java
new file mode 100644
index 00000000000..fb37090325d
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java
@@ -0,0 +1,87 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This layer over {@link java.io.File} adds information useful for code analyzers.
+ *
+ * @since 4.2
+ */
+public interface InputFile extends Serializable {
+
+ enum Type {
+ MAIN, TEST
+ }
+
+ /**
+ * Status regarding previous analysis
+ */
+ enum Status {
+ SAME, CHANGED, ADDED
+ }
+
+ /**
+ * 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.
+ * <p/>
+ * Returns <code>src/main/java/com/Foo.java</code> if module base dir is
+ * <code>/absolute/path/to/module</code> and if file is
+ * <code>/absolute/path/to/module/src/main/java/com/Foo.java</code>.
+ * <p/>
+ * Relative path is not null and is normalized ('foo/../foo' is replaced by 'foo').
+ */
+ String relativePath();
+
+ /**
+ * Normalized absolute path. File separator is forward slash ('/'), even on Microsoft Windows.
+ * <p/>
+ * This is not canonical path. Symbolic links are not resolved. For example if /project/src links
+ * to /tmp/src and basedir is /project, then this method returns /project/src/index.php. Use
+ * {@code file().getCanonicalPath()} to resolve symbolic link.
+ */
+ String absolutePath();
+
+ /**
+ * The underlying absolute {@link java.io.File}
+ */
+ File file();
+
+ /**
+ * Language, for example "java" or "php". It's automatically guessed when it is not
+ * set by project configuration.
+ */
+ String language();
+
+ /**
+ * Does it contain main or test code ?
+ */
+ Type type();
+
+ /**
+ * Status regarding previous analysis
+ */
+ Status status();
+
+ int lines();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/InputFileFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java
index 7c58519f9e9..d9bdac27857 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/InputFileFilter.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java
@@ -17,18 +17,17 @@
* 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.scan.filesystem;
+package org.sonar.api.batch.fs;
import org.sonar.api.BatchExtension;
/**
- * Implement this extension to limit the set of files to be analyzed. Global file inclusion/exclusion patterns
- * are already applied.
- *
+ * Extension point to complete the list of files to ignore during inspection
* @since 4.2
*/
public interface InputFileFilter extends BatchExtension {
- boolean accept(InputFile inputFile);
+ // TODO requires a context (FileSystem) ?
+ boolean accept(InputFile f);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/LanguagePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/LanguagePredicate.java
new file mode 100644
index 00000000000..9ab1578b33a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/LanguagePredicate.java
@@ -0,0 +1,36 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class LanguagePredicate implements FilePredicate {
+ private final String language;
+
+ LanguagePredicate(String language) {
+ this.language = language;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return language.equals(f.language());
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/NotPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/NotPredicate.java
new file mode 100644
index 00000000000..5a83803bab0
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/NotPredicate.java
@@ -0,0 +1,38 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class NotPredicate implements FilePredicate {
+
+ private final FilePredicate predicate;
+
+ NotPredicate(FilePredicate predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return !predicate.apply(f);
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/OrPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/OrPredicate.java
new file mode 100644
index 00000000000..af364527a2a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/OrPredicate.java
@@ -0,0 +1,45 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import javax.annotation.Nullable;
+
+/**
+ * @since 4.2
+ */
+class OrPredicate implements FilePredicate {
+
+ private final Iterable<FilePredicate> predicates;
+
+ OrPredicate(@Nullable Iterable<FilePredicate> predicates) {
+ this.predicates = predicates;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ for (FilePredicate predicate : predicates) {
+ if (predicate.apply(f)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/PathPatternPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/PathPatternPredicate.java
new file mode 100644
index 00000000000..2a342026352
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/PathPatternPredicate.java
@@ -0,0 +1,40 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.sonar.api.batch.fs.internal.PathPattern;
+
+/**
+ * @since 4.2
+ */
+class PathPatternPredicate implements FilePredicate {
+
+ private final PathPattern pattern;
+
+ PathPatternPredicate(PathPattern pattern) {
+ this.pattern = pattern;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return pattern.match(f);
+ }
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFilesTest.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/RelativePathPredicate.java
index f0b522be7c5..98453eb4a58 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFilesTest.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/RelativePathPredicate.java
@@ -17,32 +17,35 @@
* 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.scan.filesystem.internal;
+package org.sonar.api.batch.fs;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.apache.commons.io.FilenameUtils;
+import org.sonar.api.batch.fs.internal.RelativePathIndex;
-import com.google.common.base.Charsets;
-import com.google.common.collect.Lists;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
+/**
+ * @since 4.2
+ */
+class RelativePathPredicate implements FilePredicate, UniqueIndexPredicate {
-import static org.fest.assertions.Assertions.assertThat;
+ private final String path;
-public class InputFilesTest {
+ RelativePathPredicate(String path) {
+ this.path = FilenameUtils.normalize(path, true);
+ }
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
+ @Override
+ public boolean apply(InputFile f) {
+ return path.equals(f.relativePath());
+ }
- @Test
- public void test_toFiles() throws Exception {
- File file1 = temp.newFile();
- File file2 = temp.newFile();
- InputFile input1 = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").build();
- InputFile input2 = new InputFileBuilder(file2, Charsets.UTF_8, "src/main/java/Bar.java").build();
+ @Override
+ public Object value() {
+ return path;
+ }
- assertThat(InputFiles.toFiles(Lists.newArrayList(input1, input2))).containsOnly(file1, file2);
+ @Override
+ public String indexId() {
+ return RelativePathIndex.ID;
}
+
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/StatusPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/StatusPredicate.java
new file mode 100644
index 00000000000..c80b4830f7b
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/StatusPredicate.java
@@ -0,0 +1,38 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class StatusPredicate implements FilePredicate {
+
+ 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/TypePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/TypePredicate.java
new file mode 100644
index 00000000000..84be0a29e15
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/TypePredicate.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class TypePredicate implements FilePredicate {
+
+ private final InputFile.Type type;
+
+ TypePredicate(InputFile.Type type) {
+ this.type = type;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return type == f.type();
+ }
+
+}
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFileBuilderTest.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/UniqueIndexPredicate.java
index 6e70f14fa1d..693722d101f 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFileBuilderTest.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/UniqueIndexPredicate.java
@@ -17,14 +17,15 @@
* 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.scan.filesystem.internal;
+package org.sonar.api.batch.fs;
-import org.junit.Test;
+/**
+ * @since 4.2
+ */
+public interface UniqueIndexPredicate {
+
+ String indexId();
+
+ Object value();
-public class InputFileBuilderTest {
- @Test
- public void just_for_coverage() throws Exception {
- InputFileBuilder._FOR_UNIT_TESTING_ONLY_();
- // do not fail
- }
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
new file mode 100644
index 00000000000..4754c1aebb1
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
@@ -0,0 +1,225 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.commons.io.Charsets;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.UniqueIndexPredicate;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @since 4.2
+ */
+public class DefaultFileSystem implements FileSystem {
+
+ private final Cache cache;
+ private final Set<String> languages = Sets.newTreeSet();
+ private File baseDir, workDir;
+ private Charset encoding = Charsets.UTF_8;
+ private boolean isDefaultJvmEncoding = false;
+
+ /**
+ * Only for testing
+ */
+ public DefaultFileSystem() {
+ this.cache = new MapCache();
+ }
+
+ protected DefaultFileSystem(Cache cache) {
+ this.cache = cache;
+ }
+
+ public DefaultFileSystem setBaseDir(File d) {
+ Preconditions.checkNotNull(d, "Base directory can't be null");
+ this.baseDir = d.getAbsoluteFile();
+ return this;
+ }
+
+ /**
+ * Marked as nullable only for the tests that do not call {@link #setBaseDir(java.io.File)}
+ */
+ @Override
+ @CheckForNull
+ public File baseDir() {
+ return baseDir;
+ }
+
+ public DefaultFileSystem setEncoding(Charset e) {
+ this.encoding = e;
+ return this;
+ }
+
+ @Override
+ public Charset encoding() {
+ return encoding;
+ }
+
+ public boolean isDefaultJvmEncoding() {
+ return isDefaultJvmEncoding;
+ }
+
+ public void setIsDefaultJvmEncoding(boolean b) {
+ this.isDefaultJvmEncoding = b;
+ }
+
+ public DefaultFileSystem setWorkDir(File d) {
+ this.workDir = d.getAbsoluteFile();
+ return this;
+ }
+
+ /**
+ * Marked as nullable only for the tests that do not call {@link #setWorkDir(java.io.File)}
+ */
+ @Override
+ @CheckForNull
+ public File workDir() {
+ return workDir;
+ }
+
+ @Override
+ public InputFile inputFile(FilePredicate predicate) {
+ if (predicate instanceof UniqueIndexPredicate) {
+ return cache.inputFile((UniqueIndexPredicate) predicate);
+ }
+ try {
+ Iterable<InputFile> files = inputFiles(predicate);
+ return Iterables.getOnlyElement(files);
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public Iterable<InputFile> inputFiles(FilePredicate predicate) {
+ return Iterables.filter(cache.inputFiles(), new GuavaPredicate(predicate));
+ }
+
+ @Override
+ public boolean hasFiles(FilePredicate predicate) {
+ return Iterables.indexOf(cache.inputFiles(), new GuavaPredicate(predicate)) >= 0;
+ }
+
+ @Override
+ public Iterable<File> files(FilePredicate predicate) {
+ return Iterables.transform(inputFiles(predicate), new Function<InputFile, File>() {
+ @Override
+ public File apply(@Nullable InputFile input) {
+ return input == null ? null : input.file();
+ }
+ });
+ }
+
+ public void add(InputFile inputFile) {
+ cache.add(inputFile);
+ if (inputFile.language() != null) {
+ languages.add(inputFile.language());
+ }
+ }
+
+ @Override
+ public Set<String> languages() {
+ return languages;
+ }
+
+ public static abstract class Cache {
+ protected abstract Iterable<InputFile> inputFiles();
+
+ @CheckForNull
+ protected abstract InputFile inputFile(UniqueIndexPredicate predicate);
+
+ protected abstract void doAdd(InputFile inputFile);
+
+ protected abstract void doIndex(String indexId, Object value, InputFile inputFile);
+
+ final void add(InputFile inputFile) {
+ doAdd(inputFile);
+ for (FileIndex index : FileIndex.ALL) {
+ doIndex(index.id(), index.valueOf(inputFile), inputFile);
+ }
+ }
+ }
+
+ /**
+ * Used only for testing
+ */
+ private static class MapCache extends Cache {
+ private final List<InputFile> files = Lists.newArrayList();
+ private final Map<String, Map<Object, InputFile>> fileMap = Maps.newHashMap();
+
+ @Override
+ public Iterable<InputFile> inputFiles() {
+ return Lists.newArrayList(files);
+ }
+
+ @Override
+ public InputFile inputFile(UniqueIndexPredicate predicate) {
+ Map<Object, InputFile> byAttr = fileMap.get(predicate.indexId());
+ if (byAttr != null) {
+ return byAttr.get(predicate.value());
+ }
+ return null;
+ }
+
+ @Override
+ protected void doAdd(InputFile inputFile) {
+ files.add(inputFile);
+ }
+
+ @Override
+ protected void doIndex(String indexId, Object value, InputFile inputFile) {
+ Map<Object, InputFile> attrValues = fileMap.get(indexId);
+ if (attrValues == null) {
+ attrValues = Maps.newHashMap();
+ fileMap.put(indexId, attrValues);
+ }
+ attrValues.put(value, inputFile);
+ }
+ }
+
+ private static class GuavaPredicate implements Predicate<InputFile> {
+ private final FilePredicate predicate;
+
+ private GuavaPredicate(FilePredicate predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean apply(@Nullable InputFile input) {
+ return input != null && predicate.apply(input);
+ }
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
new file mode 100644
index 00000000000..fa3f49d0c0a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
@@ -0,0 +1,252 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.apache.commons.io.FilenameUtils;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.utils.PathUtils;
+
+import javax.annotation.CheckForNull;
+import java.io.*;
+
+/**
+ * @since 4.2
+ */
+public class DefaultInputFile implements InputFile, org.sonar.api.resources.InputFile, Serializable {
+
+ private final String relativePath;
+ private String absolutePath;
+ private String language;
+ private Type type = Type.MAIN;
+ private Status status;
+ private String hash;
+ private int lines;
+ private String key;
+ private String deprecatedKey;
+ private String sourceDirAbsolutePath;
+ private String pathRelativeToSourceDir;
+ private String basedir;
+
+ public DefaultInputFile(String relativePath) {
+ this.relativePath = FilenameUtils.normalize(relativePath, true);
+ }
+
+ @Override
+ public String relativePath() {
+ return relativePath;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not call {@link #setFile(java.io.File)}
+ * previously.
+ */
+ @Override
+ @CheckForNull
+ public String absolutePath() {
+ return absolutePath;
+ }
+
+ @Override
+ public File file() {
+ return new File(absolutePath);
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not call {@link #setLanguage(String)}
+ * previously.
+ */
+ @CheckForNull
+ @Override
+ public String language() {
+ return language;
+ }
+
+ @Override
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not previously call
+ * {@link #setStatus(org.sonar.api.batch.fs.InputFile.Status)}
+ */
+ @CheckForNull
+ @Override
+ public Status status() {
+ return status;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not previously call
+ * {@link #setHash(String)}
+ */
+ @CheckForNull
+ public String hash() {
+ return hash;
+ }
+
+ @Override
+ public int lines() {
+ return lines;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not previously call
+ * {@link #setKey(String)}.
+ */
+ @CheckForNull
+ public String key() {
+ return key;
+ }
+
+ public DefaultInputFile setAbsolutePath(String s) {
+ this.absolutePath = FilenameUtils.normalize(s, true);
+ return this;
+ }
+
+ public DefaultInputFile setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
+
+ public DefaultInputFile setFile(File file) {
+ setAbsolutePath(file.getAbsolutePath());
+ return this;
+ }
+
+ public DefaultInputFile setType(Type type) {
+ this.type = type;
+ return this;
+ }
+
+ public DefaultInputFile setStatus(Status status) {
+ this.status = status;
+ return this;
+ }
+
+ public DefaultInputFile setHash(String hash) {
+ this.hash = hash;
+ return this;
+ }
+
+ public DefaultInputFile setLines(int lines) {
+ this.lines = lines;
+ return this;
+ }
+
+ public DefaultInputFile setKey(String s) {
+ this.key = s;
+ return this;
+ }
+
+ /**
+ * Key used before version 4.2. It's different than {@link #key} on Java files.
+ */
+ public String deprecatedKey() {
+ return deprecatedKey;
+ }
+
+ public DefaultInputFile setDeprecatedKey(String s) {
+ this.deprecatedKey = s;
+ return this;
+ }
+
+ /**
+ * Used only for backward-compatibility. Meaningless since version 4.2.
+ */
+ public String sourceDirAbsolutePath() {
+ return sourceDirAbsolutePath;
+ }
+
+ public DefaultInputFile setSourceDirAbsolutePath(String s) {
+ this.sourceDirAbsolutePath = FilenameUtils.normalize(s, true);
+ return this;
+ }
+
+ /**
+ * Used only for backward-compatibility. Meaningless since version 4.2.
+ */
+
+ public String pathRelativeToSourceDir() {
+ return pathRelativeToSourceDir;
+ }
+
+ public DefaultInputFile setPathRelativeToSourceDir(String s) {
+ this.pathRelativeToSourceDir = FilenameUtils.normalize(s, true);
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ DefaultInputFile that = (DefaultInputFile) o;
+ return relativePath.equals(that.relativePath);
+ }
+
+ @Override
+ public int hashCode() {
+ return relativePath.hashCode();
+ }
+
+ /**
+ * @deprecated in 4.2. Use {@link org.sonar.api.batch.fs.FileSystem#baseDir()}
+ */
+ @Deprecated
+ @Override
+ public File getFileBaseDir() {
+ return new File(basedir);
+ }
+
+ public void setBasedir(File basedir) {
+ this.basedir = PathUtils.sanitize(basedir.getAbsolutePath());
+ }
+
+ /**
+ * @deprecated in 4.2. Use {@link #file()}
+ */
+ @Deprecated
+ @Override
+ public File getFile() {
+ return file();
+ }
+
+ /**
+ * @deprecated in 4.2. Use {@link #relativePath()}
+ */
+ @Deprecated
+ @Override
+ public String getRelativePath() {
+ return relativePath();
+ }
+
+ @Override
+ public InputStream getInputStream() throws FileNotFoundException {
+ return new BufferedInputStream(new FileInputStream(file()));
+ }
+}
+
+
+
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileIndex.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileIndex.java
new file mode 100644
index 00000000000..a6a6d45e470
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileIndex.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import com.google.common.collect.ImmutableList;
+import org.sonar.api.batch.fs.InputFile;
+
+import javax.annotation.CheckForNull;
+import java.util.List;
+
+// Accepted to support both InputFile and InputDir as long as indexes are on the same attributes
+public interface FileIndex {
+
+ // Currently only a single index is supported
+ List<FileIndex> ALL = ImmutableList.<FileIndex>of(new RelativePathIndex());
+
+ @CheckForNull
+ Object valueOf(InputFile f);
+
+ String id();
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java
new file mode 100644
index 00000000000..186226fb47b
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java
@@ -0,0 +1,135 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.utils.PathUtils;
+import org.sonar.api.utils.WildcardPattern;
+
+import java.io.File;
+
+public abstract class PathPattern {
+
+ final WildcardPattern pattern;
+
+ PathPattern(String pattern) {
+ this.pattern = WildcardPattern.create(pattern);
+ }
+
+ public abstract boolean match(InputFile inputFile);
+
+ public abstract boolean match(File ioFile, String relativePathFromBasedir);
+
+ public abstract boolean match(InputFile inputFile, boolean caseSensitiveFileExtension);
+
+ public static PathPattern create(String s) {
+ String trimmed = StringUtils.trim(s);
+ if (StringUtils.startsWithIgnoreCase(trimmed, "file:")) {
+ return new AbsolutePathPattern(StringUtils.substring(trimmed, "file:".length()));
+ }
+ return new RelativePathPattern(trimmed);
+ }
+
+ public static PathPattern[] create(String[] s) {
+ PathPattern[] result = new PathPattern[s.length];
+ for (int i = 0; i < s.length; i++) {
+ result[i] = create(s[i]);
+ }
+ return result;
+ }
+
+ private static class AbsolutePathPattern extends PathPattern {
+ private AbsolutePathPattern(String pattern) {
+ super(pattern);
+ }
+
+ @Override
+ public boolean match(File ioFile, String relativePathFromBasedir) {
+ String path = PathUtils.sanitize(ioFile.getAbsolutePath());
+ return pattern.match(path);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile) {
+ return match(inputFile, true);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
+ String path = inputFile.absolutePath();
+ if (!caseSensitiveFileExtension) {
+ String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
+ if (StringUtils.isNotBlank(extension)) {
+ StringUtils.removeEndIgnoreCase(path, extension);
+ path = path + extension;
+ }
+ }
+ return pattern.match(path);
+ }
+
+ @Override
+ public String toString() {
+ return "file:" + pattern.toString();
+ }
+ }
+
+ /**
+ * Path relative to module basedir
+ */
+ private static class RelativePathPattern extends PathPattern {
+ private RelativePathPattern(String pattern) {
+ super(pattern);
+ }
+
+ @Override
+ public boolean match(File ioFile, String relativePathFromBasedir) {
+ return relativePathFromBasedir != null && pattern.match(relativePathFromBasedir);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile) {
+ return match(inputFile, true);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
+ String path = inputFile.relativePath();
+ if (!caseSensitiveFileExtension) {
+ String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
+ if (StringUtils.isNotBlank(extension)) {
+ path = StringUtils.removeEndIgnoreCase(path, extension);
+ path = path + extension;
+ }
+ }
+ return path != null && pattern.match(path);
+ }
+
+ @Override
+ public String toString() {
+ return pattern.toString();
+ }
+ }
+
+ static String sanitizeExtension(String suffix) {
+ return StringUtils.lowerCase(StringUtils.removeStart(suffix, "."));
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathIndex.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathIndex.java
new file mode 100644
index 00000000000..dc52ed7bf49
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathIndex.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.sonar.api.batch.fs.InputFile;
+
+/**
+ * @since 4.2
+ */
+public class RelativePathIndex implements FileIndex {
+ public static final String ID = "rel";
+
+ @Override
+ public Object valueOf(InputFile f) {
+ return f.relativePath();
+ }
+
+ @Override
+ public String id() {
+ return ID;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/package-info.java
index 2018417ac1c..80283a000fb 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/package-info.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/package-info.java
@@ -18,6 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
-package org.sonar.api.scan.filesystem.internal;
+package org.sonar.api.batch.fs.internal;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/package-info.java
new file mode 100644
index 00000000000..02490a199b8
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.api.batch.fs;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/FileLinesContextFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/FileLinesContextFactory.java
index d9908d4583b..f7af0d48af5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/FileLinesContextFactory.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/FileLinesContextFactory.java
@@ -21,8 +21,8 @@ package org.sonar.api.measures;
import com.google.common.annotations.Beta;
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.InputFile;
/**
* <p>This interface is not intended to be implemented by clients.</p>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java
index e8d05fe14d0..f1adc52953f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java
@@ -50,7 +50,7 @@ public class FileQuery {
public static FileQuery on(FileType... types) {
FileQuery query = new FileQuery();
for (FileType type : types) {
- query.on(InputFile.ATTRIBUTE_TYPE, type.typeValue());
+ query.on("TYPE", type.typeValue());
}
return query;
}
@@ -75,12 +75,12 @@ public class FileQuery {
*/
public static FileQuery onMain() {
FileQuery query = new FileQuery();
- return query.on(InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_MAIN);
+ return query.on("TYPE", "MAIN");
}
public static FileQuery onTest() {
FileQuery query = new FileQuery();
- return query.on(InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_TEST);
+ return query.on("TYPE", "TEST");
}
private FileQuery() {
@@ -102,7 +102,7 @@ public class FileQuery {
*/
@Deprecated
public Collection<FileType> types() {
- return Collections2.transform(attributes.get(InputFile.ATTRIBUTE_TYPE), new Function<String, FileType>() {
+ return Collections2.transform(attributes.get("TYPE"), new Function<String, FileType>() {
@Override
public FileType apply(@Nullable String input) {
return input != null ? FileType.valueOf(input) : null;
@@ -111,15 +111,15 @@ public class FileQuery {
}
public Collection<String> typeAttributes() {
- return attributes.get(InputFile.ATTRIBUTE_TYPE);
+ return attributes.get("TYPE");
}
public Collection<String> languages() {
- return attributes.get(InputFile.ATTRIBUTE_LANGUAGE);
+ return attributes.get("LANG");
}
public FileQuery onLanguage(String... languages) {
- return on(InputFile.ATTRIBUTE_LANGUAGE, languages);
+ return on("LANG", languages);
}
public Collection<String> inclusions() {
@@ -144,10 +144,6 @@ public class FileQuery {
throw new UnsupportedOperationException("TODO");
}
- public FileQuery withFilters(FileFilter... filters) {
- throw new UnsupportedOperationException("TODO");
- }
-
@Override
public boolean equals(Object obj) {
if (obj == null) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileType.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileType.java
index 6754503a9f8..bf296dc8ad2 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileType.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileType.java
@@ -21,11 +21,11 @@ package org.sonar.api.scan.filesystem;
/**
* @since 3.5
- * @deprecated since 4.2 use {@link InputFile#TYPE_MAIN} or {@link InputFile#TYPE_TEST}
+ * @deprecated in 4.2
*/
@Deprecated
public enum FileType {
- SOURCE(InputFile.TYPE_MAIN), TEST(InputFile.TYPE_TEST);
+ SOURCE("MAIN"), TEST("TEST"), MAIN("MAIN");
private String typeValue;
@@ -33,7 +33,7 @@ public enum FileType {
this.typeValue = typeValue;
}
- String typeValue() {
+ public String typeValue() {
return typeValue;
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/InputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/InputFile.java
deleted file mode 100644
index e811576ec2e..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/InputFile.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem;
-
-import javax.annotation.CheckForNull;
-
-import java.io.File;
-import java.io.Serializable;
-import java.nio.charset.Charset;
-import java.util.Map;
-
-public interface InputFile extends Serializable {
-
- /**
- * Detected language
- */
- String ATTRIBUTE_LANGUAGE = "LANG";
-
- /**
- * Number of lines in the file.
- */
- String ATTRIBUTE_LINE_COUNT = "LINE_COUNT";
-
- /**
- * Type of source file. For now only possible values are {@link #TYPE_MAIN} or {@link #TYPE_TEST}
- */
- String ATTRIBUTE_TYPE = "TYPE";
- String TYPE_MAIN = "MAIN";
- String TYPE_TEST = "TEST";
-
- String ATTRIBUTE_STATUS = "STATUS";
- String STATUS_SAME = "SAME";
- String STATUS_CHANGED = "CHANGED";
- String STATUS_ADDED = "ADDED";
-
- /**
- * Path is relative from module base directory. Path is unique and identifies file
- * within given <code>{@link org.sonar.api.scan.filesystem.ModuleFileSystem}</code>.
- * File separator is the forward slash ('/'), even on MSWindows.
- * <p/>
- * Returns <code>src/main/java/com/Foo.java</code> if module base dir is
- * <code>/absolute/path/to/module</code> and if file is
- * <code>/absolute/path/to/module/src/main/java/com/Foo.java</code>.
- * <p/>
- * Returned path is never null.
- */
- String path();
-
- /**
- * Not-null canonical path. File separator is forward slash ('/'), even on MSWindows.
- */
- String absolutePath();
-
- File file();
-
- Charset encoding();
-
- /**
- * Not-null filename, including extension
- */
- String name();
-
- /**
- * Not-null type (is it a main file or a unit test file?).
- * See constant values prefixed by <code>TYPE_</code>, for example {@link #TYPE_MAIN}.
- */
- String type();
-
- /**
- * Does the given attribute have the given value ?
- */
- boolean has(String attribute, String value);
-
- /**
- * See list of attribute keys in constants starting with ATTRIBUTE_.
- */
- @CheckForNull
- String attribute(String key);
-
- Map<String, String> attributes();
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java
index 9ea6ec091e9..89d721d27ec 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/ModuleFileSystem.java
@@ -22,14 +22,15 @@ package org.sonar.api.scan.filesystem;
import org.sonar.api.BatchComponent;
import javax.annotation.CheckForNull;
-
import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
/**
* @since 3.5
+ * @deprecated in 4.2. Replaced by {@link org.sonar.api.batch.fs.FileSystem}
*/
+@Deprecated
public interface ModuleFileSystem extends BatchComponent {
/**
@@ -49,7 +50,6 @@ public interface ModuleFileSystem extends BatchComponent {
* Example in Maven : ${project.basedir}/src/main/java
* @deprecated since 4.2 will always return {@link #baseDir()}
*/
- @Deprecated
List<File> sourceDirs();
/**
@@ -57,7 +57,6 @@ public interface ModuleFileSystem extends BatchComponent {
* Example in Maven : ${project.basedir}/src/test/java
* @deprecated since 4.2 will always return {@link #baseDir()}
*/
- @Deprecated
List<File> testDirs();
/**
@@ -70,30 +69,14 @@ public interface ModuleFileSystem extends BatchComponent {
* </ul>
* @deprecated since 4.2 sonar.binaries should be converted to language specific property
*/
- @Deprecated
List<File> binaryDirs();
/**
* Search for files. Never return null.
- * @deprecated since 4.2 use {@link #inputFiles(FileQuery)}
*/
- @Deprecated
List<File> files(FileQuery query);
/**
- * Search for input files. Never return null.
- * @since 4.2
- */
- Iterable<InputFile> inputFiles(FileQuery query);
-
- /**
- * Search for input file corresponding to the given java.io.File.
- * @since 4.2
- */
- @CheckForNull
- InputFile inputFile(File ioFile);
-
- /**
* Default charset for files of the module. If it's not defined, then
* return the platform default charset. When trying to read an input file it is better to rely on
* {@link InputFile#encoding()} as encoding may be different for each file.
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java
deleted file mode 100644
index 9f75219c86d..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.apache.commons.codec.Charsets;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.utils.PathUtils;
-
-import javax.annotation.CheckForNull;
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.Map;
-
-/**
- * PLUGINS MUST NOT USE THIS CLASS, EVEN FOR UNIT TESTING.
- *
- * @since 4.0
- */
-public class DefaultInputFile implements InputFile {
-
- /**
- * We're not sure that this is the correct way, so not in API yet.
- */
- public static final String ATTRIBUTE_COMPONENT_KEY = "CMP_KEY";
-
- public static final String ATTRIBUTE_COMPONENT_DEPRECATED_KEY = "CMP_DEPRECATED_KEY";
-
- public static final String ATTRIBUTE_HASH = "HASH";
-
- /**
- * Relative path from source directory. File separator is the forward slash ('/'),
- * even on MSWindows.
- * @deprecated since 4.2 No more sonar.sources
- */
- @Deprecated
- public static final String ATTRIBUTE_SOURCE_RELATIVE_PATH = "SRC_REL_PATH";
-
- /**
- * Canonical path of source directory.
- * Example: <code>/path/to/module/src/main/java</code> or <code>C:\path\to\module\src\main\java</code>
- * @deprecated since 4.2 No more sonar.sources
- */
- @Deprecated
- public static final String ATTRIBUTE_SOURCEDIR_PATH = "SRC_DIR_PATH";
-
- private final String absolutePath;
- private final String path;
- private final Map<String, String> attributes;
- private final String encoding;
-
- private DefaultInputFile(File file, Charset encoding, String path, Map<String, String> attributes) {
- this.encoding = encoding.name();
- this.absolutePath = PathUtils.canonicalPath(file);
- this.path = FilenameUtils.separatorsToUnix(path);
- this.attributes = attributes;
- }
-
- /**
- * Plugins must not build their own instances of {@link InputFile}.
- * {@link org.sonar.api.scan.filesystem.ModuleFileSystem} must be used to search for files to scan.
- * <p/>
- * Usage: <code>InputFile.create(file, "src/main/java/com/Foo.java", attributes)</code>
- */
- public static DefaultInputFile create(File file, Charset encoding, String path, Map<String, String> attributes) {
- return new DefaultInputFile(file, encoding, path, attributes);
- }
-
- @Override
- public String path() {
- return path;
- }
-
- @Override
- public String absolutePath() {
- return absolutePath;
- }
-
- @Override
- public File file() {
- return new File(absolutePath);
- }
-
- @Override
- public Charset encoding() {
- return Charsets.toCharset(encoding);
- }
-
- @Override
- public String name() {
- return file().getName();
- }
-
- @Override
- public String type() {
- return attribute(ATTRIBUTE_TYPE);
- }
-
- @Override
- public boolean has(String attribute, String value) {
- return StringUtils.equals(attributes.get(attribute), value);
- }
-
- @Override
- @CheckForNull
- public String attribute(String key) {
- return attributes.get(key);
- }
-
- @Override
- public Map<String, String> attributes() {
- return attributes;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- DefaultInputFile other = (DefaultInputFile) o;
- return absolutePath.equals(other.absolutePath);
- }
-
- @Override
- public int hashCode() {
- return absolutePath.hashCode();
- }
-
- public DefaultInputFile setLines(long l) {
- attributes.put(ATTRIBUTE_LINE_COUNT, String.valueOf(l));
- return this;
- }
-
- public String language() {
- return attributes.get(ATTRIBUTE_LANGUAGE);
- }
-
- public DefaultInputFile setLanguage(String s) {
- attributes.put(ATTRIBUTE_LANGUAGE, s);
- return this;
- }
-
- public DefaultInputFile setHash(String s) {
- attributes.put(ATTRIBUTE_HASH, s);
- return this;
- }
-
- public DefaultInputFile setStatus(String s) {
- attributes.put(ATTRIBUTE_STATUS, s);
- return this;
- }
-
- public DefaultInputFile setKey(String s) {
- attributes.put(ATTRIBUTE_COMPONENT_KEY, s);
- return this;
- }
-
- public DefaultInputFile setDeprecatedKey(String s) {
- attributes.put(ATTRIBUTE_COMPONENT_DEPRECATED_KEY, s);
- return this;
- }
-
- public DefaultInputFile setType(String s) {
- attributes.put(ATTRIBUTE_TYPE, s);
- return this;
- }
-
- /**
- * Used only for backward-compatibility. Meaningless since version 4.2.
- */
- public String sourceDirAbsolutePath() {
- return attributes.get(ATTRIBUTE_SOURCEDIR_PATH);
- }
-
- public DefaultInputFile setSourceDirAbsolutePath(String s) {
- attributes.put(ATTRIBUTE_SOURCEDIR_PATH, FilenameUtils.normalize(s, true));
- return this;
- }
-
- /**
- * Used only for backward-compatibility. Meaningless since version 4.2.
- */
- public String pathRelativeToSourceDir() {
- return attributes.get(ATTRIBUTE_SOURCE_RELATIVE_PATH);
- }
-
- public DefaultInputFile setPathRelativeToSourceDir(String s) {
- attributes.put(ATTRIBUTE_SOURCE_RELATIVE_PATH, FilenameUtils.normalize(s, true));
- return this;
- }
-
- @Override
- public String toString() {
- return String.format("[%s,%s]", path, type());
- }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java
deleted file mode 100644
index d7e2d730fbe..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.sonar.api.scan.filesystem.InputFile;
-
-import org.sonar.api.utils.PathUtils;
-
-import javax.annotation.Nullable;
-
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * FOR UNIT-TESTING ONLY
- *
- * @since 4.0
- */
-public class InputFileBuilder {
-
- private final Map<String, String> attributes = new HashMap<String, String>();
- private final File file;
- private final String relativePath;
- private Charset encoding;
-
- public static void _FOR_UNIT_TESTING_ONLY_() {
- // For those who don't read javadoc
- }
-
- public InputFileBuilder(File file, Charset encoding, String relativePath) {
- this.file = file;
- this.encoding = encoding;
- this.relativePath = relativePath;
- }
-
- public InputFileBuilder attribute(String key, @Nullable String value) {
- if (value != null) {
- attributes.put(key, value);
- }
- return this;
- }
-
- public InputFileBuilder type(@Nullable String type) {
- return attribute(InputFile.ATTRIBUTE_TYPE, type);
- }
-
- public InputFileBuilder language(@Nullable String language) {
- return attribute(InputFile.ATTRIBUTE_LANGUAGE, language);
- }
-
- public InputFileBuilder hash(@Nullable String hash) {
- return attribute(DefaultInputFile.ATTRIBUTE_HASH, hash);
- }
-
- public InputFileBuilder status(@Nullable String status) {
- return attribute(InputFile.ATTRIBUTE_STATUS, status);
- }
-
- public InputFileBuilder sourceDir(File dir) {
- return attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH, PathUtils.canonicalPath(dir));
- }
-
- public InputFileBuilder sourceDir(@Nullable String path) {
- return attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH, PathUtils.sanitize(path));
- }
-
- public DefaultInputFile build() {
- return DefaultInputFile.create(file, encoding, relativePath, attributes);
- }
-}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
new file mode 100644
index 00000000000..afbc74f2928
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
@@ -0,0 +1,75 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+
+import java.io.File;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class DefaultInputFileTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void test() throws Exception {
+ DefaultInputFile inputFile = new DefaultInputFile("src/Foo.php")
+ .setFile(temp.newFile("Foo.php"))
+ .setDeprecatedKey("deprecated")
+ .setKey("ABCDE")
+ .setHash("1234")
+ .setLines(42)
+ .setLanguage("php")
+ .setStatus(InputFile.Status.ADDED)
+ .setType(InputFile.Type.TEST);
+
+ assertThat(inputFile.relativePath()).isEqualTo("src/Foo.php");
+ assertThat(inputFile.getRelativePath()).isEqualTo("src/Foo.php");
+ assertThat(new File(inputFile.relativePath())).isRelative();
+ assertThat(inputFile.absolutePath()).endsWith("Foo.php");
+ assertThat(new File(inputFile.absolutePath())).isAbsolute();
+ assertThat(inputFile.language()).isEqualTo("php");
+ assertThat(inputFile.status()).isEqualTo(InputFile.Status.ADDED);
+ assertThat(inputFile.type()).isEqualTo(InputFile.Type.TEST);
+ assertThat(inputFile.lines()).isEqualTo(42);
+ assertThat(inputFile.hash()).isEqualTo("1234");
+ }
+
+ @Test
+ public void test_equals_and_hashcode() throws Exception {
+ DefaultInputFile f1 = new DefaultInputFile("src/Foo.php");
+ DefaultInputFile f1a = new DefaultInputFile("src/Foo.php");
+ DefaultInputFile f2 = new DefaultInputFile("src/Bar.php");
+
+ assertThat(f1).isEqualTo(f1);
+ assertThat(f1).isEqualTo(f1a);
+ assertThat(f1).isNotEqualTo(f2);
+ assertThat(f1.equals("foo")).isFalse();
+ assertThat(f1.equals(null)).isFalse();
+
+ assertThat(f1.hashCode()).isEqualTo(f1.hashCode());
+ assertThat(f1.hashCode()).isEqualTo(f1a.hashCode());
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java
deleted file mode 100644
index a8346a0ccd3..00000000000
--- a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.base.Charsets;
-import org.apache.commons.io.FilenameUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.utils.PathUtils;
-
-import java.io.File;
-import java.io.IOException;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DefaultInputFileTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void test_attributes() throws IOException {
- File file = temp.newFile();
- InputFile input = new InputFileBuilder(file, Charsets.UTF_8, "src/main/java/Foo.java")
- .attribute("foo", "bar")
- .type(InputFile.TYPE_TEST)
- .hash("ABC")
- .status(InputFile.STATUS_ADDED)
- .language("java")
- .build();
-
- assertThat(input.attributes()).hasSize(5);
- assertThat(input.attribute("unknown")).isNull();
- assertThat(input.attribute("foo")).isEqualTo("bar");
- assertThat(input.attribute(InputFile.ATTRIBUTE_TYPE)).isEqualTo(InputFile.TYPE_TEST);
- assertThat(input.attribute(DefaultInputFile.ATTRIBUTE_HASH)).isEqualTo("ABC");
- assertThat(input.attribute(InputFile.ATTRIBUTE_LANGUAGE)).isEqualTo("java");
- assertThat(input.attribute(InputFile.ATTRIBUTE_STATUS)).isEqualTo(InputFile.STATUS_ADDED);
-
- assertThat(input.has(InputFile.ATTRIBUTE_LANGUAGE, "java")).isTrue();
- assertThat(input.has(InputFile.ATTRIBUTE_LANGUAGE, "php")).isFalse();
- assertThat(input.has("unknown", "xxx")).isFalse();
- }
-
- @Test
- public void test_file() throws Exception {
- File sourceDir = temp.newFolder();
- File file = temp.newFile("Foo.java");
- InputFile input = new InputFileBuilder(file, Charsets.UTF_8, "src/main/java/Foo.java")
- .sourceDir(sourceDir)
- .build();
-
- assertThat(input.name()).isEqualTo("Foo.java");
- assertThat(input.file()).isEqualTo(file);
- assertThat(input.attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH)).isEqualTo(FilenameUtils.separatorsToUnix(sourceDir.getAbsolutePath()));
- assertThat(input.path()).isEqualTo("src/main/java/Foo.java");
- assertThat(input.absolutePath()).isEqualTo(PathUtils.canonicalPath(file));
- }
-
- @Test
- public void test_equals_and_hashCode() throws Exception {
- File file1 = temp.newFile();
- InputFile input1 = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").build();
- InputFile input1a = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").build();
- InputFile input2 = new InputFileBuilder(temp.newFile(), Charsets.UTF_8, "src/main/java/Bar.java").build();
-
- assertThat(input1.equals(input1)).isTrue();
- assertThat(input1.equals(input1a)).isTrue();
- assertThat(input1.equals(input2)).isFalse();
- assertThat(input1.hashCode()).isEqualTo(input1.hashCode());
- assertThat(input1.hashCode()).isEqualTo(input1a.hashCode());
- }
-
- @Test
- public void test_toString() throws Exception {
- File file1 = temp.newFile();
- InputFile input = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").type(InputFile.TYPE_TEST).build();
- assertThat(input.toString()).isEqualTo("[src/main/java/Foo.java,TEST]");
- }
-}