diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2019-06-04 09:24:58 -0500 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-07-12 20:21:13 +0200 |
commit | e3a0108ef0dd26689dc58198e85ba8655c77fb1f (patch) | |
tree | d2cedb4bfd8cb6ac737420b8f45713475871ee89 /sonar-plugin-api/src | |
parent | 0f63c1e2bdf0c9fad3ca66ea64ef197bb16e6258 (diff) | |
download | sonarqube-e3a0108ef0dd26689dc58198e85ba8655c77fb1f.tar.gz sonarqube-e3a0108ef0dd26689dc58198e85ba8655c77fb1f.zip |
Extract implementation from plugin API - Scanner FS
Diffstat (limited to 'sonar-plugin-api/src')
39 files changed, 5 insertions, 3066 deletions
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 index 701a2182348..d29918e3dc1 100644 --- 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 @@ -25,12 +25,11 @@ import java.io.InputStream; import java.nio.charset.Charset; import java.nio.file.Path; import javax.annotation.CheckForNull; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.SensorDescriptor; /** * This layer over {@link java.io.File} adds information for code analyzers. - * For unit testing purpose, use {@link TestInputFileBuilder} and initialize + * For unit testing purpose, use TestInputFileBuilder and initialize * the needed fields: * * <pre> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java deleted file mode 100644 index 89af60d238f..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.Index; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.api.utils.PathUtils; - -import java.io.File; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; - -/** - * @since 4.2 - */ -class AbsolutePathPredicate extends AbstractFilePredicate { - - private final String path; - private final Path baseDir; - - AbsolutePathPredicate(String path, Path baseDir) { - this.baseDir = baseDir; - this.path = PathUtils.sanitize(path); - } - - @Override - public boolean apply(InputFile f) { - return path.equals(f.absolutePath()); - } - - @Override - public Iterable<InputFile> get(Index index) { - String relative = PathUtils.sanitize(new PathResolver().relativePath(baseDir.toFile(), new File(path))); - if (relative == null) { - return Collections.emptyList(); - } - InputFile f = index.inputFile(relative); - return f != null ? Arrays.asList(f) : Collections.<InputFile>emptyList(); - } - - @Override - public int priority() { - return USE_INDEX; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractFilePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractFilePredicate.java deleted file mode 100644 index 62f8355b949..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractFilePredicate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.stream.StreamSupport; -import org.sonar.api.batch.fs.FileSystem.Index; -import org.sonar.api.batch.fs.InputFile; - -/** - * Partial implementation of {@link OptimizedFilePredicate}. - * @since 5.1 - */ -public abstract class AbstractFilePredicate implements OptimizedFilePredicate { - - protected static final int DEFAULT_PRIORITY = 10; - protected static final int USE_INDEX = 20; - - @Override - public Iterable<InputFile> filter(Iterable<InputFile> target) { - return () -> StreamSupport.stream(target.spliterator(), false) - .filter(this::apply) - .iterator(); - } - - @Override - public Iterable<InputFile> get(Index index) { - return filter(index.inputFiles()); - } - - @Override - public int priority() { - return DEFAULT_PRIORITY; - } - - @Override - public final int compareTo(OptimizedFilePredicate o) { - return o.priority() - priority(); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java deleted file mode 100644 index 932e2a2ef62..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.FileSystem.Index; -import org.sonar.api.batch.fs.InputFile; - -import static java.util.stream.Collectors.toList; - -/** - * @since 4.2 - */ -class AndPredicate extends AbstractFilePredicate implements OperatorPredicate { - - private final List<OptimizedFilePredicate> predicates = new ArrayList<>(); - - private AndPredicate() { - } - - public static FilePredicate create(Collection<FilePredicate> predicates) { - if (predicates.isEmpty()) { - return TruePredicate.TRUE; - } - AndPredicate result = new AndPredicate(); - for (FilePredicate filePredicate : predicates) { - if (filePredicate == TruePredicate.TRUE) { - continue; - } else if (filePredicate == FalsePredicate.FALSE) { - return FalsePredicate.FALSE; - } else if (filePredicate instanceof AndPredicate) { - result.predicates.addAll(((AndPredicate) filePredicate).predicates); - } else { - result.predicates.add(OptimizedFilePredicateAdapter.create(filePredicate)); - } - } - Collections.sort(result.predicates); - return result; - } - - @Override - public boolean apply(InputFile f) { - for (OptimizedFilePredicate predicate : predicates) { - if (!predicate.apply(f)) { - return false; - } - } - return true; - } - - @Override - public Iterable<InputFile> filter(Iterable<InputFile> target) { - Iterable<InputFile> result = target; - for (OptimizedFilePredicate predicate : predicates) { - result = predicate.filter(result); - } - return result; - } - - @Override - public Iterable<InputFile> get(Index index) { - if (predicates.isEmpty()) { - return index.inputFiles(); - } - // Optimization, use get on first predicate then filter with next predicates - Iterable<InputFile> result = predicates.get(0).get(index); - for (int i = 1; i < predicates.size(); i++) { - result = predicates.get(i).filter(result); - } - return result; - } - - Collection<OptimizedFilePredicate> predicates() { - return predicates; - } - - @Override - public List<FilePredicate> operands() { - return predicates.stream().map(p -> (FilePredicate) p).collect(toList()); - } - -} 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 deleted file mode 100644 index 4d36ce60c82..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.net.URI; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.FilePredicates; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputFile.Status; - -/** - * Factory of {@link org.sonar.api.batch.fs.FilePredicate} - * - * @since 4.2 - */ -public class DefaultFilePredicates implements FilePredicates { - - private final Path baseDir; - - /** - * Client code should use {@link org.sonar.api.batch.fs.FileSystem#predicates()} to get an instance - */ - public DefaultFilePredicates(Path baseDir) { - this.baseDir = baseDir; - } - - /** - * Returns a predicate that always evaluates to true - */ - @Override - public FilePredicate all() { - return TruePredicate.TRUE; - } - - /** - * Returns a predicate that always evaluates to false - */ - @Override - public FilePredicate none() { - return FalsePredicate.FALSE; - } - - @Override - public FilePredicate hasAbsolutePath(String s) { - return new AbsolutePathPredicate(s, baseDir); - } - - /** - * non-normalized path and Windows-style path are supported - */ - @Override - public FilePredicate hasRelativePath(String s) { - return new RelativePathPredicate(s); - } - - @Override - public FilePredicate hasFilename(String s) { - return new FilenamePredicate(s); - } - - @Override - public FilePredicate hasExtension(String s) { - return new FileExtensionPredicate(s); - } - - @Override - public FilePredicate hasURI(URI uri) { - return new URIPredicate(uri, baseDir); - } - - @Override - public FilePredicate matchesPathPattern(String inclusionPattern) { - return new PathPatternPredicate(PathPattern.create(inclusionPattern)); - } - - @Override - public FilePredicate matchesPathPatterns(String[] inclusionPatterns) { - if (inclusionPatterns.length == 0) { - return TruePredicate.TRUE; - } - FilePredicate[] predicates = new FilePredicate[inclusionPatterns.length]; - for (int i = 0; i < inclusionPatterns.length; i++) { - predicates[i] = new PathPatternPredicate(PathPattern.create(inclusionPatterns[i])); - } - return or(predicates); - } - - @Override - public FilePredicate doesNotMatchPathPattern(String exclusionPattern) { - return not(matchesPathPattern(exclusionPattern)); - } - - @Override - public FilePredicate doesNotMatchPathPatterns(String[] exclusionPatterns) { - if (exclusionPatterns.length == 0) { - return TruePredicate.TRUE; - } - return not(matchesPathPatterns(exclusionPatterns)); - } - - @Override - public FilePredicate hasPath(String s) { - File file = new File(s); - if (file.isAbsolute()) { - return hasAbsolutePath(s); - } - return hasRelativePath(s); - } - - @Override - public FilePredicate is(File ioFile) { - if (ioFile.isAbsolute()) { - return hasAbsolutePath(ioFile.getAbsolutePath()); - } - return hasRelativePath(ioFile.getPath()); - } - - @Override - public FilePredicate hasLanguage(String language) { - return new LanguagePredicate(language); - } - - @Override - public FilePredicate hasLanguages(Collection<String> languages) { - List<FilePredicate> list = new ArrayList<>(); - for (String language : languages) { - list.add(hasLanguage(language)); - } - return or(list); - } - - @Override - public FilePredicate hasLanguages(String... languages) { - List<FilePredicate> list = new ArrayList<>(); - for (String language : languages) { - list.add(hasLanguage(language)); - } - return or(list); - } - - @Override - public FilePredicate hasType(InputFile.Type type) { - return new TypePredicate(type); - } - - @Override - public FilePredicate not(FilePredicate p) { - return new NotPredicate(p); - } - - @Override - public FilePredicate or(Collection<FilePredicate> or) { - return OrPredicate.create(or); - } - - @Override - public FilePredicate or(FilePredicate... or) { - return OrPredicate.create(Arrays.asList(or)); - } - - @Override - public FilePredicate or(FilePredicate first, FilePredicate second) { - return OrPredicate.create(Arrays.asList(first, second)); - } - - @Override - public FilePredicate and(Collection<FilePredicate> and) { - return AndPredicate.create(and); - } - - @Override - public FilePredicate and(FilePredicate... and) { - return AndPredicate.create(Arrays.asList(and)); - } - - @Override - public FilePredicate and(FilePredicate first, FilePredicate second) { - return AndPredicate.create(Arrays.asList(first, second)); - } - - @Override - public FilePredicate hasStatus(Status status) { - return new StatusPredicate(status); - } - - @Override - public FilePredicate hasAnyStatus() { - return new StatusPredicate(null); - } -} 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 deleted file mode 100644 index 3b9b7ac22e9..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.nio.charset.Charset; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.stream.StreamSupport; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.FilePredicates; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.fs.InputDir; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.api.utils.PathUtils; - -/** - * @since 4.2 - */ -public class DefaultFileSystem implements FileSystem { - - private final Cache cache; - private final Path baseDir; - private Path workDir; - private Charset encoding; - protected final FilePredicates predicates; - - /** - * Only for testing - */ - public DefaultFileSystem(Path baseDir) { - this(baseDir, new MapCache()); - } - - /** - * Only for testing - */ - public DefaultFileSystem(File baseDir) { - this(baseDir.toPath(), new MapCache()); - } - - protected DefaultFileSystem(Path baseDir, Cache cache) { - this.baseDir = baseDir; - this.cache = cache; - this.predicates = new DefaultFilePredicates(this.baseDir); - } - - public Path baseDirPath() { - return baseDir; - } - - @Override - public File baseDir() { - return baseDir.toFile(); - } - - public DefaultFileSystem setEncoding(Charset e) { - this.encoding = e; - return this; - } - - @Override - public Charset encoding() { - return encoding; - } - - public DefaultFileSystem setWorkDir(Path d) { - this.workDir = d; - return this; - } - - @Override - public File workDir() { - return workDir.toFile(); - } - - @Override - public InputFile inputFile(FilePredicate predicate) { - Iterable<InputFile> files = inputFiles(predicate); - Iterator<InputFile> iterator = files.iterator(); - if (!iterator.hasNext()) { - return null; - } - InputFile first = iterator.next(); - if (!iterator.hasNext()) { - return first; - } - - StringBuilder sb = new StringBuilder(); - sb.append("expected one element but was: <" + first); - for (int i = 0; i < 4 && iterator.hasNext(); i++) { - sb.append(", " + iterator.next()); - } - if (iterator.hasNext()) { - sb.append(", ..."); - } - sb.append('>'); - - throw new IllegalArgumentException(sb.toString()); - - } - - public Iterable<InputFile> inputFiles() { - return inputFiles(predicates.all()); - } - - @Override - public Iterable<InputFile> inputFiles(FilePredicate predicate) { - return OptimizedFilePredicateAdapter.create(predicate).get(cache); - } - - @Override - public boolean hasFiles(FilePredicate predicate) { - return inputFiles(predicate).iterator().hasNext(); - } - - @Override - public Iterable<File> files(FilePredicate predicate) { - return () -> StreamSupport.stream(inputFiles(predicate).spliterator(), false) - .map(InputFile::file) - .iterator(); - } - - @Override - public InputDir inputDir(File dir) { - String relativePath = PathUtils.sanitize(new PathResolver().relativePath(baseDir.toFile(), dir)); - if (relativePath == null) { - return null; - } - // Issues on InputDir are moved to the project, so we just return a fake InputDir for backward compatibility - return new DefaultInputDir("unused", relativePath).setModuleBaseDir(baseDir); - } - - public DefaultFileSystem add(InputFile inputFile) { - cache.add(inputFile); - return this; - } - - @Override - public SortedSet<String> languages() { - return cache.languages(); - } - - @Override - public FilePredicates predicates() { - return predicates; - } - - public abstract static class Cache implements Index { - - protected abstract void doAdd(InputFile inputFile); - - final void add(InputFile inputFile) { - doAdd(inputFile); - } - - protected abstract SortedSet<String> languages(); - } - - /** - * Used only for testing - */ - private static class MapCache extends Cache { - private final Map<String, InputFile> fileMap = new HashMap<>(); - private final Map<String, Set<InputFile>> filesByNameCache = new HashMap<>(); - private final Map<String, Set<InputFile>> filesByExtensionCache = new HashMap<>(); - private SortedSet<String> languages = new TreeSet<>(); - - @Override - public Iterable<InputFile> inputFiles() { - return new ArrayList<>(fileMap.values()); - } - - @Override - public InputFile inputFile(String relativePath) { - return fileMap.get(relativePath); - } - - @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) { - if (inputFile.language() != null) { - languages.add(inputFile.language()); - } - fileMap.put(inputFile.relativePath(), inputFile); - filesByNameCache.computeIfAbsent(inputFile.filename(), x -> new HashSet<>()).add(inputFile); - filesByExtensionCache.computeIfAbsent(FileExtensionPredicate.getExtension(inputFile), x -> new HashSet<>()).add(inputFile); - } - - @Override - protected SortedSet<String> languages() { - return languages; - } - } - - @Override - public File resolvePath(String path) { - File file = new File(path); - if (!file.isAbsolute()) { - try { - file = new File(baseDir(), path).getCanonicalFile(); - } catch (IOException e) { - throw new IllegalArgumentException("Unable to resolve path '" + path + "'", e); - } - } - return file; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java index 1488121129c..ba7cb94cff3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java @@ -45,14 +45,6 @@ public class DefaultIndexedFile extends DefaultInputComponent implements Indexed private final Path absolutePath; private final SensorStrategy sensorStrategy; - /** - * Testing purposes only! - */ - public DefaultIndexedFile(String projectKey, Path baseDir, String relativePath, @Nullable String language) { - this(baseDir.resolve(relativePath), projectKey, relativePath, relativePath, Type.MAIN, language, TestInputFileBuilder.nextBatchId(), - new SensorStrategy()); - } - public DefaultIndexedFile(Path absolutePath, String projectKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId, SensorStrategy sensorStrategy) { super(batchId); 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 index 5dbcf99c541..19381e4c7ea 100644 --- 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 @@ -49,7 +49,7 @@ import static org.sonar.api.utils.Preconditions.checkState; /** * @since 4.2 - * To create {@link InputFile} in tests, use {@link TestInputFileBuilder}. + * To create {@link InputFile} in tests, use TestInputFileBuilder. */ public class DefaultInputFile extends DefaultInputComponent implements InputFile { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java deleted file mode 100644 index 8bbbea90f41..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.FilePredicate; -import org.sonar.api.batch.fs.FileSystem.Index; -import org.sonar.api.batch.fs.InputFile; - -import java.util.Collections; - -class FalsePredicate extends AbstractFilePredicate { - - static final FilePredicate FALSE = new FalsePredicate(); - - @Override - public boolean apply(InputFile inputFile) { - return false; - } - - @Override - public Iterable<InputFile> filter(Iterable<InputFile> target) { - return Collections.emptyList(); - } - - @Override - public Iterable<InputFile> get(Index index) { - return Collections.emptyList(); - } -} 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 deleted file mode 100644 index e9fa863b645..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileExtensionPredicate.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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(inputFile.filename()); - } - - 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/FileMetadata.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java deleted file mode 100644 index bda14d89d4b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.charhandler.CharHandler; -import org.sonar.api.batch.fs.internal.charhandler.FileHashComputer; -import org.sonar.api.batch.fs.internal.charhandler.LineCounter; -import org.sonar.api.batch.fs.internal.charhandler.LineHashComputer; -import org.sonar.api.batch.fs.internal.charhandler.LineOffsetCounter; - -/** - * Computes hash of files. Ends of Lines are ignored, so files with - * same content but different EOL encoding have the same hash. - */ -@Immutable -public class FileMetadata { - private static final char LINE_FEED = '\n'; - private static final char CARRIAGE_RETURN = '\r'; - - /** - * Compute hash of a file ignoring line ends differences. - * Maximum performance is needed. - */ - public Metadata readMetadata(InputStream stream, Charset encoding, String filePath, @Nullable CharHandler otherHandler) { - LineCounter lineCounter = new LineCounter(filePath, encoding); - FileHashComputer fileHashComputer = new FileHashComputer(filePath); - LineOffsetCounter lineOffsetCounter = new LineOffsetCounter(); - - if (otherHandler != null) { - CharHandler[] handlers = {lineCounter, fileHashComputer, lineOffsetCounter, otherHandler}; - readFile(stream, encoding, filePath, handlers); - } else { - CharHandler[] handlers = {lineCounter, fileHashComputer, lineOffsetCounter}; - readFile(stream, encoding, filePath, handlers); - } - return new Metadata(lineCounter.lines(), lineCounter.nonBlankLines(), fileHashComputer.getHash(), lineOffsetCounter.getOriginalLineStartOffsets(), - lineOffsetCounter.getOriginalLineEndOffsets(), - lineOffsetCounter.getLastValidOffset()); - } - - public Metadata readMetadata(InputStream stream, Charset encoding, String filePath) { - return readMetadata(stream, encoding, filePath, null); - } - - /** - * For testing purpose - */ - public Metadata readMetadata(Reader reader) { - LineCounter lineCounter = new LineCounter("fromString", StandardCharsets.UTF_16); - FileHashComputer fileHashComputer = new FileHashComputer("fromString"); - LineOffsetCounter lineOffsetCounter = new LineOffsetCounter(); - CharHandler[] handlers = {lineCounter, fileHashComputer, lineOffsetCounter}; - - try { - read(reader, handlers); - } catch (IOException e) { - throw new IllegalStateException("Should never occur", e); - } - return new Metadata(lineCounter.lines(), lineCounter.nonBlankLines(), fileHashComputer.getHash(), lineOffsetCounter.getOriginalLineStartOffsets(), - lineOffsetCounter.getOriginalLineEndOffsets(), - lineOffsetCounter.getLastValidOffset()); - } - - public static void readFile(InputStream stream, Charset encoding, String filePath, CharHandler[] handlers) { - try (Reader reader = new BufferedReader(new InputStreamReader(stream, encoding))) { - read(reader, handlers); - } catch (IOException e) { - throw new IllegalStateException(String.format("Fail to read file '%s' with encoding '%s'", filePath, encoding), e); - } - } - - private static void read(Reader reader, CharHandler[] handlers) throws IOException { - char c; - int i = reader.read(); - boolean afterCR = false; - while (i != -1) { - c = (char) i; - if (afterCR) { - for (CharHandler handler : handlers) { - if (c == CARRIAGE_RETURN) { - handler.newLine(); - handler.handleAll(c); - } else if (c == LINE_FEED) { - handler.handleAll(c); - handler.newLine(); - } else { - handler.newLine(); - handler.handleIgnoreEoL(c); - handler.handleAll(c); - } - } - afterCR = c == CARRIAGE_RETURN; - } else if (c == LINE_FEED) { - for (CharHandler handler : handlers) { - handler.handleAll(c); - handler.newLine(); - } - } else if (c == CARRIAGE_RETURN) { - afterCR = true; - for (CharHandler handler : handlers) { - handler.handleAll(c); - } - } else { - for (CharHandler handler : handlers) { - handler.handleIgnoreEoL(c); - handler.handleAll(c); - } - } - i = reader.read(); - } - for (CharHandler handler : handlers) { - if (afterCR) { - handler.newLine(); - } - handler.eof(); - } - } - - @FunctionalInterface - public interface LineHashConsumer { - void consume(int lineIdx, @Nullable byte[] hash); - } - - /** - * Compute a MD5 hash of each line of the file after removing of all blank chars - */ - public static void computeLineHashesForIssueTracking(InputFile f, LineHashConsumer consumer) { - try { - readFile(f.inputStream(), f.charset(), f.absolutePath(), new CharHandler[] {new LineHashComputer(consumer, f.file())}); - } catch (IOException e) { - throw new IllegalStateException("Failed to compute line hashes for " + f.absolutePath(), e); - } - } -} 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 deleted file mode 100644 index 303ff5797e7..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FilenamePredicate.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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(inputFile.filename()); - } - - @Override - public Iterable<InputFile> get(FileSystem.Index index) { - return index.getFilesByName(filename); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java deleted file mode 100644 index 433bbc35bfd..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import org.sonar.api.batch.fs.InputFile; - -/** - * @since 4.2 - */ -class LanguagePredicate extends AbstractFilePredicate { - 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/internal/NotPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java deleted file mode 100644 index bd82a7a1c3b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.Arrays; -import java.util.List; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.InputFile; - -/** - * @since 4.2 - */ -class NotPredicate extends AbstractFilePredicate implements OperatorPredicate { - - private final FilePredicate predicate; - - NotPredicate(FilePredicate predicate) { - this.predicate = predicate; - } - - @Override - public boolean apply(InputFile f) { - return !predicate.apply(f); - } - - @Override - public List<FilePredicate> operands() { - return Arrays.asList(predicate); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OperatorPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OperatorPredicate.java deleted file mode 100644 index 2c2b90f424f..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OperatorPredicate.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.List; -import org.sonar.api.batch.fs.FilePredicate; - -/** - * A predicate that associate other predicates - */ -public interface OperatorPredicate extends FilePredicate { - - List<FilePredicate> operands(); - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicate.java deleted file mode 100644 index c78696d0c75..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicate.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.FilePredicate; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.fs.InputFile; - -/** - * Optimized version of FilePredicate allowing to speed up query by looking at InputFile by index. - */ -public interface OptimizedFilePredicate extends FilePredicate, Comparable<OptimizedFilePredicate> { - - /** - * Filter provided files to keep only the ones that are valid for this predicate - */ - Iterable<InputFile> filter(Iterable<InputFile> inputFiles); - - /** - * Get all files that are valid for this predicate. - */ - Iterable<InputFile> get(FileSystem.Index index); - - /** - * For optimization. FilePredicates will be applied in priority order. For example when doing - * p.and(p1, p2, p3) then p1, p2 and p3 will be applied according to their priority value. Higher priority value - * are applied first. - * Assign a high priority when the predicate will likely highly reduce the set of InputFiles to filter. Also - * {@link RelativePathPredicate} and AbsolutePathPredicate have a high priority since they are using cache index. - */ - int priority(); -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java deleted file mode 100644 index 15a71972988..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.FilePredicate; -import org.sonar.api.batch.fs.InputFile; - -class OptimizedFilePredicateAdapter extends AbstractFilePredicate { - - private FilePredicate unoptimizedPredicate; - - private OptimizedFilePredicateAdapter(FilePredicate unoptimizedPredicate) { - this.unoptimizedPredicate = unoptimizedPredicate; - } - - @Override - public boolean apply(InputFile inputFile) { - return unoptimizedPredicate.apply(inputFile); - } - - public static OptimizedFilePredicate create(FilePredicate predicate) { - if (predicate instanceof OptimizedFilePredicate) { - return (OptimizedFilePredicate) predicate; - } else { - return new OptimizedFilePredicateAdapter(predicate); - } - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java deleted file mode 100644 index 58c81e4e31b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.ArrayList; -import java.util.Collection; -import java.util.List; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.InputFile; - -/** - * @since 4.2 - */ -class OrPredicate extends AbstractFilePredicate implements OperatorPredicate { - - private final List<FilePredicate> predicates = new ArrayList<>(); - - private OrPredicate() { - } - - public static FilePredicate create(Collection<FilePredicate> predicates) { - if (predicates.isEmpty()) { - return TruePredicate.TRUE; - } - OrPredicate result = new OrPredicate(); - for (FilePredicate filePredicate : predicates) { - if (filePredicate == TruePredicate.TRUE) { - return TruePredicate.TRUE; - } else if (filePredicate == FalsePredicate.FALSE) { - continue; - } else if (filePredicate instanceof OrPredicate) { - result.predicates.addAll(((OrPredicate) filePredicate).predicates); - } else { - result.predicates.add(filePredicate); - } - } - return result; - } - - @Override - public boolean apply(InputFile f) { - for (FilePredicate predicate : predicates) { - if (predicate.apply(f)) { - return true; - } - } - return false; - } - - Collection<FilePredicate> predicates() { - return predicates; - } - - @Override - public List<FilePredicate> operands() { - return predicates; - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java deleted file mode 100644 index ea9bea14054..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.nio.file.Paths; -import org.sonar.api.batch.fs.InputFile; - -/** - * @since 4.2 - */ -class PathPatternPredicate extends AbstractFilePredicate { - - private final PathPattern pattern; - - PathPatternPredicate(PathPattern pattern) { - this.pattern = pattern; - } - - @Override - public boolean apply(InputFile f) { - return pattern.match(f.path(), Paths.get(f.relativePath())); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java deleted file mode 100644 index 27c2958e460..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.Collections; -import javax.annotation.Nullable; -import org.sonar.api.batch.fs.FileSystem.Index; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.utils.PathUtils; - -/** - * @since 4.2 - */ -public class RelativePathPredicate extends AbstractFilePredicate { - - @Nullable - private final String path; - - RelativePathPredicate(String path) { - this.path = PathUtils.sanitize(path); - } - - public String path() { - return path; - } - - @Override - public boolean apply(InputFile f) { - if (path == null) { - return false; - } - - return path.equals(f.relativePath()); - } - - @Override - public Iterable<InputFile> get(Index index) { - if (path != null) { - InputFile f = index.inputFile(this.path); - if (f != null) { - return Collections.singletonList(f); - } - } - return Collections.emptyList(); - } - - @Override - public int priority() { - return USE_INDEX; - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java deleted file mode 100644 index 7aaaf4cba56..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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 javax.annotation.Nullable; -import org.sonar.api.batch.fs.InputFile; - -/** - * @deprecated since 7.8 - */ -@Deprecated -public class StatusPredicate extends AbstractFilePredicate { - - private final InputFile.Status status; - - StatusPredicate(@Nullable InputFile.Status status) { - this.status = status; - } - - @Override - public boolean apply(InputFile f) { - return status == null || status == f.status(); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java deleted file mode 100644 index 00f9319c2d4..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.io.StringReader; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.LinkOption; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.utils.PathUtils; - -/** - * Intended to be used in unit tests that need to create {@link InputFile}s. - * An InputFile is unambiguously identified by a <b>module key</b> and a <b>relative path</b>, so these parameters are mandatory. - * <p> - * A module base directory is only needed to construct absolute paths. - * <p> - * Examples of usage of the constructors: - * - * <pre> - * InputFile file1 = TestInputFileBuilder.create("module1", "myfile.java").build(); - * InputFile file2 = TestInputFileBuilder.create("", fs.baseDir(), myfile).build(); - * </pre> - * <p> - * file1 will have the "module1" as both module key and module base directory. - * file2 has an empty string as module key, and a relative path which is the path from the filesystem base directory to myfile. - * - * @since 6.3 - */ -public class TestInputFileBuilder { - private static int batchId = 1; - - private final int id; - private final String relativePath; - private final String projectKey; - @CheckForNull - private Path projectBaseDir; - private Path moduleBaseDir; - private String language; - private InputFile.Type type = InputFile.Type.MAIN; - private InputFile.Status status; - private int lines = -1; - private Charset charset; - private String hash; - private int nonBlankLines; - private int[] originalLineStartOffsets = new int[0]; - private int[] originalLineEndOffsets = new int[0]; - private int lastValidOffset = -1; - private boolean publish = true; - private String contents; - - /** - * Create a InputFile identified by the given project key and relative path. - */ - public TestInputFileBuilder(String projectKey, String relativePath) { - this(projectKey, relativePath, batchId++); - } - - /** - * Create a InputFile with a given module key and module base directory. - * The relative path is generated comparing the file path to the module base directory. - * filePath must point to a file that is within the module base directory. - */ - public TestInputFileBuilder(String projectKey, File moduleBaseDir, File filePath) { - String relativePath = moduleBaseDir.toPath().relativize(filePath.toPath()).toString(); - this.projectKey = projectKey; - setModuleBaseDir(moduleBaseDir.toPath()); - this.relativePath = PathUtils.sanitize(relativePath); - this.id = batchId++; - } - - public TestInputFileBuilder(String projectKey, String relativePath, int id) { - this.projectKey = projectKey; - setModuleBaseDir(Paths.get(projectKey)); - this.relativePath = PathUtils.sanitize(relativePath); - this.id = id; - } - - public static TestInputFileBuilder create(String moduleKey, File moduleBaseDir, File filePath) { - return new TestInputFileBuilder(moduleKey, moduleBaseDir, filePath); - } - - public static TestInputFileBuilder create(String moduleKey, String relativePath) { - return new TestInputFileBuilder(moduleKey, relativePath); - } - - public static int nextBatchId() { - return batchId++; - } - - public TestInputFileBuilder setProjectBaseDir(Path projectBaseDir) { - this.projectBaseDir = normalize(projectBaseDir); - return this; - } - - public TestInputFileBuilder setModuleBaseDir(Path moduleBaseDir) { - this.moduleBaseDir = normalize(moduleBaseDir); - return this; - } - - private static Path normalize(Path path) { - try { - return path.normalize().toRealPath(LinkOption.NOFOLLOW_LINKS); - } catch (IOException e) { - return path.normalize(); - } - } - - public TestInputFileBuilder setLanguage(@Nullable String language) { - this.language = language; - return this; - } - - public TestInputFileBuilder setType(InputFile.Type type) { - this.type = type; - return this; - } - - public TestInputFileBuilder setStatus(InputFile.Status status) { - this.status = status; - return this; - } - - public TestInputFileBuilder setLines(int lines) { - this.lines = lines; - return this; - } - - public TestInputFileBuilder setCharset(Charset charset) { - this.charset = charset; - return this; - } - - public TestInputFileBuilder setHash(String hash) { - this.hash = hash; - return this; - } - - /** - * Set contents of the file and calculates metadata from it. - * The contents will be returned by {@link InputFile#contents()} and {@link InputFile#inputStream()} and can be - * inconsistent with the actual physical file pointed by {@link InputFile#path()}, {@link InputFile#absolutePath()}, etc. - */ - public TestInputFileBuilder setContents(String content) { - this.contents = content; - initMetadata(content); - return this; - } - - public TestInputFileBuilder setNonBlankLines(int nonBlankLines) { - this.nonBlankLines = nonBlankLines; - return this; - } - - public TestInputFileBuilder setLastValidOffset(int lastValidOffset) { - this.lastValidOffset = lastValidOffset; - return this; - } - - public TestInputFileBuilder setOriginalLineStartOffsets(int[] originalLineStartOffsets) { - this.originalLineStartOffsets = originalLineStartOffsets; - return this; - } - - public TestInputFileBuilder setOriginalLineEndOffsets(int[] originalLineEndOffsets) { - this.originalLineEndOffsets = originalLineEndOffsets; - return this; - } - - public TestInputFileBuilder setPublish(boolean publish) { - this.publish = publish; - return this; - } - - public TestInputFileBuilder setMetadata(Metadata metadata) { - this.setLines(metadata.lines()); - this.setLastValidOffset(metadata.lastValidOffset()); - this.setNonBlankLines(metadata.nonBlankLines()); - this.setHash(metadata.hash()); - this.setOriginalLineStartOffsets(metadata.originalLineStartOffsets()); - this.setOriginalLineEndOffsets(metadata.originalLineEndOffsets()); - return this; - } - - public TestInputFileBuilder initMetadata(String content) { - return setMetadata(new FileMetadata().readMetadata(new StringReader(content))); - } - - public DefaultInputFile build() { - Path absolutePath = moduleBaseDir.resolve(relativePath); - if (projectBaseDir == null) { - projectBaseDir = moduleBaseDir; - } - String projectRelativePath = projectBaseDir.relativize(absolutePath).toString(); - DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, projectKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy()); - DefaultInputFile inputFile = new DefaultInputFile(indexedFile, - f -> f.setMetadata(new Metadata(lines, nonBlankLines, hash, originalLineStartOffsets, originalLineEndOffsets, lastValidOffset)), - contents); - inputFile.setStatus(status); - inputFile.setCharset(charset); - inputFile.setPublished(publish); - return inputFile; - } - - public static DefaultInputModule newDefaultInputModule(String moduleKey, File baseDir) { - ProjectDefinition definition = ProjectDefinition.create() - .setKey(moduleKey) - .setBaseDir(baseDir) - .setWorkDir(new File(baseDir, ".sonar")); - return newDefaultInputModule(definition); - } - - public static DefaultInputModule newDefaultInputModule(ProjectDefinition projectDefinition) { - return new DefaultInputModule(projectDefinition, TestInputFileBuilder.nextBatchId()); - } - - public static DefaultInputModule newDefaultInputModule(AbstractProjectOrModule parent, String key) throws IOException { - Path basedir = parent.getBaseDir().resolve(key); - Files.createDirectory(basedir); - return newDefaultInputModule(key, basedir.toFile()); - } - - public static DefaultInputProject newDefaultInputProject(String projectKey, File baseDir) { - ProjectDefinition definition = ProjectDefinition.create() - .setKey(projectKey) - .setBaseDir(baseDir) - .setWorkDir(new File(baseDir, ".sonar")); - return newDefaultInputProject(definition); - } - - public static DefaultInputProject newDefaultInputProject(ProjectDefinition projectDefinition) { - return new DefaultInputProject(projectDefinition, TestInputFileBuilder.nextBatchId()); - } - - public static DefaultInputProject newDefaultInputProject(String key, Path baseDir) throws IOException { - Files.createDirectory(baseDir); - return newDefaultInputProject(key, baseDir.toFile()); - } - - public static DefaultInputDir newDefaultInputDir(AbstractProjectOrModule module, String relativePath) throws IOException { - Path basedir = module.getBaseDir().resolve(relativePath); - Files.createDirectory(basedir); - return new DefaultInputDir(module.key(), relativePath) - .setModuleBaseDir(module.getBaseDir()); - } - - public static DefaultInputFile newDefaultInputFile(Path projectBaseDir, AbstractProjectOrModule module, String relativePath) { - return new TestInputFileBuilder(module.key(), relativePath) - .setStatus(InputFile.Status.SAME) - .setProjectBaseDir(projectBaseDir) - .setModuleBaseDir(module.getBaseDir()) - .build(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java deleted file mode 100644 index 6f4d9f637d1..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.FilePredicate; -import org.sonar.api.batch.fs.FileSystem.Index; -import org.sonar.api.batch.fs.InputFile; - -class TruePredicate extends AbstractFilePredicate { - - static final FilePredicate TRUE = new TruePredicate(); - - @Override - public boolean apply(InputFile inputFile) { - return true; - } - - @Override - public Iterable<InputFile> get(Index index) { - return index.inputFiles(); - } - - @Override - public Iterable<InputFile> filter(Iterable<InputFile> target) { - return target; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java deleted file mode 100644 index 55f364b048f..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import org.sonar.api.batch.fs.InputFile; - -/** - * @since 4.2 - */ -class TypePredicate extends AbstractFilePredicate { - - 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/main/java/org/sonar/api/batch/fs/internal/URIPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/URIPredicate.java deleted file mode 100644 index 2c710f1777b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/URIPredicate.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.net.URI; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collections; -import java.util.Optional; -import org.sonar.api.batch.fs.FileSystem.Index; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.scan.filesystem.PathResolver; - -/** - * @since 6.6 - */ -class URIPredicate extends AbstractFilePredicate { - - private final URI uri; - private final Path baseDir; - - URIPredicate(URI uri, Path baseDir) { - this.baseDir = baseDir; - this.uri = uri; - } - - @Override - public boolean apply(InputFile f) { - return uri.equals(f.uri()); - } - - @Override - public Iterable<InputFile> get(Index index) { - Path path = Paths.get(uri); - Optional<String> relative = PathResolver.relativize(baseDir, path); - if (!relative.isPresent()) { - return Collections.emptyList(); - } - InputFile f = index.inputFile(relative.get()); - return f != null ? Arrays.asList(f) : Collections.<InputFile>emptyList(); - } - - @Override - public int priority() { - return USE_INDEX; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/CharHandler.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/CharHandler.java deleted file mode 100644 index 8932b7d8994..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/CharHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.charhandler; - -public abstract class CharHandler { - - public void handleAll(char c) { - } - - public void handleIgnoreEoL(char c) { - } - - public void newLine() { - } - - public void eof() { - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/FileHashComputer.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/FileHashComputer.java deleted file mode 100644 index 42a8c7ae2f1..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/FileHashComputer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.charhandler; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CodingErrorAction; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; - -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.digest.DigestUtils; - -public class FileHashComputer extends CharHandler { - private static final char LINE_FEED = '\n'; - - - private MessageDigest globalMd5Digest = DigestUtils.getMd5Digest(); - private StringBuilder sb = new StringBuilder(); - private final CharsetEncoder encoder; - private final String filePath; - - public FileHashComputer(String filePath) { - encoder = StandardCharsets.UTF_8.newEncoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - this.filePath = filePath; - } - - @Override - public void handleIgnoreEoL(char c) { - sb.append(c); - } - - @Override - public void newLine() { - sb.append(LINE_FEED); - processBuffer(); - sb.setLength(0); - } - - @Override - public void eof() { - if (sb.length() > 0) { - processBuffer(); - } - } - - private void processBuffer() { - try { - if (sb.length() > 0) { - ByteBuffer encoded = encoder.encode(CharBuffer.wrap(sb)); - globalMd5Digest.update(encoded.array(), 0, encoded.limit()); - } - } catch (CharacterCodingException e) { - throw new IllegalStateException("Error encoding line hash in file: " + filePath, e); - } - } - - public String getHash() { - return Hex.encodeHexString(globalMd5Digest.digest()); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/IntArrayList.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/IntArrayList.java deleted file mode 100644 index 0795098bd7c..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/IntArrayList.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.charhandler; - -import java.util.Arrays; -import java.util.Collection; - -/** - * Specialization of {@link java.util.ArrayList} to create a list of int (only append elements) and then produce an int[]. - */ -class IntArrayList { - - /** - * Default initial capacity. - */ - private static final int DEFAULT_CAPACITY = 10; - - /** - * Shared empty array instance used for default sized empty instances. We - * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when - * first element is added. - */ - private static final int[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; - - /** - * The array buffer into which the elements of the ArrayList are stored. - * The capacity of the IntArrayList is the length of this array buffer. Any - * empty IntArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA - * will be expanded to DEFAULT_CAPACITY when the first element is added. - */ - private int[] elementData; - - /** - * The size of the IntArrayList (the number of elements it contains). - */ - private int size; - - /** - * Constructs an empty list with an initial capacity of ten. - */ - public IntArrayList() { - this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; - } - - /** - * Trims the capacity of this <tt>IntArrayList</tt> instance to be the - * list's current size and return the internal array. An application can use this operation to minimize - * the storage of an <tt>IntArrayList</tt> instance. - */ - public int[] trimAndGet() { - if (size < elementData.length) { - elementData = Arrays.copyOf(elementData, size); - } - return elementData; - } - - private void ensureCapacityInternal(int minCapacity) { - int capacity = minCapacity; - if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { - capacity = Math.max(DEFAULT_CAPACITY, minCapacity); - } - - ensureExplicitCapacity(capacity); - } - - private void ensureExplicitCapacity(int minCapacity) { - if (minCapacity - elementData.length > 0) { - grow(minCapacity); - } - } - - /** - * Increases the capacity to ensure that it can hold at least the - * number of elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity - */ - private void grow(int minCapacity) { - int oldCapacity = elementData.length; - int newCapacity = oldCapacity + (oldCapacity >> 1); - if (newCapacity - minCapacity < 0) { - newCapacity = minCapacity; - } - elementData = Arrays.copyOf(elementData, newCapacity); - } - - /** - * Appends the specified element to the end of this list. - * - * @param e element to be appended to this list - * @return <tt>true</tt> (as specified by {@link Collection#add}) - */ - public boolean add(int e) { - ensureCapacityInternal(size + 1); - elementData[size] = e; - size++; - return true; - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineCounter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineCounter.java deleted file mode 100644 index 9925e16e3a9..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineCounter.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.charhandler; - -import java.nio.charset.Charset; - -import org.sonar.api.CoreProperties; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -public class LineCounter extends CharHandler { - private static final Logger LOG = Loggers.get(LineCounter.class); - - private int lines = 1; - private int nonBlankLines = 0; - private boolean blankLine = true; - boolean alreadyLoggedInvalidCharacter = false; - private final String filePath; - private final Charset encoding; - - public LineCounter(String filePath, Charset encoding) { - this.filePath = filePath; - this.encoding = encoding; - } - - @Override - public void handleAll(char c) { - if (!alreadyLoggedInvalidCharacter && c == '\ufffd') { - LOG.warn("Invalid character encountered in file {} at line {} for encoding {}. Please fix file content or configure the encoding to be used using property '{}'.", filePath, - lines, encoding, CoreProperties.ENCODING_PROPERTY); - alreadyLoggedInvalidCharacter = true; - } - } - - @Override - public void newLine() { - lines++; - if (!blankLine) { - nonBlankLines++; - } - blankLine = true; - } - - @Override - public void handleIgnoreEoL(char c) { - if (!Character.isWhitespace(c)) { - blankLine = false; - } - } - - @Override - public void eof() { - if (!blankLine) { - nonBlankLines++; - } - } - - public int lines() { - return lines; - } - - public int nonBlankLines() { - return nonBlankLines; - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineHashComputer.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineHashComputer.java deleted file mode 100644 index ce0c62b4d1e..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineHashComputer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.charhandler; - -import java.io.File; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CodingErrorAction; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; - -import org.apache.commons.codec.digest.DigestUtils; -import org.sonar.api.batch.fs.internal.FileMetadata.LineHashConsumer; - -public class LineHashComputer extends CharHandler { - private final MessageDigest lineMd5Digest = DigestUtils.getMd5Digest(); - private final CharsetEncoder encoder; - private final StringBuilder sb = new StringBuilder(); - private final LineHashConsumer consumer; - private final File file; - private int line = 1; - - public LineHashComputer(LineHashConsumer consumer, File f) { - this.consumer = consumer; - this.file = f; - this.encoder = StandardCharsets.UTF_8.newEncoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - } - - @Override - public void handleIgnoreEoL(char c) { - if (!Character.isWhitespace(c)) { - sb.append(c); - } - } - - @Override - public void newLine() { - processBuffer(); - sb.setLength(0); - line++; - } - - @Override - public void eof() { - if (this.line > 0) { - processBuffer(); - } - } - - private void processBuffer() { - try { - if (sb.length() > 0) { - ByteBuffer encoded = encoder.encode(CharBuffer.wrap(sb)); - lineMd5Digest.update(encoded.array(), 0, encoded.limit()); - consumer.consume(line, lineMd5Digest.digest()); - } - } catch (CharacterCodingException e) { - throw new IllegalStateException("Error encoding line hash in file: " + file.getAbsolutePath(), e); - } - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineOffsetCounter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineOffsetCounter.java deleted file mode 100644 index 22292bef569..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineOffsetCounter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.charhandler; - -public class LineOffsetCounter extends CharHandler { - private long currentOriginalLineStartOffset = 0; - private long currentOriginalLineEndOffset = 0; - private final IntArrayList originalLineStartOffsets = new IntArrayList(); - private final IntArrayList originalLineEndOffsets = new IntArrayList(); - private long lastValidOffset = 0; - - public LineOffsetCounter() { - originalLineStartOffsets.add(0); - } - - @Override - public void handleAll(char c) { - currentOriginalLineStartOffset++; - } - - @Override - public void handleIgnoreEoL(char c) { - currentOriginalLineEndOffset++; - } - - @Override - public void newLine() { - if (currentOriginalLineStartOffset > Integer.MAX_VALUE) { - throw new IllegalStateException("File is too big: " + currentOriginalLineStartOffset); - } - originalLineStartOffsets.add((int) currentOriginalLineStartOffset); - originalLineEndOffsets.add((int) currentOriginalLineEndOffset); - currentOriginalLineEndOffset = currentOriginalLineStartOffset; - } - - @Override - public void eof() { - originalLineEndOffsets.add((int) currentOriginalLineEndOffset); - lastValidOffset = currentOriginalLineStartOffset; - } - - public int[] getOriginalLineStartOffsets() { - return originalLineStartOffsets.trimAndGet(); - } - - public int[] getOriginalLineEndOffsets() { - return originalLineEndOffsets.trimAndGet(); - } - - public int getLastValidOffset() { - if (lastValidOffset > Integer.MAX_VALUE) { - throw new IllegalStateException("File is too big: " + lastValidOffset); - } - return (int) lastValidOffset; - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/package-info.java deleted file mode 100644 index 953ee253c6a..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/charhandler/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.api.batch.fs.internal.charhandler; - -import javax.annotation.ParametersAreNonnullByDefault; - diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java deleted file mode 100644 index def001211e7..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.rule.internal; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.rule.Rule; -import org.sonar.api.batch.rule.Rules; -import org.sonar.api.rule.RuleKey; - -@Immutable -class DefaultRules implements Rules { - private final Map<String, List<Rule>> rulesByRepository; - private final Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKey; - private final Map<RuleKey, Rule> rulesByRuleKey; - - DefaultRules(Collection<NewRule> newRules) { - Map<String, List<Rule>> rulesByRepositoryBuilder = new HashMap<>(); - Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKeyBuilder = new HashMap<>(); - Map<RuleKey, Rule> rulesByRuleKeyBuilder = new HashMap<>(); - - for (NewRule newRule : newRules) { - DefaultRule r = new DefaultRule(newRule); - rulesByRuleKeyBuilder.put(r.key(), r); - rulesByRepositoryBuilder.computeIfAbsent(r.key().repository(), x -> new ArrayList<>()).add(r); - addToTable(rulesByRepositoryAndInternalKeyBuilder, r); - } - - rulesByRuleKey = Collections.unmodifiableMap(rulesByRuleKeyBuilder); - rulesByRepository = Collections.unmodifiableMap(rulesByRepositoryBuilder); - rulesByRepositoryAndInternalKey = Collections.unmodifiableMap(rulesByRepositoryAndInternalKeyBuilder); - } - - private static void addToTable(Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKeyBuilder, DefaultRule r) { - if (r.internalKey() == null) { - return; - } - - rulesByRepositoryAndInternalKeyBuilder - .computeIfAbsent(r.key().repository(), x -> new HashMap<>()) - .computeIfAbsent(r.internalKey(), x -> new ArrayList<>()) - .add(r); - } - - @Override - public Rule find(RuleKey ruleKey) { - return rulesByRuleKey.get(ruleKey); - } - - @Override - public Collection<Rule> findAll() { - return rulesByRepository.values().stream().flatMap(List::stream).collect(Collectors.toList()); - } - - @Override - public Collection<Rule> findByRepository(String repository) { - return rulesByRepository.getOrDefault(repository, Collections.emptyList()); - } - - @Override - public Collection<Rule> findByInternalKey(String repository, String internalKey) { - return rulesByRepositoryAndInternalKey - .getOrDefault(repository, Collections.emptyMap()) - .getOrDefault(internalKey, Collections.emptyList()); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/RulesBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/RulesBuilder.java deleted file mode 100644 index f7ebe363d09..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/RulesBuilder.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.rule.internal; - -import org.sonar.api.batch.rule.Rules; -import org.sonar.api.rule.RuleKey; - -import java.util.HashMap; -import java.util.Map; - -/** - * For unit testing and internal use only. - * - * @since 4.2 - */ - -public class RulesBuilder { - - private final Map<RuleKey, NewRule> map = new HashMap<>(); - - public NewRule add(RuleKey key) { - if (map.containsKey(key)) { - throw new IllegalStateException(String.format("Rule '%s' already exists", key)); - } - NewRule newRule = new NewRule(key); - map.put(key, newRule); - return newRule; - } - - public Rules build() { - return new DefaultRules(map.values()); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java index 8e0a70824e9..7d4536c68ce 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java @@ -22,7 +22,6 @@ package org.sonar.api.batch.sensor; import org.sonar.api.ExtensionPoint; import org.sonar.api.batch.InstantiationStrategy; import org.sonar.api.batch.ScannerSide; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.scanner.sensor.ProjectSensor; import org.sonarsource.api.sonarlint.SonarLintSide; @@ -33,7 +32,7 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * <p> * For example the Cobertura Sensor parses Cobertura report and saves the first-level of measures on files. * - * For testing purpose you can use {@link SensorContextTester} + * For testing purpose you can use SensorContextTester * @since 5.1 * @since 7.6 use {@link ProjectSensor} instead to make your Sensor run only once per analysis, and no more once per module */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java index 8f7cb5fdaf6..cc2e443bbca 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java @@ -30,7 +30,6 @@ import org.sonar.api.batch.sensor.coverage.NewCoverage; import org.sonar.api.batch.sensor.cpd.NewCpdTokens; import org.sonar.api.batch.sensor.error.NewAnalysisError; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.NewExternalIssue; @@ -48,7 +47,7 @@ import org.sonar.api.utils.Version; /** * See {@link Sensor#execute(SensorContext)} - * In order to write unit tests you can use {@link SensorContextTester} + * In order to write unit tests you can use SensorContextTester * @since 5.1 */ public interface SensorContext { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java deleted file mode 100644 index 74b238c4b63..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sensor.internal; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; -import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; -import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; -import org.sonar.api.batch.sensor.error.AnalysisError; -import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; -import org.sonar.api.batch.sensor.issue.ExternalIssue; -import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue; -import org.sonar.api.batch.sensor.measure.Measure; -import org.sonar.api.batch.sensor.rule.AdHocRule; -import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; - -import static org.sonar.api.utils.Preconditions.checkArgument; - -class InMemorySensorStorage implements SensorStorage { - - Map<String, Map<String, Measure>> measuresByComponentAndMetric = new HashMap<>(); - - Collection<Issue> allIssues = new ArrayList<>(); - Collection<ExternalIssue> allExternalIssues = new ArrayList<>(); - Collection<AdHocRule> allAdHocRules = new ArrayList<>(); - Collection<AnalysisError> allAnalysisErrors = new ArrayList<>(); - - Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>(); - Map<String, DefaultCpdTokens> cpdTokensByComponent = new HashMap<>(); - Map<String, List<DefaultCoverage>> coverageByComponent = new HashMap<>(); - Map<String, DefaultSymbolTable> symbolsPerComponent = new HashMap<>(); - Map<String, String> contextProperties = new HashMap<>(); - Map<String, DefaultSignificantCode> significantCodePerComponent = new HashMap<>(); - - @Override - public void store(Measure measure) { - // Emulate duplicate measure check - String componentKey = measure.inputComponent().key(); - String metricKey = measure.metric().key(); - if (measuresByComponentAndMetric.getOrDefault(componentKey, Collections.emptyMap()).containsKey(metricKey)) { - throw new IllegalStateException("Can not add the same measure twice"); - } - measuresByComponentAndMetric.computeIfAbsent(componentKey, x -> new HashMap<>()).put(metricKey, measure); - } - - @Override - public void store(Issue issue) { - allIssues.add(issue); - } - - @Override - public void store(DefaultAdHocRule adHocRule) { - allAdHocRules.add(adHocRule); - } - - @Override - public void store(DefaultHighlighting highlighting) { - String fileKey = highlighting.inputFile().key(); - // Emulate duplicate storage check - if (highlightingByComponent.containsKey(fileKey)) { - throw new UnsupportedOperationException("Trying to save highlighting twice for the same file is not supported: " + highlighting.inputFile()); - } - highlightingByComponent.put(fileKey, highlighting); - } - - @Override - public void store(DefaultCoverage defaultCoverage) { - String fileKey = defaultCoverage.inputFile().key(); - coverageByComponent.computeIfAbsent(fileKey, x -> new ArrayList<>()).add(defaultCoverage); - } - - @Override - public void store(DefaultCpdTokens defaultCpdTokens) { - String fileKey = defaultCpdTokens.inputFile().key(); - // Emulate duplicate storage check - if (cpdTokensByComponent.containsKey(fileKey)) { - throw new UnsupportedOperationException("Trying to save CPD tokens twice for the same file is not supported: " + defaultCpdTokens.inputFile()); - } - cpdTokensByComponent.put(fileKey, defaultCpdTokens); - } - - @Override - public void store(DefaultSymbolTable symbolTable) { - String fileKey = symbolTable.inputFile().key(); - // Emulate duplicate storage check - if (symbolsPerComponent.containsKey(fileKey)) { - throw new UnsupportedOperationException("Trying to save symbol table twice for the same file is not supported: " + symbolTable.inputFile()); - } - symbolsPerComponent.put(fileKey, symbolTable); - } - - @Override - public void store(AnalysisError analysisError) { - allAnalysisErrors.add(analysisError); - } - - @Override - public void storeProperty(String key, String value) { - checkArgument(key != null, "Key of context property must not be null"); - checkArgument(value != null, "Value of context property must not be null"); - contextProperties.put(key, value); - } - - @Override - public void store(DefaultExternalIssue issue) { - allExternalIssues.add(issue); - } - - @Override - public void store(DefaultSignificantCode significantCode) { - String fileKey = significantCode.inputFile().key(); - // Emulate duplicate storage check - if (significantCodePerComponent.containsKey(fileKey)) { - throw new UnsupportedOperationException("Trying to save significant code information twice for the same file is not supported: " + significantCode.inputFile()); - } - significantCodePerComponent.put(fileKey, significantCode); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java deleted file mode 100644 index 70f5d509131..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sensor.internal; - -import java.io.File; -import java.io.Serializable; -import java.nio.charset.Charset; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Stream; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.sonar.api.SonarQubeSide; -import org.sonar.api.SonarRuntime; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; -import org.sonar.api.batch.sensor.Sensor; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.code.NewSignificantCode; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; -import org.sonar.api.batch.sensor.coverage.NewCoverage; -import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; -import org.sonar.api.batch.sensor.cpd.NewCpdTokens; -import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; -import org.sonar.api.batch.sensor.cpd.internal.TokensLine; -import org.sonar.api.batch.sensor.error.AnalysisError; -import org.sonar.api.batch.sensor.error.NewAnalysisError; -import org.sonar.api.batch.sensor.error.internal.DefaultAnalysisError; -import org.sonar.api.batch.sensor.highlighting.NewHighlighting; -import org.sonar.api.batch.sensor.highlighting.TypeOfText; -import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; -import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule; -import org.sonar.api.batch.sensor.issue.ExternalIssue; -import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.NewExternalIssue; -import org.sonar.api.batch.sensor.issue.NewIssue; -import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue; -import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; -import org.sonar.api.batch.sensor.measure.Measure; -import org.sonar.api.batch.sensor.measure.NewMeasure; -import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; -import org.sonar.api.batch.sensor.rule.AdHocRule; -import org.sonar.api.batch.sensor.rule.NewAdHocRule; -import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule; -import org.sonar.api.batch.sensor.symbol.NewSymbolTable; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; -import org.sonar.api.config.Configuration; -import org.sonar.api.config.Settings; -import org.sonar.api.config.internal.ConfigurationBridge; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.internal.MetadataLoader; -import org.sonar.api.internal.SonarRuntimeImpl; -import org.sonar.api.measures.Metric; -import org.sonar.api.scanner.fs.InputProject; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.Version; - -import static java.util.Collections.unmodifiableMap; - -/** - * Utility class to help testing {@link Sensor}. This is not an API and method signature may evolve. - * <p> - * Usage: call {@link #create(File)} to create an "in memory" implementation of {@link SensorContext} with a filesystem initialized with provided baseDir. - * <p> - * You have to manually register inputFiles using: - * <pre> - * sensorContextTester.fileSystem().add(new DefaultInputFile("myProjectKey", "src/Foo.java") - * .setLanguage("java") - * .initMetadata("public class Foo {\n}")); - * </pre> - * <p> - * Then pass it to your {@link Sensor}. You can then query elements provided by your sensor using methods {@link #allIssues()}, ... - */ -public class SensorContextTester implements SensorContext { - - private Settings settings; - private DefaultFileSystem fs; - private ActiveRules activeRules; - private InMemorySensorStorage sensorStorage; - private DefaultInputProject project; - private DefaultInputModule module; - private SonarRuntime runtime; - private boolean cancelled; - - private SensorContextTester(Path moduleBaseDir) { - this.settings = new MapSettings(); - this.fs = new DefaultFileSystem(moduleBaseDir).setEncoding(Charset.defaultCharset()); - this.activeRules = new ActiveRulesBuilder().build(); - this.sensorStorage = new InMemorySensorStorage(); - this.project = new DefaultInputProject(ProjectDefinition.create().setKey("projectKey").setBaseDir(moduleBaseDir.toFile()).setWorkDir(moduleBaseDir.resolve(".sonar").toFile())); - this.module = new DefaultInputModule(ProjectDefinition.create().setKey("projectKey").setBaseDir(moduleBaseDir.toFile()).setWorkDir(moduleBaseDir.resolve(".sonar").toFile())); - this.runtime = SonarRuntimeImpl.forSonarQube(MetadataLoader.loadVersion(System2.INSTANCE), SonarQubeSide.SCANNER, MetadataLoader.loadEdition(System2.INSTANCE)); - } - - public static SensorContextTester create(File moduleBaseDir) { - return new SensorContextTester(moduleBaseDir.toPath()); - } - - public static SensorContextTester create(Path moduleBaseDir) { - return new SensorContextTester(moduleBaseDir); - } - - @Override - public Settings settings() { - return settings; - } - - @Override - public Configuration config() { - return new ConfigurationBridge(settings); - } - - public SensorContextTester setSettings(Settings settings) { - this.settings = settings; - return this; - } - - @Override - public DefaultFileSystem fileSystem() { - return fs; - } - - public SensorContextTester setFileSystem(DefaultFileSystem fs) { - this.fs = fs; - return this; - } - - @Override - public ActiveRules activeRules() { - return activeRules; - } - - public SensorContextTester setActiveRules(ActiveRules activeRules) { - this.activeRules = activeRules; - return this; - } - - /** - * Default value is the version of this API at compilation time. You can override it - * using {@link #setRuntime(SonarRuntime)} to test your Sensor behaviour. - */ - @Override - public Version getSonarQubeVersion() { - return runtime().getApiVersion(); - } - - /** - * @see #setRuntime(SonarRuntime) to override defaults (SonarQube scanner with version - * of this API as used at compilation time). - */ - @Override - public SonarRuntime runtime() { - return runtime; - } - - public SensorContextTester setRuntime(SonarRuntime runtime) { - this.runtime = runtime; - return this; - } - - @Override - public boolean isCancelled() { - return cancelled; - } - - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } - - @Override - public InputModule module() { - return module; - } - - @Override - public InputProject project() { - return project; - } - - @Override - public <G extends Serializable> NewMeasure<G> newMeasure() { - return new DefaultMeasure<>(sensorStorage); - } - - public Collection<Measure> measures(String componentKey) { - return sensorStorage.measuresByComponentAndMetric.getOrDefault(componentKey, Collections.emptyMap()).values(); - } - - public <G extends Serializable> Measure<G> measure(String componentKey, Metric<G> metric) { - return measure(componentKey, metric.key()); - } - - public <G extends Serializable> Measure<G> measure(String componentKey, String metricKey) { - return sensorStorage.measuresByComponentAndMetric.getOrDefault(componentKey, Collections.emptyMap()).get(metricKey); - } - - @Override - public NewIssue newIssue() { - return new DefaultIssue(project, sensorStorage); - } - - public Collection<Issue> allIssues() { - return sensorStorage.allIssues; - } - - @Override - public NewExternalIssue newExternalIssue() { - return new DefaultExternalIssue(project, sensorStorage); - } - - @Override - public NewAdHocRule newAdHocRule() { - return new DefaultAdHocRule(sensorStorage); - } - - public Collection<ExternalIssue> allExternalIssues() { - return sensorStorage.allExternalIssues; - } - - public Collection<AdHocRule> allAdHocRules() { - return sensorStorage.allAdHocRules; - } - - public Collection<AnalysisError> allAnalysisErrors() { - return sensorStorage.allAnalysisErrors; - } - - @CheckForNull - public Integer lineHits(String fileKey, int line) { - return sensorStorage.coverageByComponent.getOrDefault(fileKey, Collections.emptyList()).stream() - .map(c -> c.hitsByLine().get(line)) - .flatMap(Stream::of) - .filter(Objects::nonNull) - .reduce(null, SensorContextTester::sumOrNull); - } - - @CheckForNull - public static Integer sumOrNull(@Nullable Integer o1, @Nullable Integer o2) { - return o1 == null ? o2 : (o1 + o2); - } - - @CheckForNull - public Integer conditions(String fileKey, int line) { - return sensorStorage.coverageByComponent.getOrDefault(fileKey, Collections.emptyList()).stream() - .map(c -> c.conditionsByLine().get(line)) - .flatMap(Stream::of) - .filter(Objects::nonNull) - .reduce(null, SensorContextTester::maxOrNull); - } - - @CheckForNull - public Integer coveredConditions(String fileKey, int line) { - return sensorStorage.coverageByComponent.getOrDefault(fileKey, Collections.emptyList()).stream() - .map(c -> c.coveredConditionsByLine().get(line)) - .flatMap(Stream::of) - .filter(Objects::nonNull) - .reduce(null, SensorContextTester::maxOrNull); - } - - @CheckForNull - public TextRange significantCodeTextRange(String fileKey, int line) { - if (sensorStorage.significantCodePerComponent.containsKey(fileKey)) { - return sensorStorage.significantCodePerComponent.get(fileKey) - .significantCodePerLine() - .get(line); - } - return null; - - } - - @CheckForNull - public static Integer maxOrNull(@Nullable Integer o1, @Nullable Integer o2) { - return o1 == null ? o2 : Math.max(o1, o2); - } - - @CheckForNull - public List<TokensLine> cpdTokens(String componentKey) { - DefaultCpdTokens defaultCpdTokens = sensorStorage.cpdTokensByComponent.get(componentKey); - return defaultCpdTokens != null ? defaultCpdTokens.getTokenLines() : null; - } - - @Override - public NewHighlighting newHighlighting() { - return new DefaultHighlighting(sensorStorage); - } - - @Override - public NewCoverage newCoverage() { - return new DefaultCoverage(sensorStorage); - } - - @Override - public NewCpdTokens newCpdTokens() { - return new DefaultCpdTokens(sensorStorage); - } - - @Override - public NewSymbolTable newSymbolTable() { - return new DefaultSymbolTable(sensorStorage); - } - - @Override - public NewAnalysisError newAnalysisError() { - return new DefaultAnalysisError(sensorStorage); - } - - /** - * Return list of syntax highlighting applied for a given position in a file. The result is a list because in theory you - * can apply several styles to the same range. - * - * @param componentKey Key of the file like 'myProjectKey:src/foo.php' - * @param line Line you want to query - * @param lineOffset Offset you want to query. - * @return List of styles applied to this position or empty list if there is no highlighting at this position. - */ - public List<TypeOfText> highlightingTypeAt(String componentKey, int line, int lineOffset) { - DefaultHighlighting syntaxHighlightingData = sensorStorage.highlightingByComponent.get(componentKey); - if (syntaxHighlightingData == null) { - return Collections.emptyList(); - } - List<TypeOfText> result = new ArrayList<>(); - DefaultTextPointer location = new DefaultTextPointer(line, lineOffset); - for (SyntaxHighlightingRule sortedRule : syntaxHighlightingData.getSyntaxHighlightingRuleSet()) { - if (sortedRule.range().start().compareTo(location) <= 0 && sortedRule.range().end().compareTo(location) > 0) { - result.add(sortedRule.getTextType()); - } - } - return result; - } - - /** - * Return list of symbol references ranges for the symbol at a given position in a file. - * - * @param componentKey Key of the file like 'myProjectKey:src/foo.php' - * @param line Line you want to query - * @param lineOffset Offset you want to query. - * @return List of references for the symbol (potentially empty) or null if there is no symbol at this position. - */ - @CheckForNull - public Collection<TextRange> referencesForSymbolAt(String componentKey, int line, int lineOffset) { - DefaultSymbolTable symbolTable = sensorStorage.symbolsPerComponent.get(componentKey); - if (symbolTable == null) { - return null; - } - DefaultTextPointer location = new DefaultTextPointer(line, lineOffset); - for (Map.Entry<TextRange, Set<TextRange>> symbol : symbolTable.getReferencesBySymbol().entrySet()) { - if (symbol.getKey().start().compareTo(location) <= 0 && symbol.getKey().end().compareTo(location) > 0) { - return symbol.getValue(); - } - } - return null; - } - - @Override - public void addContextProperty(String key, String value) { - sensorStorage.storeProperty(key, value); - } - - /** - * @return an immutable map of the context properties defined with {@link SensorContext#addContextProperty(String, String)}. - * @since 6.1 - */ - public Map<String, String> getContextProperties() { - return unmodifiableMap(sensorStorage.contextProperties); - } - - @Override - public void markForPublishing(InputFile inputFile) { - DefaultInputFile file = (DefaultInputFile) inputFile; - file.setPublished(true); - } - - @Override - public NewSignificantCode newSignificantCode() { - return new DefaultSignificantCode(sensorStorage); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scanner/sensor/ProjectSensor.java b/sonar-plugin-api/src/main/java/org/sonar/api/scanner/sensor/ProjectSensor.java index 3d81fa9385b..9ea27e49f78 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/scanner/sensor/ProjectSensor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/scanner/sensor/ProjectSensor.java @@ -23,7 +23,6 @@ import org.sonar.api.ExtensionPoint; import org.sonar.api.scanner.ScannerSide; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonarsource.api.sonarlint.SonarLintSide; /** @@ -32,7 +31,7 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * <p> * For example the Cobertura Sensor parses Cobertura report and saves the first-level of measures on files. * - * For testing purpose you can use {@link SensorContextTester} + * For testing purpose you can use SensorContextTester * @since 7.6 */ @ScannerSide |