diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2018-11-13 15:38:22 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-01-16 09:42:59 +0100 |
commit | 4a659a05cf4ff177629e9cb78aa6a0721810ff61 (patch) | |
tree | 6f9a066e40db44cff8808f3d58285d2e7600fd8e /sonar-plugin-api | |
parent | 8bbac3c6e0023978a59814cd1e77fd0efcb6c265 (diff) | |
download | sonarqube-4a659a05cf4ff177629e9cb78aa6a0721810ff61.tar.gz sonarqube-4a659a05cf4ff177629e9cb78aa6a0721810ff61.zip |
SONAR-11465 NoSonarFilter moved to project level
Diffstat (limited to 'sonar-plugin-api')
3 files changed, 31 insertions, 98 deletions
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 278d288d185..f7d640a4dbb 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 @@ -30,6 +30,8 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import java.util.function.Consumer; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -56,6 +58,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile private Metadata metadata; private boolean published; private boolean excludedForCoverage; + private final Set<Integer> noSonarLines = new HashSet<>(); public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator) { this(indexedFile, metadataGenerator, null); @@ -82,7 +85,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile public InputStream inputStream() throws IOException { return contents != null ? new ByteArrayInputStream(contents.getBytes(charset())) : new BOMInputStream(Files.newInputStream(path()), - ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE); + ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE); } @Override @@ -242,7 +245,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile checkMetadata(); Preconditions.checkState(metadata.originalLineEndOffsets() != null, "InputFile is not properly initialized."); Preconditions.checkState(metadata.originalLineEndOffsets().length == metadata.lines(), - "InputFile is not properly initialized. 'originalLineEndOffsets' property length should be equal to 'lines'"); + "InputFile is not properly initialized. 'originalLineEndOffsets' property length should be equal to 'lines'"); return metadata.originalLineEndOffsets(); } @@ -299,7 +302,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile int line = findLine(globalOffset); int startLineOffset = originalLineStartOffsets()[line - 1]; // In case the global offset is between \r and \n, move the pointer to a valid location - return new DefaultTextPointer(line, Math.min(globalOffset, originalLineEndOffsets()[line -1]) - startLineOffset); + return new DefaultTextPointer(line, Math.min(globalOffset, originalLineEndOffsets()[line - 1]) - startLineOffset); } public DefaultInputFile setStatus(Status status) { @@ -369,4 +372,12 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile return indexedFile.uri(); } + public void noSonarAt(Set<Integer> noSonarLines) { + this.noSonarLines.addAll(noSonarLines); + } + + public boolean hasNoSonarAt(int line) { + return this.noSonarLines.contains(line); + } + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java index 947b6d28c18..a58e5f02e4f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java @@ -19,63 +19,34 @@ */ package org.sonar.api.issue; -import java.util.HashMap; -import java.util.Map; import java.util.Set; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.ScannerSide; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.scan.issue.filter.FilterableIssue; -import org.sonar.api.scan.issue.filter.IssueFilter; -import org.sonar.api.scan.issue.filter.IssueFilterChain; +import org.sonar.api.scanner.ScannerSide; /** * Issue filter used to ignore issues created on lines commented with the tag "NOSONAR". * <br> - * Plugins, via {@link ScannerSide}s, must feed this filter by registering the + * Plugins, via {@link org.sonar.api.batch.sensor.Sensor}s, must feed this filter by registering the * lines that contain "NOSONAR". Note that filters are disabled for the issues reported by * end-users from UI or web services. * * @since 3.6 */ -public class NoSonarFilter implements IssueFilter { - - private final Map<String, Set<Integer>> noSonarLinesByResource = new HashMap<>(); - - /** - * @deprecated since 5.0 use {@link #noSonarInFile(InputFile, Set)} - */ - @Deprecated - public NoSonarFilter addComponent(String componentKey, Set<Integer> noSonarLines) { - noSonarLinesByResource.put(componentKey, noSonarLines); - return this; - } +@ScannerSide +public class NoSonarFilter { /** * Register lines in a file that contains the NOSONAR flag. + * * @param inputFile * @param noSonarLines Line number starts at 1 in a file * @since 5.0 + * @since 7.6 the method can be called multiple times by different sensors, and NOSONAR lines are merged */ public NoSonarFilter noSonarInFile(InputFile inputFile, Set<Integer> noSonarLines) { - noSonarLinesByResource.put(((DefaultInputFile) inputFile).key(), noSonarLines); + ((DefaultInputFile) inputFile).noSonarAt(noSonarLines); return this; } - @Override - public boolean accept(FilterableIssue issue, IssueFilterChain chain) { - boolean accepted = true; - if (issue.line() != null) { - Set<Integer> noSonarLines = noSonarLinesByResource.get(issue.componentKey()); - accepted = noSonarLines == null || !noSonarLines.contains(issue.line()); - if (!accepted && StringUtils.containsIgnoreCase(issue.ruleKey().rule(), "nosonar")) { - accepted = true; - } - } - if (accepted) { - accepted = chain.accept(issue); - } - return accepted; - } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java index 3e4435f489b..0665df11878 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java @@ -19,72 +19,23 @@ */ package org.sonar.api.issue; -import org.sonar.api.scan.issue.filter.FilterableIssue; - -import com.google.common.collect.ImmutableSet; -import org.junit.Before; +import java.util.Arrays; +import java.util.HashSet; import org.junit.Test; -import org.sonar.api.scan.issue.filter.IssueFilterChain; -import org.sonar.api.rule.RuleKey; - -import java.util.Set; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class NoSonarFilterTest { - NoSonarFilter filter = new NoSonarFilter(); - IssueFilterChain chain = mock(IssueFilterChain.class); - - @Before - public void setupChain() { - when(chain.accept(isA(FilterableIssue.class))).thenReturn(true); - } - - @Test - public void should_ignore_lines_commented_with_nosonar() { - FilterableIssue issue = mock(FilterableIssue.class); - when(issue.componentKey()).thenReturn("struts:org.apache.Action"); - when(issue.ruleKey()).thenReturn(RuleKey.of("squid", "AvoidCycles")); - - Set<Integer> noSonarLines = ImmutableSet.of(31, 55); - filter.addComponent("struts:org.apache.Action", noSonarLines); - - // issue on file - when(issue.line()).thenReturn(null); - assertThat(filter.accept(issue, chain)).isTrue(); - - // issue on lines - when(issue.line()).thenReturn(31); - assertThat(filter.accept(issue, chain)).isFalse(); - - when(issue.line()).thenReturn(222); - assertThat(filter.accept(issue, chain)).isTrue(); - - verify(chain, times(2)).accept(issue); - } - @Test - public void should_accept_issues_on_no_sonar_rules() { - // The "No Sonar" rule logs violations on the lines that are flagged with "NOSONAR" !! - FilterableIssue issue = mock(FilterableIssue.class); - when(issue.componentKey()).thenReturn("struts:org.apache.Action"); - when(issue.ruleKey()).thenReturn(RuleKey.of("squid", "NoSonarCheck")); - - Set<Integer> noSonarLines = ImmutableSet.of(31, 55); - filter.addComponent("struts:org.apache.Action", noSonarLines); - - when(issue.line()).thenReturn(31); - assertThat(filter.accept(issue, chain)).isTrue(); - - when(issue.line()).thenReturn(222); - assertThat(filter.accept(issue, chain)).isTrue(); + public void should_store_nosonar_lines_on_inputfile() { + DefaultInputFile f = TestInputFileBuilder.create("module1", "myfile.java").build(); + new NoSonarFilter().noSonarInFile(f, new HashSet<>(Arrays.asList(1,4))); - verify(chain, times(2)).accept(issue); + assertThat(f.hasNoSonarAt(1)).isTrue(); + assertThat(f.hasNoSonarAt(2)).isFalse(); + assertThat(f.hasNoSonarAt(4)).isTrue(); } } |