3 * Copyright (C) 2009-2024 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.ce.task.projectanalysis.batch;
22 import com.google.common.base.Preconditions;
23 import java.io.ByteArrayInputStream;
24 import java.io.InputStream;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.List;
31 import java.util.Objects;
32 import java.util.Optional;
33 import javax.annotation.CheckForNull;
34 import javax.annotation.Nullable;
35 import org.junit.jupiter.api.extension.AfterEachCallback;
36 import org.junit.jupiter.api.extension.ExtensionContext;
37 import org.junit.rules.TestRule;
38 import org.junit.runner.Description;
39 import org.junit.runners.model.Statement;
40 import org.sonar.core.util.CloseableIterator;
41 import org.sonar.scanner.protocol.output.ScannerReport;
42 import org.sonar.scanner.protocol.output.ScannerReport.LineSgnificantCode;
44 public class BatchReportReaderRule implements TestRule, BatchReportReader, AfterEachCallback {
45 private ScannerReport.Metadata metadata;
46 private List<String> scannerLogs;
47 private List<ScannerReport.ActiveRule> activeRules = new ArrayList<>();
48 private List<ScannerReport.ContextProperty> contextProperties = new ArrayList<>();
49 private Map<Integer, List<ScannerReport.Measure>> measures = new HashMap<>();
50 private Map<Integer, ScannerReport.Changesets> changesets = new HashMap<>();
51 private Map<Integer, ScannerReport.Component> components = new HashMap<>();
52 private Map<Integer, List<ScannerReport.Issue>> issues = new HashMap<>();
53 private Map<Integer, List<ScannerReport.ExternalIssue>> externalIssues = new HashMap<>();
54 private List<ScannerReport.AdHocRule> adHocRules = new ArrayList<>();
55 private Map<Integer, List<ScannerReport.Duplication>> duplications = new HashMap<>();
56 private Map<Integer, List<ScannerReport.CpdTextBlock>> duplicationBlocks = new HashMap<>();
57 private Map<Integer, List<ScannerReport.Symbol>> symbols = new HashMap<>();
58 private Map<Integer, List<ScannerReport.SyntaxHighlightingRule>> syntaxHighlightings = new HashMap<>();
59 private Map<Integer, List<ScannerReport.LineCoverage>> coverages = new HashMap<>();
60 private Map<Integer, List<String>> fileSources = new HashMap<>();
61 private Map<Integer, List<ScannerReport.LineSgnificantCode>> significantCode = new HashMap<>();
62 private Map<Integer, ScannerReport.ChangedLines> changedLines = new HashMap<>();
63 private List<ScannerReport.AnalysisWarning> analysisWarnings = Collections.emptyList();
64 private byte[] analysisCache;
65 private List<ScannerReport.Cve> cves = new ArrayList<>();
68 public Statement apply(final Statement statement, Description description) {
69 return new Statement() {
71 public void evaluate() throws Throwable {
81 private void clear() {
83 this.scannerLogs = null;
84 this.measures.clear();
85 this.changesets.clear();
86 this.components.clear();
88 this.duplications.clear();
89 this.duplicationBlocks.clear();
91 this.syntaxHighlightings.clear();
92 this.coverages.clear();
93 this.fileSources.clear();
94 this.significantCode.clear();
98 public CloseableIterator<ScannerReport.ContextProperty> readContextProperties() {
99 return CloseableIterator.from(contextProperties.iterator());
102 public BatchReportReaderRule putContextProperties(List<ScannerReport.ContextProperty> contextProperties) {
103 this.contextProperties = Objects.requireNonNull(contextProperties);
108 public ScannerReport.Metadata readMetadata() {
109 if (metadata == null) {
110 throw new IllegalStateException("Metadata is missing");
117 public InputStream getAnalysisCache() {
118 if (analysisCache == null) {
121 return new ByteArrayInputStream(analysisCache);
124 public void setAnalysisCache(byte[] cache) {
125 this.analysisCache = cache;
128 public BatchReportReaderRule setMetadata(ScannerReport.Metadata metadata) {
129 this.metadata = metadata;
134 public CloseableIterator<String> readScannerLogs() {
135 if (scannerLogs == null) {
136 throw new IllegalStateException("Scanner logs are missing");
138 return CloseableIterator.from(scannerLogs.iterator());
141 public BatchReportReaderRule setScannerLogs(@Nullable List<String> logs) {
142 this.scannerLogs = logs;
147 public CloseableIterator<ScannerReport.ActiveRule> readActiveRules() {
148 if (activeRules == null) {
149 throw new IllegalStateException("Active rules are not set");
151 return CloseableIterator.from(activeRules.iterator());
154 public BatchReportReaderRule putActiveRules(List<ScannerReport.ActiveRule> activeRules) {
155 this.activeRules = activeRules;
160 public CloseableIterator<ScannerReport.Measure> readComponentMeasures(int componentRef) {
161 return closeableIterator(this.measures.get(componentRef));
164 public BatchReportReaderRule putMeasures(int componentRef, List<ScannerReport.Measure> measures) {
165 this.measures.put(componentRef, measures);
171 public ScannerReport.Changesets readChangesets(int componentRef) {
172 return changesets.get(componentRef);
175 public BatchReportReaderRule putChangesets(ScannerReport.Changesets changesets) {
176 this.changesets.put(changesets.getComponentRef(), changesets);
181 public ScannerReport.Component readComponent(int componentRef) {
182 return components.get(componentRef);
185 public BatchReportReaderRule putComponent(ScannerReport.Component component) {
186 this.components.put(component.getRef(), component);
191 public CloseableIterator<ScannerReport.Issue> readComponentIssues(int componentRef) {
192 return closeableIterator(issues.get(componentRef));
196 public CloseableIterator<ScannerReport.ExternalIssue> readComponentExternalIssues(int componentRef) {
197 return closeableIterator(externalIssues.get(componentRef));
201 public CloseableIterator<ScannerReport.AdHocRule> readAdHocRules() {
202 return closeableIterator(adHocRules);
205 public BatchReportReaderRule putAdHocRules(List<ScannerReport.AdHocRule> adHocRules) {
206 this.adHocRules = adHocRules;
210 public BatchReportReaderRule putIssues(int componentRef, List<ScannerReport.Issue> issues) {
211 this.issues.put(componentRef, issues);
215 public BatchReportReaderRule putExternalIssues(int componentRef, List<ScannerReport.ExternalIssue> externalIssues) {
216 this.externalIssues.put(componentRef, externalIssues);
221 public CloseableIterator<ScannerReport.Duplication> readComponentDuplications(int componentRef) {
222 return closeableIterator(this.duplications.get(componentRef));
225 public BatchReportReaderRule putDuplications(int componentRef, ScannerReport.Duplication... duplications) {
226 this.duplications.put(componentRef, Arrays.asList(duplications));
231 public CloseableIterator<ScannerReport.CpdTextBlock> readCpdTextBlocks(int componentRef) {
232 return closeableIterator(this.duplicationBlocks.get(componentRef));
235 public BatchReportReaderRule putDuplicationBlocks(int componentRef, List<ScannerReport.CpdTextBlock> duplicationBlocks) {
236 this.duplicationBlocks.put(componentRef, duplicationBlocks);
241 public CloseableIterator<ScannerReport.Symbol> readComponentSymbols(int componentRef) {
242 return closeableIterator(this.symbols.get(componentRef));
245 private static <T> CloseableIterator<T> closeableIterator(@Nullable List<T> list) {
246 return list == null ? CloseableIterator.emptyCloseableIterator() : CloseableIterator.from(list.iterator());
249 public BatchReportReaderRule putSymbols(int componentRef, List<ScannerReport.Symbol> symbols) {
250 this.symbols.put(componentRef, symbols);
254 public BatchReportReaderRule putSignificantCode(int fileRef, List<ScannerReport.LineSgnificantCode> significantCode) {
255 this.significantCode.put(fileRef, significantCode);
260 public Optional<CloseableIterator<LineSgnificantCode>> readComponentSignificantCode(int fileRef) {
261 List<LineSgnificantCode> list = significantCode.get(fileRef);
262 return list == null ? Optional.empty() : Optional.of(CloseableIterator.from(list.iterator()));
265 public BatchReportReaderRule putChangedLines(int fileRef, ScannerReport.ChangedLines fileChangedLines) {
266 changedLines.put(fileRef, fileChangedLines);
271 public Optional<ScannerReport.ChangedLines> readComponentChangedLines(int fileRef) {
272 return Optional.ofNullable(changedLines.get(fileRef));
276 public CloseableIterator<ScannerReport.AnalysisWarning> readAnalysisWarnings() {
277 return closeableIterator(analysisWarnings);
280 public BatchReportReaderRule setAnalysisWarnings(List<ScannerReport.AnalysisWarning> analysisWarnings) {
281 this.analysisWarnings = new ArrayList<>(analysisWarnings);
286 public CloseableIterator<ScannerReport.SyntaxHighlightingRule> readComponentSyntaxHighlighting(int fileRef) {
287 return closeableIterator(this.syntaxHighlightings.get(fileRef));
290 public BatchReportReaderRule putSyntaxHighlighting(int fileRef, List<ScannerReport.SyntaxHighlightingRule> syntaxHighlightings) {
291 this.syntaxHighlightings.put(fileRef, syntaxHighlightings);
296 public CloseableIterator<ScannerReport.LineCoverage> readComponentCoverage(int fileRef) {
297 return closeableIterator(this.coverages.get(fileRef));
300 public BatchReportReaderRule putCoverage(int fileRef, List<ScannerReport.LineCoverage> coverages) {
301 this.coverages.put(fileRef, coverages);
306 public Optional<CloseableIterator<String>> readFileSource(int fileRef) {
307 List<String> lines = fileSources.get(fileRef);
309 return Optional.empty();
312 return Optional.of(CloseableIterator.from(lines.iterator()));
315 public BatchReportReaderRule putFileSourceLines(int fileRef, @Nullable String... lines) {
316 Preconditions.checkNotNull(lines);
317 this.fileSources.put(fileRef, Arrays.asList(lines));
321 public BatchReportReaderRule putFileSourceLines(int fileRef, List<String> lines) {
322 this.fileSources.put(fileRef, lines);
327 public void afterEach(ExtensionContext context) {
332 public CloseableIterator<ScannerReport.Cve> readCves() {
333 return CloseableIterator.from(cves.iterator());
336 public BatchReportReaderRule putCves(List<ScannerReport.Cve> cves) {