Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

RunMapper.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  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.
  10. *
  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.
  15. *
  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.
  19. */
  20. package org.sonar.scanner.externalissue.sarif;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Optional;
  24. import java.util.Set;
  25. import java.util.stream.Stream;
  26. import javax.annotation.Nullable;
  27. import org.slf4j.Logger;
  28. import org.slf4j.LoggerFactory;
  29. import org.sonar.api.batch.sensor.issue.NewExternalIssue;
  30. import org.sonar.api.batch.sensor.rule.NewAdHocRule;
  31. import org.sonar.api.scanner.ScannerSide;
  32. import org.sonar.core.sarif.Driver;
  33. import org.sonar.core.sarif.Extension;
  34. import org.sonar.core.sarif.Result;
  35. import org.sonar.core.sarif.Rule;
  36. import org.sonar.core.sarif.Run;
  37. import org.sonar.core.sarif.Tool;
  38. import static java.util.Collections.emptyList;
  39. import static java.util.stream.Collectors.toSet;
  40. import static org.sonar.api.utils.Preconditions.checkArgument;
  41. import static org.sonar.scanner.externalissue.sarif.RulesSeverityDetector.detectRulesSeverities;
  42. import static org.sonar.scanner.externalissue.sarif.RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy;
  43. @ScannerSide
  44. public class RunMapper {
  45. private static final Logger LOG = LoggerFactory.getLogger(RunMapper.class);
  46. private final ResultMapper resultMapper;
  47. private final RuleMapper ruleMapper;
  48. RunMapper(ResultMapper resultMapper, RuleMapper ruleMapper) {
  49. this.resultMapper = resultMapper;
  50. this.ruleMapper = ruleMapper;
  51. }
  52. RunMapperResult mapRun(Run run) {
  53. if (run.getResults().isEmpty()) {
  54. return new RunMapperResult();
  55. }
  56. String driverName = getToolDriverName(run);
  57. Map<String, String> ruleSeveritiesByRuleId = detectRulesSeverities(run, driverName);
  58. Map<String, String> ruleSeveritiesByRuleIdForNewCCT = detectRulesSeveritiesForNewTaxonomy(run, driverName);
  59. return new RunMapperResult()
  60. .newAdHocRules(toNewAdHocRules(run, driverName, ruleSeveritiesByRuleId, ruleSeveritiesByRuleIdForNewCCT))
  61. .newExternalIssues(toNewExternalIssues(run, driverName, ruleSeveritiesByRuleId, ruleSeveritiesByRuleIdForNewCCT));
  62. }
  63. private static String getToolDriverName(Run run) throws IllegalArgumentException {
  64. checkArgument(hasToolDriverNameDefined(run), "The run does not have a tool driver name defined.");
  65. return run.getTool().getDriver().getName();
  66. }
  67. private static boolean hasToolDriverNameDefined(Run run) {
  68. return Optional.ofNullable(run)
  69. .map(Run::getTool)
  70. .map(Tool::getDriver)
  71. .map(Driver::getName)
  72. .isPresent();
  73. }
  74. private List<NewAdHocRule> toNewAdHocRules(Run run, String driverName, Map<String, String> ruleSeveritiesByRuleId, Map<String, String> ruleSeveritiesByRuleIdForNewCCT) {
  75. Set<Rule> driverRules = run.getTool().getDriver().getRules();
  76. Set<Rule> extensionRules = hasExtensions(run.getTool())
  77. ? run.getTool().getExtensions().stream().filter(RunMapper::hasRules).flatMap(extension -> extension.getRules().stream()).collect(toSet())
  78. : Set.of();
  79. return Stream.concat(driverRules.stream(), extensionRules.stream())
  80. .distinct()
  81. .map(rule -> ruleMapper.mapRule(rule, driverName, ruleSeveritiesByRuleId.get(rule.getId()), ruleSeveritiesByRuleIdForNewCCT.get(rule.getId())))
  82. .toList();
  83. }
  84. private static boolean hasExtensions(Tool tool) {
  85. return tool.getExtensions() != null && !tool.getExtensions().isEmpty();
  86. }
  87. private static boolean hasRules(Extension extension) {
  88. return extension.getRules() != null && !extension.getRules().isEmpty();
  89. }
  90. private List<NewExternalIssue> toNewExternalIssues(Run run, String driverName, Map<String, String> ruleSeveritiesByRuleId, Map<String, String> ruleSeveritiesByRuleIdForNewCCT) {
  91. return run.getResults()
  92. .stream()
  93. .map(result -> toNewExternalIssue(driverName, ruleSeveritiesByRuleId.get(result.getRuleId()), ruleSeveritiesByRuleIdForNewCCT.get(result.getRuleId()), result))
  94. .filter(Optional::isPresent)
  95. .map(Optional::get)
  96. .toList();
  97. }
  98. private Optional<NewExternalIssue> toNewExternalIssue(String driverName, @Nullable String ruleSeverity, @Nullable String ruleSeverityForNewTaxonomy, Result result) {
  99. try {
  100. return Optional.of(resultMapper.mapResult(driverName, ruleSeverity, ruleSeverityForNewTaxonomy, result));
  101. } catch (Exception exception) {
  102. LOG.warn("Failed to import an issue raised by tool {}, error: {}", driverName, exception.getMessage());
  103. return Optional.empty();
  104. }
  105. }
  106. static class RunMapperResult {
  107. private List<NewExternalIssue> newExternalIssues;
  108. private List<NewAdHocRule> newAdHocRules;
  109. private boolean success;
  110. public RunMapperResult() {
  111. this.newExternalIssues = emptyList();
  112. this.newAdHocRules = emptyList();
  113. this.success = true;
  114. }
  115. public RunMapperResult newExternalIssues(List<NewExternalIssue> newExternalIssues) {
  116. this.newExternalIssues = newExternalIssues;
  117. return this;
  118. }
  119. public RunMapperResult newAdHocRules(List<NewAdHocRule> newAdHocRules) {
  120. this.newAdHocRules = newAdHocRules;
  121. return this;
  122. }
  123. public RunMapperResult success(boolean success) {
  124. this.success = success;
  125. return this;
  126. }
  127. public List<NewExternalIssue> getNewExternalIssues() {
  128. return newExternalIssues;
  129. }
  130. public List<NewAdHocRule> getNewAdHocRules() {
  131. return newAdHocRules;
  132. }
  133. public boolean isSuccess() {
  134. return success;
  135. }
  136. }
  137. }