aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorJanos Gyerik <janos.gyerik@sonarsource.com>2017-01-24 17:32:28 +0100
committerDuarte Meneses <duarte.meneses@sonarsource.com>2017-01-27 16:26:30 +0100
commit291382160309e0543067c59c193d126710370dee (patch)
treebacef8cf02968d4911360db95fd6375049bccf3e /sonar-plugin-api
parente606937326a6f2c9d83d7d2509d73bb237a94356 (diff)
downloadsonarqube-291382160309e0543067c59c193d126710370dee.tar.gz
sonarqube-291382160309e0543067c59c193d126710370dee.zip
SONAR-8630 query by filename and ext (#1555)
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java18
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java15
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileExtensionPredicate.java62
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FilenamePredicate.java48
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java10
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java72
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java66
9 files changed, 304 insertions, 0 deletions
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
index 72614539fad..1aa79288923 100644
--- 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
@@ -56,6 +56,24 @@ public interface FilePredicates {
FilePredicate hasRelativePath(String s);
/**
+ * Predicate that matches files by filename, in any directory.
+ * For example, the parameter <code>Foo.java</code> will match both
+ * <code>some/path/Foo.java</code> and <code>other/path/Foo.java</code>.
+ * The parameter must match exactly, no patterns are allowed,
+ * and it must not be <code>null</code>.
+ */
+ FilePredicate hasFilename(String s);
+
+ /**
+ * Predicate that matches files by extension (case insensitive).
+ * For example, the parameter <code>java</code> will match
+ * <code>some/path/Foo.java</code> and <code>other/path/Foo.JAVA</code>
+ * but not <code>some/path/Foo.js</code>.
+ * The parameter must not be <code>null</code>.
+ */
+ FilePredicate hasExtension(String s);
+
+ /**
* Predicate that gets the files which relative or absolute path matches a wildcard pattern.
* <br>
* If the parameter starts with <code>file:</code>, then absolute path is used, else relative path. Pattern
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
index 3243f8dcab5..2c9adee3092 100644
--- 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
@@ -165,5 +165,9 @@ public interface FileSystem {
InputDir inputDir(String relativePath);
InputModule module();
+
+ Iterable<InputFile> getFilesByName(String filename);
+
+ Iterable<InputFile> getFilesByExtension(String extension);
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java
index 864fde37b8e..1c503394418 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java
@@ -76,6 +76,15 @@ public class DefaultFilePredicates implements FilePredicates {
}
@Override
+ public FilePredicate hasFilename(String s) {
+ return new FilenamePredicate(s);
+ }
+
+ @Override public FilePredicate hasExtension(String s) {
+ return new FileExtensionPredicate(s);
+ }
+
+ @Override
public FilePredicate matchesPathPattern(String inclusionPattern) {
return new PathPatternPredicate(PathPattern.create(inclusionPattern));
}
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
index 7c7632df8d8..de2c28766de 100644
--- 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
@@ -20,6 +20,8 @@
package org.sonar.api.batch.fs.internal;
import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.SetMultimap;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -264,6 +266,8 @@ public class DefaultFileSystem implements FileSystem {
private final Map<String, InputFile> fileMap = new HashMap<>();
private final Map<String, InputDir> dirMap = new HashMap<>();
private InputModule module;
+ private final SetMultimap<String, InputFile> filesByNameCache = LinkedHashMultimap.create();
+ private final SetMultimap<String, InputFile> filesByExtensionCache = LinkedHashMultimap.create();
@Override
public Iterable<InputFile> inputFiles() {
@@ -286,8 +290,19 @@ public class DefaultFileSystem implements FileSystem {
}
@Override
+ public Iterable<InputFile> getFilesByName(String filename) {
+ return filesByNameCache.get(filename);
+ }
+
+ @Override public Iterable<InputFile> getFilesByExtension(String extension) {
+ return filesByExtensionCache.get(extension);
+ }
+
+ @Override
protected void doAdd(InputFile inputFile) {
fileMap.put(inputFile.relativePath(), inputFile);
+ filesByNameCache.put(FilenamePredicate.getFilename(inputFile), inputFile);
+ filesByExtensionCache.put(FileExtensionPredicate.getExtension(inputFile), inputFile);
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileExtensionPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileExtensionPredicate.java
new file mode 100644
index 00000000000..8eba8b00fc6
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileExtensionPredicate.java
@@ -0,0 +1,62 @@
+/*
+ * 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.util.Locale;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+
+/**
+ * @since 6.3
+ */
+public class FileExtensionPredicate extends AbstractFilePredicate {
+
+ private final String extension;
+
+ public FileExtensionPredicate(String extension) {
+ this.extension = lowercase(extension);
+ }
+
+ @Override
+ public boolean apply(InputFile inputFile) {
+ return extension.equals(getExtension(inputFile));
+ }
+
+ @Override
+ public Iterable<InputFile> get(FileSystem.Index index) {
+ return index.getFilesByExtension(extension);
+ }
+
+ public static String getExtension(InputFile inputFile) {
+ return getExtension(FilenamePredicate.getFilename(inputFile));
+ }
+
+ static String getExtension(String name) {
+ int index = name.lastIndexOf('.');
+ if (index < 0) {
+ return "";
+ }
+ return lowercase(name.substring(index + 1));
+ }
+
+ private static String lowercase(String extension) {
+ return extension.toLowerCase(Locale.ENGLISH);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FilenamePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FilenamePredicate.java
new file mode 100644
index 00000000000..16a66535720
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FilenamePredicate.java
@@ -0,0 +1,48 @@
+/*
+ * 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.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+
+/**
+ * @since 6.3
+ */
+public class FilenamePredicate extends AbstractFilePredicate {
+ private final String filename;
+
+ public FilenamePredicate(String filename) {
+ this.filename = filename;
+ }
+
+ @Override
+ public boolean apply(InputFile inputFile) {
+ return filename.equals(getFilename(inputFile));
+ }
+
+ @Override
+ public Iterable<InputFile> get(FileSystem.Index index) {
+ return index.getFilesByName(filename);
+ }
+
+ public static String getFilename(InputFile inputFile) {
+ return inputFile.file().getName();
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java
index b1befd9e62b..2d38624aa3f 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java
@@ -214,4 +214,14 @@ public class DefaultFilePredicatesTest {
assertThat(predicates.or(new FilePredicate[] {predicates.all(), predicates.none()}).apply(javaFile)).isTrue();
assertThat(predicates.or(new FilePredicate[] {predicates.none(), predicates.none()}).apply(javaFile)).isFalse();
}
+
+ @Test
+ public void hasFilename() {
+ assertThat(predicates.hasFilename("Action.java").apply(javaFile)).isTrue();
+ }
+
+ @Test
+ public void hasExtension() {
+ assertThat(predicates.hasExtension("java").apply(javaFile)).isTrue();
+ }
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java
new file mode 100644
index 00000000000..4de9de7723c
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.io.IOException;
+import org.junit.*;
+import org.sonar.api.batch.fs.InputFile;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.*;
+import static org.sonar.api.batch.fs.internal.FileExtensionPredicate.getExtension;
+
+public class FileExtensionPredicateTest {
+
+ @Test
+ public void should_match_correct_extension() throws IOException {
+ FileExtensionPredicate predicate = new FileExtensionPredicate("bat");
+ assertThat(predicate.apply(mockWithName("prog.bat"))).isTrue();
+ assertThat(predicate.apply(mockWithName("prog.bat.bat"))).isTrue();
+ }
+
+ @Test
+ public void should_not_match_incorrect_extension() throws IOException {
+ FileExtensionPredicate predicate = new FileExtensionPredicate("bat");
+ assertThat(predicate.apply(mockWithName("prog.batt"))).isFalse();
+ assertThat(predicate.apply(mockWithName("prog.abat"))).isFalse();
+ assertThat(predicate.apply(mockWithName("prog."))).isFalse();
+ assertThat(predicate.apply(mockWithName("prog.bat."))).isFalse();
+ assertThat(predicate.apply(mockWithName("prog.bat.batt"))).isFalse();
+ assertThat(predicate.apply(mockWithName("prog"))).isFalse();
+ }
+
+ @Test
+ public void should_match_correct_extension_case_insensitively() throws IOException {
+ FileExtensionPredicate predicate = new FileExtensionPredicate("jAVa");
+ assertThat(predicate.apply(mockWithName("Program.java"))).isTrue();
+ assertThat(predicate.apply(mockWithName("Program.JAVA"))).isTrue();
+ assertThat(predicate.apply(mockWithName("Program.Java"))).isTrue();
+ assertThat(predicate.apply(mockWithName("Program.JaVa"))).isTrue();
+ }
+
+ @Test
+ public void test_empty_extension() {
+ assertThat(getExtension("prog")).isEmpty();
+ assertThat(getExtension("prog.")).isEmpty();
+ assertThat(getExtension(".")).isEmpty();
+ }
+
+ private InputFile mockWithName(String filename) throws IOException {
+ InputFile inputFile = mock(InputFile.class);
+ when(inputFile.file()).thenReturn(new File("dummy parent", filename));
+ return inputFile;
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java
new file mode 100644
index 00000000000..edcaadd70fb
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java
@@ -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.api.batch.fs.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import org.junit.*;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.*;
+
+public class FilenamePredicateTest {
+ @Test
+ public void should_match_file_by_filename() throws IOException {
+ String filename = "some name";
+ InputFile inputFile = mock(InputFile.class);
+ when(inputFile.file()).thenReturn(newDummyFile(filename));
+
+ assertThat(new FilenamePredicate(filename).apply(inputFile)).isTrue();
+ }
+
+ @Test
+ public void should_not_match_file_by_different_filename() throws IOException {
+ String filename = "some name";
+ InputFile inputFile = mock(InputFile.class);
+ when(inputFile.file()).thenReturn(newDummyFile(filename + "x"));
+
+ assertThat(new FilenamePredicate(filename).apply(inputFile)).isFalse();
+ }
+
+ @Test
+ public void should_find_matching_file_in_index() throws IOException {
+ String filename = "some name";
+ InputFile inputFile = mock(InputFile.class);
+ when(inputFile.file()).thenReturn(newDummyFile(filename));
+
+ FileSystem.Index index = mock(FileSystem.Index.class);
+ when(index.getFilesByName(filename)).thenReturn(Collections.singleton(inputFile));
+
+ assertThat(new FilenamePredicate(filename).get(index)).containsOnly(inputFile);
+ }
+
+ private File newDummyFile(String filename) {
+ return new File("dummy parent", filename);
+ }
+}