123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- /*
- * SonarQube
- * Copyright (C) 2009-2019 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.externalissue;
-
- import com.google.common.base.MoreObjects;
- import java.util.LinkedHashSet;
- import java.util.Set;
- import java.util.stream.Collectors;
- import javax.annotation.CheckForNull;
- import org.sonar.api.batch.fs.InputFile;
- import org.sonar.api.batch.fs.TextPointer;
- import org.sonar.api.batch.rule.Severity;
- import org.sonar.api.batch.sensor.SensorContext;
- import org.sonar.api.batch.sensor.issue.NewExternalIssue;
- import org.sonar.api.batch.sensor.issue.NewIssueLocation;
- import org.sonar.api.rules.RuleType;
- import org.sonar.api.utils.log.Logger;
- import org.sonar.api.utils.log.Loggers;
- import org.sonar.scanner.externalissue.ReportParser.Issue;
- import org.sonar.scanner.externalissue.ReportParser.Location;
- import org.sonar.scanner.externalissue.ReportParser.Report;
-
- public class ExternalIssueImporter {
- private static final Logger LOG = Loggers.get(ExternalIssuesImportSensor.class);
- private static final int MAX_UNKNOWN_FILE_PATHS_TO_PRINT = 5;
-
- private final SensorContext context;
- private final Report report;
- private final Set<String> unknownFiles = new LinkedHashSet<>();
- private final Set<String> knownFiles = new LinkedHashSet<>();
-
- public ExternalIssueImporter(SensorContext context, Report report) {
- this.context = context;
- this.report = report;
- }
-
- public void execute() {
- int issueCount = 0;
-
- for (Issue issue : report.issues) {
- if (importIssue(issue)) {
- issueCount++;
- }
- }
-
- LOG.info("Imported {} {} in {} {}", issueCount, pluralize("issue", issueCount), knownFiles.size(), pluralize("file", knownFiles.size()));
- int numberOfUnknownFiles = unknownFiles.size();
- if (numberOfUnknownFiles > 0) {
- LOG.info("External issues ignored for " + numberOfUnknownFiles + " unknown files, including: "
- + unknownFiles.stream().limit(MAX_UNKNOWN_FILE_PATHS_TO_PRINT).collect(Collectors.joining(", ")));
- }
- }
-
- private boolean importIssue(Issue issue) {
- NewExternalIssue externalIssue = context.newExternalIssue()
- .engineId(issue.engineId)
- .ruleId(issue.ruleId)
- .severity(Severity.valueOf(issue.severity))
- .type(RuleType.valueOf(issue.type));
-
- if (issue.effortMinutes != null) {
- externalIssue.remediationEffortMinutes(Long.valueOf(issue.effortMinutes));
- }
-
- NewIssueLocation primary = fillLocation(context, externalIssue.newLocation(), issue.primaryLocation);
- if (primary != null) {
- knownFiles.add(issue.primaryLocation.filePath);
- externalIssue.at(primary);
- if (issue.secondaryLocations != null) {
- for (Location l : issue.secondaryLocations) {
- NewIssueLocation secondary = fillLocation(context, externalIssue.newLocation(), l);
- if (secondary != null) {
- externalIssue.addLocation(secondary);
- }
- }
- }
- externalIssue.save();
- return true;
- } else {
- unknownFiles.add(issue.primaryLocation.filePath);
- return false;
- }
- }
-
- private static String pluralize(String msg, int count) {
- if (count == 1) {
- return msg;
- }
- return msg + "s";
- }
-
- @CheckForNull
- private static NewIssueLocation fillLocation(SensorContext context, NewIssueLocation newLocation, Location location) {
- InputFile file = findFile(context, location.filePath);
- if (file == null) {
- return null;
- }
- newLocation.on(file);
-
- if (location.message != null) {
- newLocation.message(location.message);
- }
-
- if (location.textRange != null) {
- if (location.textRange.startColumn != null) {
- TextPointer start = file.newPointer(location.textRange.startLine, location.textRange.startColumn);
- int endLine = MoreObjects.firstNonNull(location.textRange.endLine, location.textRange.startLine);
- int endColumn;
-
- if (location.textRange.endColumn == null) {
- // assume it's until the last character of the end line
- endColumn = file.selectLine(endLine).end().lineOffset();
- } else {
- endColumn = location.textRange.endColumn;
- }
- TextPointer end = file.newPointer(endLine, endColumn);
- newLocation.at(file.newRange(start, end));
- } else {
- newLocation.at(file.selectLine(location.textRange.startLine));
- }
- }
- return newLocation;
- }
-
- @CheckForNull
- private static InputFile findFile(SensorContext context, String filePath) {
- return context.fileSystem().inputFile(context.fileSystem().predicates().hasPath(filePath));
- }
-
- }
|