]> source.dussan.org Git - sonarqube.git/blob
73598cc54a8ae097f0fa2b68b17876b13a12cf9a
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 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.ce.task.projectanalysis.issue;
21
22 import com.google.common.collect.Multimap;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Optional;
27 import java.util.Set;
28 import java.util.function.Supplier;
29 import javax.annotation.CheckForNull;
30 import org.sonar.api.rule.RuleKey;
31 import org.sonar.api.rule.RuleStatus;
32 import org.sonar.api.rules.RuleType;
33 import org.sonar.api.server.debt.DebtRemediationFunction;
34 import org.sonar.core.util.stream.MoreCollectors;
35 import org.sonar.db.DbClient;
36 import org.sonar.db.DbSession;
37 import org.sonar.db.rule.DeprecatedRuleKeyDto;
38 import org.sonar.db.rule.RuleDto;
39
40 import static com.google.common.base.Preconditions.checkArgument;
41 import static java.util.Objects.requireNonNull;
42
43 public class RuleRepositoryImpl implements RuleRepository {
44
45   @CheckForNull
46   private Map<RuleKey, Rule> rulesByKey;
47   @CheckForNull
48   private Map<String, Rule> rulesByUuid;
49
50   private final AdHocRuleCreator creator;
51   private final DbClient dbClient;
52
53   private Map<RuleKey, NewAdHocRule> adHocRulesPersist = new HashMap<>();
54
55   public RuleRepositoryImpl(AdHocRuleCreator creator, DbClient dbClient) {
56     this.creator = creator;
57     this.dbClient = dbClient;
58   }
59
60   public void addOrUpdateAddHocRuleIfNeeded(RuleKey ruleKey, Supplier<NewAdHocRule> ruleSupplier) {
61     ensureInitialized();
62
63     Rule existingRule = rulesByKey.get(ruleKey);
64     if (existingRule == null || (existingRule.isAdHoc() && !adHocRulesPersist.containsKey(ruleKey))) {
65       NewAdHocRule newAdHocRule = ruleSupplier.get();
66       adHocRulesPersist.put(ruleKey, newAdHocRule);
67       rulesByKey.put(ruleKey, new AdHocRuleWrapper(newAdHocRule));
68     }
69   }
70
71   @Override
72   public void saveOrUpdateAddHocRules(DbSession dbSession) {
73     ensureInitialized();
74
75     adHocRulesPersist.values().forEach(r -> persistAndIndex(dbSession, r));
76   }
77
78   private void persistAndIndex(DbSession dbSession, NewAdHocRule adHocRule) {
79     Rule rule = new RuleImpl(creator.persistAndIndex(dbSession, adHocRule));
80     rulesByUuid.put(rule.getUuid(), rule);
81     rulesByKey.put(adHocRule.getKey(), rule);
82   }
83
84   @Override
85   public Rule getByKey(RuleKey key) {
86     verifyKeyArgument(key);
87
88     ensureInitialized();
89
90     Rule rule = rulesByKey.get(key);
91     checkArgument(rule != null, "Can not find rule for key %s. This rule does not exist in DB", key);
92     return rule;
93   }
94
95   @Override
96   public Optional<Rule> findByKey(RuleKey key) {
97     verifyKeyArgument(key);
98
99     ensureInitialized();
100
101     return Optional.ofNullable(rulesByKey.get(key));
102   }
103
104   @Override
105   public Rule getByUuid(String uuid) {
106     ensureInitialized();
107
108     Rule rule = rulesByUuid.get(uuid);
109     checkArgument(rule != null, "Can not find rule for uuid %s. This rule does not exist in DB", uuid);
110     return rule;
111   }
112
113   @Override
114   public Optional<Rule> findByUuid(String uuid) {
115     ensureInitialized();
116
117     return Optional.ofNullable(rulesByUuid.get(uuid));
118   }
119
120   private static void verifyKeyArgument(RuleKey key) {
121     requireNonNull(key, "RuleKey can not be null");
122   }
123
124   private void ensureInitialized() {
125     if (rulesByKey == null) {
126       try (DbSession dbSession = dbClient.openSession(false)) {
127         loadRulesFromDb(dbSession);
128       }
129     }
130   }
131
132   private void loadRulesFromDb(DbSession dbSession) {
133     this.rulesByKey = new HashMap<>();
134     this.rulesByUuid = new HashMap<>();
135     Multimap<String, DeprecatedRuleKeyDto> deprecatedRuleKeysByRuleUuid = dbClient.ruleDao().selectAllDeprecatedRuleKeys(dbSession).stream()
136       .collect(MoreCollectors.index(DeprecatedRuleKeyDto::getRuleUuid));
137     for (RuleDto ruleDto : dbClient.ruleDao().selectAll(dbSession)) {
138       Rule rule = new RuleImpl(ruleDto);
139       rulesByKey.put(ruleDto.getKey(), rule);
140       rulesByUuid.put(ruleDto.getUuid(), rule);
141       deprecatedRuleKeysByRuleUuid.get(ruleDto.getUuid()).forEach(t -> rulesByKey.put(RuleKey.of(t.getOldRepositoryKey(), t.getOldRuleKey()), rule));
142     }
143   }
144
145   private static class AdHocRuleWrapper implements Rule {
146     private final NewAdHocRule addHocRule;
147
148     private AdHocRuleWrapper(NewAdHocRule addHocRule) {
149       this.addHocRule = addHocRule;
150     }
151
152     public NewAdHocRule getDelegate() {
153       return addHocRule;
154     }
155
156     @Override
157     public String getUuid() {
158       throw new UnsupportedOperationException("Rule is not persisted, can't know the uuid");
159     }
160
161     @Override
162     public RuleKey getKey() {
163       return addHocRule.getKey();
164     }
165
166     @Override
167     public String getName() {
168       return addHocRule.getName();
169     }
170
171     @Override
172     @CheckForNull
173     public String getLanguage() {
174       return null;
175     }
176
177     @Override
178     public RuleStatus getStatus() {
179       return RuleStatus.defaultStatus();
180     }
181
182     @Override
183     @CheckForNull
184     public RuleType getType() {
185       return null;
186     }
187
188     @Override
189     public boolean isExternal() {
190       return true;
191     }
192
193     @Override
194     public boolean isAdHoc() {
195       return true;
196     }
197
198     @Override
199     public Set<String> getTags() {
200       return Collections.emptySet();
201     }
202
203     @CheckForNull
204     @Override
205     public DebtRemediationFunction getRemediationFunction() {
206       return null;
207     }
208
209     @CheckForNull
210     @Override
211     public String getPluginKey() {
212       return null;
213     }
214
215     @Override
216     public String getDefaultRuleDescription() {
217       return addHocRule.getDescription();
218     }
219
220     @Override
221     public String getSeverity() {
222       return addHocRule.getSeverity();
223     }
224   }
225 }