]> source.dussan.org Git - sonarqube.git/blob
42c23791290388a330d3ee0b01d10af752909106
[sonarqube.git] /
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.server.rule;
21
22 import java.util.Optional;
23 import java.util.Set;
24 import java.util.stream.Collectors;
25 import org.elasticsearch.common.util.set.Sets;
26 import org.jetbrains.annotations.Nullable;
27 import org.sonar.api.server.rule.Context;
28 import org.sonar.api.server.rule.RuleDescriptionSection;
29 import org.sonar.api.server.rule.RulesDefinition;
30 import org.sonar.core.util.UuidFactory;
31 import org.sonar.db.rule.RuleDescriptionSectionContextDto;
32 import org.sonar.db.rule.RuleDescriptionSectionDto;
33
34 import static org.sonar.api.rules.RuleType.*;
35
36 public class AdvancedRuleDescriptionSectionsGenerator implements RuleDescriptionSectionsGenerator {
37   private final UuidFactory uuidFactory;
38   private final LegacyIssueRuleDescriptionSectionsGenerator legacyIssueRuleDescriptionSectionsGenerator;
39
40   public AdvancedRuleDescriptionSectionsGenerator(UuidFactory uuidFactory, LegacyIssueRuleDescriptionSectionsGenerator legacyIssueRuleDescriptionSectionsGenerator) {
41     this.uuidFactory = uuidFactory;
42     this.legacyIssueRuleDescriptionSectionsGenerator = legacyIssueRuleDescriptionSectionsGenerator;
43   }
44
45   @Override
46   public boolean isGeneratorForRule(RulesDefinition.Rule rule) {
47     return !rule.ruleDescriptionSections().isEmpty() && skipHotspotRulesForSonar16635(rule);
48   }
49
50   private static boolean skipHotspotRulesForSonar16635(RulesDefinition.Rule rule) {
51     return !SECURITY_HOTSPOT.equals(rule.type());
52   }
53
54   @Override
55   public Set<RuleDescriptionSectionDto> generateSections(RulesDefinition.Rule rule) {
56     Set<RuleDescriptionSectionDto> advancedSections = rule.ruleDescriptionSections().stream()
57       .map(this::toRuleDescriptionSectionDto)
58       .collect(Collectors.toSet());
59     return addLegacySectionToAdvancedSections(advancedSections, rule);
60   }
61
62   /**
63    * This was done to preserve backward compatibility with SonarLint until they stop using htmlDesc field in api/rules/[show|search] endpoints, see SONAR-16635
64    * @deprecated the method should be removed once SonarLint supports rules.descriptionSections fields, I.E in 10.x
65    */
66   @Deprecated(since = "9.6", forRemoval = true)
67   private Set<RuleDescriptionSectionDto> addLegacySectionToAdvancedSections(Set<RuleDescriptionSectionDto> advancedSections, RulesDefinition.Rule rule) {
68     Set<RuleDescriptionSectionDto> legacySection = legacyIssueRuleDescriptionSectionsGenerator.generateSections(rule);
69     return Sets.union(advancedSections, legacySection);
70   }
71
72   private RuleDescriptionSectionDto toRuleDescriptionSectionDto(RuleDescriptionSection section) {
73     return RuleDescriptionSectionDto.builder()
74       .uuid(uuidFactory.create())
75       .key(section.getKey())
76       .content(section.getHtmlContent())
77       .context(toRuleDescriptionSectionContextDto(section.getContext()))
78       .build();
79   }
80
81   @Nullable
82   private static RuleDescriptionSectionContextDto toRuleDescriptionSectionContextDto(Optional<Context> context) {
83     return context
84       .map(c -> RuleDescriptionSectionContextDto.of(c.getKey(), c.getDisplayName()))
85       .orElse(null);
86   }
87
88 }