import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import java.util.ArrayList;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleKey;
+import org.sonar.db.qualityprofile.SqlActiveRuleKey;
import org.sonar.db.qualityprofile.ActiveRuleMapper;
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.qualityprofile.QualityProfileDao;
return emptyList();
}
- return DatabaseUtils.executeLargeInputs(keys, new Function<List<ActiveRuleKey>, List<ActiveRuleDto>>() {
+ List<SqlActiveRuleKey> sqlKeys = new ArrayList<>();
+ for (ActiveRuleKey key : keys) {
+ sqlKeys.add(new SqlActiveRuleKey(key));
+ }
+
+ return DatabaseUtils.executeLargeInputs(sqlKeys, new Function<List<SqlActiveRuleKey>, List<ActiveRuleDto>>() {
@Override
- public List<ActiveRuleDto> apply(@Nonnull List<ActiveRuleKey> input) {
+ public List<ActiveRuleDto> apply(@Nonnull List<SqlActiveRuleKey> input) {
return mapper(dbSession).selectByKeys(input);
}
});
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.sonar.server.db.DbClient;
import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.qualityprofile.QProfileLoader;
-import org.sonar.server.rule.Rule;
import org.sonar.server.rule.index.RuleQuery;
import org.sonarqube.ws.Rules;
import org.sonarqube.ws.Rules.SearchResponse;
return qProfileKeys;
}
- void completeShow(Rule rule, ShowResponse.Builder response) {
- for (ActiveRule activeRule : loader.findActiveRulesByRule(rule.key())) {
- response.addActives(buildActiveRuleResponse(activeRule, Collections.<ActiveRuleParamDto>emptyList()));
+ void completeShow(DbSession dbSession, RuleDto rule, ShowResponse.Builder response) {
+ List<ActiveRule> activeRules = loader.findActiveRulesByRule(rule.getKey());
+ List<ActiveRuleDto> activeRuleDtos = dbClient.activeRuleDao().selectByActiveRuleKeys(dbSession, Lists.transform(activeRules, ActiveRuleToKey.INSTANCE));
+ Map<Integer, ActiveRuleKey> activeRuleIdsByKey = new HashMap<>();
+ for (ActiveRuleDto activeRuleDto : activeRuleDtos) {
+ activeRuleIdsByKey.put(activeRuleDto.getId(), activeRuleDto.getKey());
+ }
+
+ List<ActiveRuleParamDto> activeRuleParamDtos = dbClient.activeRuleDao().selectParamsByActiveRuleIds(dbSession, Lists.transform(activeRuleDtos, ActiveRuleDtoToId.INSTANCE));
+ ListMultimap<ActiveRuleKey, ActiveRuleParamDto> activeRuleParamsByActiveRuleKey = ArrayListMultimap.create(activeRules.size(), 10);
+ for (ActiveRuleParamDto activeRuleParamDto : activeRuleParamDtos) {
+ ActiveRuleKey activeRuleKey = activeRuleIdsByKey.get(activeRuleParamDto.getId());
+ activeRuleParamsByActiveRuleKey.put(activeRuleKey, activeRuleParamDto);
+ }
+
+ for (ActiveRule activeRule : activeRules) {
+ response.addActives(buildActiveRuleResponse(activeRule, activeRuleParamsByActiveRuleKey.get(activeRule.key())));
}
}
this.macroInterpreter = macroInterpreter;
}
+ /**
+ * Convert a RuleDto to WsRule. If fieldsToReturn is empty all the fields are returned
+ */
public Rules.Rule toWsRule(RuleDto ruleDto, SearchResult result, Set<String> fieldsToReturn) {
Rules.Rule.Builder ruleResponse = Rules.Rule.newBuilder();
private static DebtRemediationFunction debtRemediationFunction(final RuleDto ruleDto) {
final String function = ruleDto.getRemediationFunction();
if (function == null || function.isEmpty()) {
- return null;
+ return defaultDebtRemediationFunction(ruleDto);
} else {
return new DebtRemediationFunction() {
@Override
.toList();
List<RuleDto> templateRules = dbClient.ruleDao().selectByIds(dbSession, templateRuleIds);
List<RuleParamDto> ruleParamDtos = dbClient.ruleDao().selectRuleParamsByRuleIds(dbSession, ruleIds);
- return new SearchResult(result)
+ return new SearchResult()
.setRules(rules)
- .setRuleParams(ruleParamDtos)
- .setTemplateRules(templateRules);
+ .setRuleParameters(ruleParamDtos)
+ .setTemplateRules(templateRules)
+ .setFacets(result.getFacetsObject())
+ .setTotal(result.getTotal());
}
protected RuleQuery doQuery(Request request) {
private List<RuleDto> rules;
private final ListMultimap<Integer, RuleParamDto> ruleParamsByRuleId;
private final Map<Integer, RuleDto> templateRulesByRuleId;
- private final long total;
- private final Facets facets;
+ private Long total;
+ private Facets facets;
- public SearchResult(Result<Rule> result) {
+ public SearchResult() {
this.rules = new ArrayList<>();
this.ruleParamsByRuleId = ArrayListMultimap.create();
this.templateRulesByRuleId = new HashMap<>();
- this.total = result.getTotal();
- this.facets = result.getFacetsObject();
}
public List<RuleDto> getRules() {
return ruleParamsByRuleId;
}
- public SearchResult setRuleParams(List<RuleParamDto> ruleParams) {
+ public SearchResult setRuleParameters(List<RuleParamDto> ruleParams) {
ruleParamsByRuleId.clear();
for (RuleParamDto ruleParam : ruleParams) {
ruleParamsByRuleId.put(ruleParam.getRuleId(), ruleParam);
return this;
}
- public long getTotal() {
+ @CheckForNull
+ public Long getTotal() {
return total;
}
+ public SearchResult setTotal(Long total) {
+ this.total = total;
+ return this;
+ }
+
+ @CheckForNull
public Facets getFacets() {
return facets;
}
+
+ public SearchResult setFacets(Facets facets) {
+ this.facets = facets;
+ return this;
+ }
}
private enum RuleDtoToId implements Function<RuleDto, Integer> {
*/
package org.sonar.server.rule.ws;
+import com.google.common.base.Optional;
import com.google.common.io.Resources;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.rule.Rule;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleParamDto;
import org.sonar.server.rule.RuleService;
import org.sonarqube.ws.Rules.ShowResponse;
+import static java.util.Collections.singletonList;
+import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
/**
public static final String PARAM_KEY = "key";
public static final String PARAM_ACTIVES = "actives";
+ private final DbClient dbClient;
private final RuleService service;
private final RuleMapping mapping;
+ private final RuleMapper mapper;
private final ActiveRuleCompleter activeRuleCompleter;
- public ShowAction(RuleService service, ActiveRuleCompleter activeRuleCompleter, RuleMapping mapping) {
+ public ShowAction(DbClient dbClient, RuleService service, RuleMapping mapping, RuleMapper mapper, ActiveRuleCompleter activeRuleCompleter) {
+ this.dbClient = dbClient;
this.service = service;
this.mapping = mapping;
this.activeRuleCompleter = activeRuleCompleter;
+ this.mapper = mapper;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
RuleKey key = RuleKey.parse(request.mandatoryParam(PARAM_KEY));
- Rule rule = service.getByKey(key);
- if (rule == null) {
- throw new NotFoundException("Rule not found: " + key);
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ Optional<RuleDto> optionalRule = dbClient.ruleDao().selectByKey(dbSession, key);
+ checkFoundWithOptional(optionalRule, "Rule not found: " + key);
+ RuleDto rule = optionalRule.get();
+ List<RuleDto> templateRules = new ArrayList<>();
+ if (rule.getTemplateId() != null) {
+ Optional<RuleDto> templateRule = dbClient.ruleDao().selectById(rule.getTemplateId(), dbSession);
+ if (templateRule.isPresent()) {
+ templateRules.add(templateRule.get());
+ }
+ }
+ List<RuleParamDto> ruleParameters = dbClient.ruleDao().selectRuleParamsByRuleIds(dbSession, singletonList(rule.getId()));
+ ShowResponse showResponse = buildResponse(dbSession, request,
+ new SearchAction.SearchResult()
+ .setRules(singletonList(rule))
+ .setTemplateRules(templateRules)
+ .setRuleParameters(ruleParameters)
+ .setTotal(1L));
+ writeProtobuf(showResponse, request, response);
+ } finally {
+ dbClient.closeSession(dbSession);
}
- ShowResponse showResponse = buildResponse(request, rule);
- writeProtobuf(showResponse, request, response);
}
- private ShowResponse buildResponse(Request request, Rule rule) {
+ private ShowResponse buildResponse(DbSession dbSession, Request request, SearchAction.SearchResult searchResult) {
ShowResponse.Builder responseBuilder = ShowResponse.newBuilder();
- responseBuilder.setRule(mapping.buildRuleResponse(rule, null /* TODO replace by SearchOptions immutable constant */));
+ RuleDto rule = searchResult.getRules().get(0);
+ responseBuilder.setRule(mapper.toWsRule(rule, searchResult, Collections.<String>emptySet()));
if (request.mandatoryParamAsBoolean(PARAM_ACTIVES)) {
- activeRuleCompleter.completeShow(rule, responseBuilder);
+ activeRuleCompleter.completeShow(dbSession, rule, responseBuilder);
}
return responseBuilder.build();
ActiveRuleDto selectByKey(@Param("profileKey") String profileKey, @Param("repository") String repository, @Param("rule") String rule);
- List<ActiveRuleDto> selectByKeys(@Param("keys") List<ActiveRuleKey> keys);
+ List<ActiveRuleDto> selectByKeys(@Param("keys") List<SqlActiveRuleKey> keys);
List<ActiveRuleDto> selectByRuleId(int ruleId);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.db.qualityprofile;
+
+public class SqlActiveRuleKey implements Comparable<SqlActiveRuleKey> {
+ private final String qProfile;
+ private final String rule;
+ private final String repository;
+
+ public SqlActiveRuleKey(ActiveRuleKey key) {
+ this.qProfile = key.qProfile();
+ this.rule = key.ruleKey().rule();
+ this.repository = key.ruleKey().repository();
+ }
+
+ @Override
+ public int compareTo(SqlActiveRuleKey o) {
+ int result = qProfile.compareTo(o.qProfile);
+ if (result != 0) {
+ return result;
+ }
+ result = rule.compareTo(o.rule);
+ if (result != 0) {
+ return result;
+ }
+
+ return repository.compareTo(o.repository);
+ }
+
+ public String getqProfile() {
+ return qProfile;
+ }
+
+ public String getRule() {
+ return rule;
+ }
+
+ public String getRepository() {
+ return repository;
+ }
+}
<include refid="activeRuleKeyJoin"/>
WHERE
<foreach collection="keys" item="key" open="(" separator=" or " close=")">
- (qp.kee = #{key.qProfile()}
- AND r.plugin_rule_key = #{key.ruleKey().rule()}
- AND r.plugin_name = #{key.ruleKey().repository()})
+ (qp.kee = #{key.qProfile}
+ AND r.plugin_rule_key = #{key.rule}
+ AND r.plugin_name = #{key.repository})
</foreach>
</select>