org.sonar.scanner.mediumtest.AnalysisResult Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sonar-scanner-engine Show documentation
Show all versions of sonar-scanner-engine Show documentation
Open source platform for continuous inspection of code quality
/*
* SonarQube
* Copyright (C) 2009-2023 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.mediumtest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.scanner.fs.InputProject;
import org.sonar.core.util.CloseableIterator;
import org.sonar.scanner.protocol.output.FileStructure;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Component;
import org.sonar.scanner.protocol.output.ScannerReport.Symbol;
import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.report.ScannerReportUtils;
import org.sonar.scanner.scan.SpringProjectScanContainer;
import org.sonar.scanner.scan.filesystem.InputComponentStore;
public class AnalysisResult implements AnalysisObserver {
private static final Logger LOG = LoggerFactory.getLogger(AnalysisResult.class);
private Map inputFilesByKeys = new HashMap<>();
private InputProject project;
private ScannerReportReader reader;
@Override
public void analysisCompleted(SpringProjectScanContainer container) {
LOG.info("Store analysis results in memory for later assertions in medium test");
FileStructure fileStructure = container.getComponentByType(FileStructure.class);
reader = new ScannerReportReader(fileStructure);
project = container.getComponentByType(InputProject.class);
storeFs(container);
}
public ScannerReportReader getReportReader() {
return reader;
}
private void storeFs(SpringProjectScanContainer container) {
InputComponentStore inputFileCache = container.getComponentByType(InputComponentStore.class);
for (InputFile inputPath : inputFileCache.inputFiles()) {
inputFilesByKeys.put(((DefaultInputFile) inputPath).getProjectRelativePath(), inputPath);
}
}
public Component getReportComponent(InputComponent inputComponent) {
return getReportReader().readComponent(((DefaultInputComponent) inputComponent).scannerId());
}
public Component getReportComponent(int scannerId) {
return getReportReader().readComponent(scannerId);
}
public List issuesFor(InputComponent inputComponent) {
return issuesFor(((DefaultInputComponent) inputComponent).scannerId());
}
public List externalIssuesFor(InputComponent inputComponent) {
return externalIssuesFor(((DefaultInputComponent) inputComponent).scannerId());
}
public List issuesFor(Component reportComponent) {
int ref = reportComponent.getRef();
return issuesFor(ref);
}
private List issuesFor(int ref) {
List result = new ArrayList<>();
try (CloseableIterator it = reader.readComponentIssues(ref)) {
while (it.hasNext()) {
result.add(it.next());
}
}
return result;
}
private List externalIssuesFor(int ref) {
List result = new ArrayList<>();
try (CloseableIterator it = reader.readComponentExternalIssues(ref)) {
while (it.hasNext()) {
result.add(it.next());
}
}
return result;
}
public InputProject project() {
return project;
}
public Collection inputFiles() {
return inputFilesByKeys.values();
}
@CheckForNull
public InputFile inputFile(String relativePath) {
return inputFilesByKeys.get(relativePath);
}
public Map> allMeasures() {
Map> result = new HashMap<>();
List projectMeasures = new ArrayList<>();
try (CloseableIterator it = reader.readComponentMeasures(((DefaultInputComponent) project).scannerId())) {
while (it.hasNext()) {
projectMeasures.add(it.next());
}
}
result.put(project.key(), projectMeasures);
for (InputFile inputFile : inputFilesByKeys.values()) {
List measures = new ArrayList<>();
try (CloseableIterator it = reader.readComponentMeasures(((DefaultInputComponent) inputFile).scannerId())) {
while (it.hasNext()) {
measures.add(it.next());
}
}
result.put(inputFile.key(), measures);
}
return result;
}
/**
* Get highlighting types at a given position in an inputfile
*
* @param lineOffset 0-based offset in file
*/
public List highlightingTypeFor(InputFile file, int line, int lineOffset) {
int ref = ((DefaultInputComponent) file).scannerId();
if (!reader.hasSyntaxHighlighting(ref)) {
return Collections.emptyList();
}
TextPointer pointer = file.newPointer(line, lineOffset);
List result = new ArrayList<>();
try (CloseableIterator it = reader.readComponentSyntaxHighlighting(ref)) {
while (it.hasNext()) {
ScannerReport.SyntaxHighlightingRule rule = it.next();
TextRange ruleRange = toRange(file, rule.getRange());
if (ruleRange.start().compareTo(pointer) <= 0 && ruleRange.end().compareTo(pointer) > 0) {
result.add(ScannerReportUtils.toBatchType(rule.getType()));
}
}
} catch (Exception e) {
throw new IllegalStateException("Can't read syntax highlighting for " + file, e);
}
return result;
}
private static TextRange toRange(InputFile file, ScannerReport.TextRange reportRange) {
return file.newRange(file.newPointer(reportRange.getStartLine(), reportRange.getStartOffset()), file.newPointer(reportRange.getEndLine(), reportRange.getEndOffset()));
}
/**
* Get list of all start positions of a symbol in an inputfile
*
* @param symbolStartLine 0-based start offset for the symbol in file
* @param symbolStartLineOffset 0-based end offset for the symbol in file
*/
@CheckForNull
public List symbolReferencesFor(InputFile file, int symbolStartLine, int symbolStartLineOffset) {
int ref = ((DefaultInputComponent) file).scannerId();
try (CloseableIterator symbols = getReportReader().readComponentSymbols(ref)) {
while (symbols.hasNext()) {
Symbol symbol = symbols.next();
if (symbol.getDeclaration().getStartLine() == symbolStartLine && symbol.getDeclaration().getStartOffset() == symbolStartLineOffset) {
return symbol.getReferenceList();
}
}
}
return Collections.emptyList();
}
public List duplicationsFor(InputFile file) {
List result = new ArrayList<>();
int ref = ((DefaultInputComponent) file).scannerId();
try (CloseableIterator it = getReportReader().readComponentDuplications(ref)) {
while (it.hasNext()) {
result.add(it.next());
}
} catch (Exception e) {
throw new IllegalStateException(e);
}
return result;
}
public List duplicationBlocksFor(InputFile file) {
List result = new ArrayList<>();
int ref = ((DefaultInputComponent) file).scannerId();
try (CloseableIterator it = getReportReader().readCpdTextBlocks(ref)) {
while (it.hasNext()) {
result.add(it.next());
}
} catch (Exception e) {
throw new IllegalStateException(e);
}
return result;
}
@CheckForNull
public ScannerReport.LineCoverage coverageFor(InputFile file, int line) {
int ref = ((DefaultInputComponent) file).scannerId();
try (CloseableIterator it = getReportReader().readComponentCoverage(ref)) {
while (it.hasNext()) {
ScannerReport.LineCoverage coverage = it.next();
if (coverage.getLine() == line) {
return coverage;
}
}
} catch (Exception e) {
throw new IllegalStateException(e);
}
return null;
}
public List adHocRules() {
List result = new ArrayList<>();
try (CloseableIterator it = getReportReader().readAdHocRules()) {
while (it.hasNext()) {
result.add(it.next());
}
} catch (Exception e) {
throw new IllegalStateException(e);
}
return result;
}
}