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;
67 public Statement apply(final Statement statement, Description description) {
68 return new Statement() {
70 public void evaluate() throws Throwable {
80 private void clear() {
82 this.scannerLogs = null;
83 this.measures.clear();
84 this.changesets.clear();
85 this.components.clear();
87 this.duplications.clear();
88 this.duplicationBlocks.clear();
90 this.syntaxHighlightings.clear();
91 this.coverages.clear();
92 this.fileSources.clear();
93 this.significantCode.clear();
97 public CloseableIterator<ScannerReport.ContextProperty> readContextProperties() {
98 return CloseableIterator.from(contextProperties.iterator());
101 public BatchReportReaderRule putContextProperties(List<ScannerReport.ContextProperty> contextProperties) {
102 this.contextProperties = Objects.requireNonNull(contextProperties);
107 public ScannerReport.Metadata readMetadata() {
108 if (metadata == null) {
109 throw new IllegalStateException("Metadata is missing");
116 public InputStream getAnalysisCache() {
117 if (analysisCache == null) {
120 return new ByteArrayInputStream(analysisCache);
123 public void setAnalysisCache(byte[] cache) {
124 this.analysisCache = cache;
127 public BatchReportReaderRule setMetadata(ScannerReport.Metadata metadata) {
128 this.metadata = metadata;
133 public CloseableIterator<String> readScannerLogs() {
134 if (scannerLogs == null) {
135 throw new IllegalStateException("Scanner logs are missing");
137 return CloseableIterator.from(scannerLogs.iterator());
140 public BatchReportReaderRule setScannerLogs(@Nullable List<String> logs) {
141 this.scannerLogs = logs;
146 public CloseableIterator<ScannerReport.ActiveRule> readActiveRules() {
147 if (activeRules == null) {
148 throw new IllegalStateException("Active rules are not set");
150 return CloseableIterator.from(activeRules.iterator());
153 public BatchReportReaderRule putActiveRules(List<ScannerReport.ActiveRule> activeRules) {
154 this.activeRules = activeRules;
159 public CloseableIterator<ScannerReport.Measure> readComponentMeasures(int componentRef) {
160 return closeableIterator(this.measures.get(componentRef));
163 public BatchReportReaderRule putMeasures(int componentRef, List<ScannerReport.Measure> measures) {
164 this.measures.put(componentRef, measures);
170 public ScannerReport.Changesets readChangesets(int componentRef) {
171 return changesets.get(componentRef);
174 public BatchReportReaderRule putChangesets(ScannerReport.Changesets changesets) {
175 this.changesets.put(changesets.getComponentRef(), changesets);
180 public ScannerReport.Component readComponent(int componentRef) {
181 return components.get(componentRef);
184 public BatchReportReaderRule putComponent(ScannerReport.Component component) {
185 this.components.put(component.getRef(), component);
190 public CloseableIterator<ScannerReport.Issue> readComponentIssues(int componentRef) {
191 return closeableIterator(issues.get(componentRef));
195 public CloseableIterator<ScannerReport.ExternalIssue> readComponentExternalIssues(int componentRef) {
196 return closeableIterator(externalIssues.get(componentRef));
200 public CloseableIterator<ScannerReport.AdHocRule> readAdHocRules() {
201 return closeableIterator(adHocRules);
204 public BatchReportReaderRule putAdHocRules(List<ScannerReport.AdHocRule> adHocRules) {
205 this.adHocRules = adHocRules;
209 public BatchReportReaderRule putIssues(int componentRef, List<ScannerReport.Issue> issues) {
210 this.issues.put(componentRef, issues);
214 public BatchReportReaderRule putExternalIssues(int componentRef, List<ScannerReport.ExternalIssue> externalIssues) {
215 this.externalIssues.put(componentRef, externalIssues);
220 public CloseableIterator<ScannerReport.Duplication> readComponentDuplications(int componentRef) {
221 return closeableIterator(this.duplications.get(componentRef));
224 public BatchReportReaderRule putDuplications(int componentRef, ScannerReport.Duplication... duplications) {
225 this.duplications.put(componentRef, Arrays.asList(duplications));
230 public CloseableIterator<ScannerReport.CpdTextBlock> readCpdTextBlocks(int componentRef) {
231 return closeableIterator(this.duplicationBlocks.get(componentRef));
234 public BatchReportReaderRule putDuplicationBlocks(int componentRef, List<ScannerReport.CpdTextBlock> duplicationBlocks) {
235 this.duplicationBlocks.put(componentRef, duplicationBlocks);
240 public CloseableIterator<ScannerReport.Symbol> readComponentSymbols(int componentRef) {
241 return closeableIterator(this.symbols.get(componentRef));
244 private static <T> CloseableIterator<T> closeableIterator(@Nullable List<T> list) {
245 return list == null ? CloseableIterator.emptyCloseableIterator() : CloseableIterator.from(list.iterator());
248 public BatchReportReaderRule putSymbols(int componentRef, List<ScannerReport.Symbol> symbols) {
249 this.symbols.put(componentRef, symbols);
253 public BatchReportReaderRule putSignificantCode(int fileRef, List<ScannerReport.LineSgnificantCode> significantCode) {
254 this.significantCode.put(fileRef, significantCode);
259 public Optional<CloseableIterator<LineSgnificantCode>> readComponentSignificantCode(int fileRef) {
260 List<LineSgnificantCode> list = significantCode.get(fileRef);
261 return list == null ? Optional.empty() : Optional.of(CloseableIterator.from(list.iterator()));
264 public BatchReportReaderRule putChangedLines(int fileRef, ScannerReport.ChangedLines fileChangedLines) {
265 changedLines.put(fileRef, fileChangedLines);
270 public Optional<ScannerReport.ChangedLines> readComponentChangedLines(int fileRef) {
271 return Optional.ofNullable(changedLines.get(fileRef));
275 public CloseableIterator<ScannerReport.AnalysisWarning> readAnalysisWarnings() {
276 return closeableIterator(analysisWarnings);
279 public BatchReportReaderRule setAnalysisWarnings(List<ScannerReport.AnalysisWarning> analysisWarnings) {
280 this.analysisWarnings = new ArrayList<>(analysisWarnings);
285 public CloseableIterator<ScannerReport.SyntaxHighlightingRule> readComponentSyntaxHighlighting(int fileRef) {
286 return closeableIterator(this.syntaxHighlightings.get(fileRef));
289 public BatchReportReaderRule putSyntaxHighlighting(int fileRef, List<ScannerReport.SyntaxHighlightingRule> syntaxHighlightings) {
290 this.syntaxHighlightings.put(fileRef, syntaxHighlightings);
295 public CloseableIterator<ScannerReport.LineCoverage> readComponentCoverage(int fileRef) {
296 return closeableIterator(this.coverages.get(fileRef));
299 public BatchReportReaderRule putCoverage(int fileRef, List<ScannerReport.LineCoverage> coverages) {
300 this.coverages.put(fileRef, coverages);
305 public Optional<CloseableIterator<String>> readFileSource(int fileRef) {
306 List<String> lines = fileSources.get(fileRef);
308 return Optional.empty();
311 return Optional.of(CloseableIterator.from(lines.iterator()));
314 public BatchReportReaderRule putFileSourceLines(int fileRef, @Nullable String... lines) {
315 Preconditions.checkNotNull(lines);
316 this.fileSources.put(fileRef, Arrays.asList(lines));
320 public BatchReportReaderRule putFileSourceLines(int fileRef, List<String> lines) {
321 this.fileSources.put(fileRef, lines);
326 public void afterEach(ExtensionContext context) {