diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2024-02-08 17:35:55 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-02-09 20:02:43 +0000 |
commit | 9129a17339ffdd61b28381aa8a408923de8006d9 (patch) | |
tree | d5779d9ba8d3a371dda217ef88b0928d19aabc0f /sonar-scanner-engine/src/main/java/org/sonar | |
parent | f35c863133c22bdc7d5a63dd914e10eda1ad04dc (diff) | |
download | sonarqube-9129a17339ffdd61b28381aa8a408923de8006d9.tar.gz sonarqube-9129a17339ffdd61b28381aa8a408923de8006d9.zip |
SONAR-21575 Populate the issue filter chain after optional plugins have been loaded
Optional plugins can contribute IssueFilter, so we should not load the list of extensions too early.
Moving the IssueFilters class in the child container was not possible due to many dependencies, so the choice has been made to make it "mutable": it is instantiated early to allow injection, but the list of IssueFilter is populated later.
Diffstat (limited to 'sonar-scanner-engine/src/main/java/org/sonar')
5 files changed, 58 insertions, 20 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java index 3718dda8689..fd69f0413f5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/AbstractExtensionDictionary.java @@ -85,7 +85,7 @@ public abstract class AbstractExtensionDictionary { } } - protected <T> Collection<T> sort(Collection<T> extensions) { + protected <T> List<T> sort(Collection<T> extensions) { DirectAcyclicGraph dag = new DirectAcyclicGraph(); for (T extension : extensions) { @@ -98,9 +98,9 @@ public abstract class AbstractExtensionDictionary { } completePhaseDependencies(dag, extension); } - List<?> sortedList = dag.sort(); + List<T> sortedList = dag.sort(); - return (Collection<T>) sortedList.stream() + return sortedList.stream() .filter(extensions::contains) .toList(); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueFilterChain.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueFilterChain.java index 81073fcfef2..f60a5ed7e1a 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueFilterChain.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueFilterChain.java @@ -30,15 +30,7 @@ import org.sonar.api.scan.issue.filter.IssueFilterChain; public class DefaultIssueFilterChain implements IssueFilterChain { private final List<IssueFilter> filters; - public DefaultIssueFilterChain(IssueFilter... filters) { - this.filters = List.of(filters); - } - - public DefaultIssueFilterChain() { - this.filters = Collections.emptyList(); - } - - private DefaultIssueFilterChain(List<IssueFilter> filters) { + public DefaultIssueFilterChain(List<IssueFilter> filters) { this.filters = filters; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilterExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilterExtensionDictionary.java new file mode 100644 index 00000000000..df4550df9b3 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilterExtensionDictionary.java @@ -0,0 +1,37 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 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.scanner.issue; + +import java.util.List; +import org.sonar.api.scan.issue.filter.IssueFilter; +import org.sonar.core.platform.SpringComponentContainer; +import org.sonar.scanner.bootstrap.AbstractExtensionDictionary; + +public class IssueFilterExtensionDictionary extends AbstractExtensionDictionary { + + + public IssueFilterExtensionDictionary(SpringComponentContainer componentContainer) { + super(componentContainer); + } + + public List<IssueFilter> selectIssueFilters() { + return sort(getFilteredExtensions(IssueFilter.class, null)); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java index 0303bfe8fea..11b29853534 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java @@ -19,6 +19,7 @@ */ package org.sonar.scanner.issue; +import java.util.List; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.scan.issue.filter.FilterableIssue; @@ -32,23 +33,24 @@ import org.springframework.beans.factory.annotation.Autowired; */ @Deprecated public class IssueFilters { - private final IssueFilterChain filterChain; + private IssueFilterChain filterChain; private final DefaultInputProject project; @Autowired(required = false) - public IssueFilters(DefaultInputProject project, IssueFilter[] exclusionFilters) { - this.project = project; - this.filterChain = new DefaultIssueFilterChain(exclusionFilters); - } - - @Autowired(required = false) public IssueFilters(DefaultInputProject project) { - this(project, new IssueFilter[0]); + this.project = project; } public boolean accept(InputComponent component, ScannerReport.Issue rawIssue) { + if (filterChain == null) { + throw new IllegalStateException("Issue filters must be registered before this class can be used"); + } FilterableIssue fIssue = new DefaultFilterableIssue(project, rawIssue, component); return filterChain.accept(fIssue); } + public void registerFilters(List<IssueFilter> exclusionFilters) { + this.filterChain = new DefaultIssueFilterChain(exclusionFilters); + } + } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java index 190c9f64859..7f060c295fd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java @@ -44,6 +44,8 @@ import org.sonar.scanner.bootstrap.PostJobExtensionDictionary; import org.sonar.scanner.bootstrap.ScannerPluginRepository; import org.sonar.scanner.cpd.CpdExecutor; import org.sonar.scanner.fs.InputModuleHierarchy; +import org.sonar.scanner.issue.IssueFilterExtensionDictionary; +import org.sonar.scanner.issue.IssueFilters; import org.sonar.scanner.mediumtest.AnalysisObservers; import org.sonar.scanner.postjob.DefaultPostJobContext; import org.sonar.scanner.postjob.PostJobOptimizer; @@ -124,6 +126,9 @@ public class SpringProjectScanContainer extends SpringComponentContainer { ProjectSensorsExecutor.class, ProjectSensorOptimizer.class, + // Issue filters + IssueFilterExtensionDictionary.class, + AnalysisObservers.class, // file system @@ -144,6 +149,8 @@ public class SpringProjectScanContainer extends SpringComponentContainer { @Override protected void doAfterStart() { getParentComponentByType(ScannerMetrics.class).addPluginMetrics(getComponentsByType(Metrics.class)); + getParentComponentByType(IssueFilters.class).registerFilters(getComponentByType(IssueFilterExtensionDictionary.class).selectIssueFilters()); + getComponentByType(ProjectLock.class).tryLock(); // NOTE: ProjectBuilders executed here will have any changes they make to the ProjectReactor discarded. |