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