Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.sonar.server.rule.DeprecatedRulesDefinitionLoader Maven / Gradle / Ivy
/*
* SonarQube
* Copyright (C) 2009-2018 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.server.rule;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import java.io.Reader;
import java.util.Collection;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.RuleParam;
import org.sonar.api.rules.RuleRepository;
import org.sonar.api.server.ServerSide;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.server.debt.DebtModelPluginRepository;
import org.sonar.server.debt.DebtModelXMLExporter;
import org.sonar.server.debt.DebtModelXMLExporter.RuleDebt;
import org.sonar.server.debt.DebtRulesXMLImporter;
import org.sonar.server.plugins.ServerPluginRepository;
import static com.google.common.collect.Lists.newArrayList;
/**
* Inject deprecated RuleRepository into {@link org.sonar.api.server.rule.RulesDefinition} for backward-compatibility.
*/
@ServerSide
@ComputeEngineSide
public class DeprecatedRulesDefinitionLoader {
private static final Logger LOG = Loggers.get(DeprecatedRulesDefinitionLoader.class);
private final RuleI18nManager i18n;
private final RuleRepository[] repositories;
private final DebtModelPluginRepository languageModelFinder;
private final DebtRulesXMLImporter importer;
private final ServerPluginRepository serverPluginRepository;
public DeprecatedRulesDefinitionLoader(RuleI18nManager i18n, DebtModelPluginRepository languageModelFinder, DebtRulesXMLImporter importer,
ServerPluginRepository serverPluginRepository, RuleRepository[] repositories) {
this.i18n = i18n;
this.serverPluginRepository = serverPluginRepository;
this.repositories = repositories;
this.languageModelFinder = languageModelFinder;
this.importer = importer;
}
/**
* Used when no deprecated repositories
*/
public DeprecatedRulesDefinitionLoader(RuleI18nManager i18n, DebtModelPluginRepository languageModelFinder, DebtRulesXMLImporter importer,
ServerPluginRepository serverPluginRepository) {
this(i18n, languageModelFinder, importer, serverPluginRepository, new RuleRepository[0]);
}
void complete(RulesDefinition.Context context) {
// Load rule debt definitions from xml files provided by plugin
List ruleDebts = loadRuleDebtList();
for (RuleRepository repository : repositories) {
context.setCurrentPluginKey(serverPluginRepository.getPluginKey(repository));
// RuleRepository API does not handle difference between new and extended repositories,
RulesDefinition.NewRepository newRepository;
if (context.repository(repository.getKey()) == null) {
newRepository = context.createRepository(repository.getKey(), repository.getLanguage());
newRepository.setName(repository.getName());
} else {
newRepository = context.extendRepository(repository.getKey(), repository.getLanguage());
}
for (org.sonar.api.rules.Rule rule : repository.createRules()) {
RulesDefinition.NewRule newRule = newRepository.createRule(rule.getKey());
newRule.setName(ruleName(repository.getKey(), rule));
newRule.setHtmlDescription(ruleDescription(repository.getKey(), rule));
newRule.setInternalKey(rule.getConfigKey());
newRule.setTemplate(rule.isTemplate());
newRule.setSeverity(rule.getSeverity().toString());
newRule.setStatus(rule.getStatus() == null ? RuleStatus.defaultStatus() : RuleStatus.valueOf(rule.getStatus()));
newRule.setTags(rule.getTags());
for (RuleParam param : rule.getParams()) {
RulesDefinition.NewParam newParam = newRule.createParam(param.getKey());
newParam.setDefaultValue(param.getDefaultValue());
newParam.setDescription(paramDescription(repository.getKey(), rule.getKey(), param));
newParam.setType(RuleParamType.parse(param.getType()));
}
updateRuleDebtDefinitions(newRule, repository.getKey(), rule.getKey(), ruleDebts);
}
newRepository.done();
}
}
private static void updateRuleDebtDefinitions(RulesDefinition.NewRule newRule, String repoKey, String ruleKey, List ruleDebts) {
RuleDebt ruleDebt = findRequirement(ruleDebts, repoKey, ruleKey);
if (ruleDebt != null) {
newRule.setDebtRemediationFunction(remediationFunction(DebtRemediationFunction.Type.valueOf(ruleDebt.function()),
ruleDebt.coefficient(),
ruleDebt.offset(),
newRule.debtRemediationFunctions(),
repoKey, ruleKey));
}
}
private static DebtRemediationFunction remediationFunction(DebtRemediationFunction.Type function, @Nullable String coefficient, @Nullable String offset,
RulesDefinition.DebtRemediationFunctions functions, String repoKey, String ruleKey) {
if (DebtRemediationFunction.Type.LINEAR.equals(function) && coefficient != null) {
return functions.linear(coefficient);
} else if (DebtRemediationFunction.Type.CONSTANT_ISSUE.equals(function) && offset != null) {
return functions.constantPerIssue(offset);
} else if (DebtRemediationFunction.Type.LINEAR_OFFSET.equals(function) && coefficient != null && offset != null) {
return functions.linearWithOffset(coefficient, offset);
} else {
throw new IllegalArgumentException(String.format("Debt definition on rule '%s:%s' is invalid", repoKey, ruleKey));
}
}
@CheckForNull
private String ruleName(String repositoryKey, org.sonar.api.rules.Rule rule) {
String name = i18n.getName(repositoryKey, rule.getKey());
if (StringUtils.isNotBlank(name)) {
return name;
}
return StringUtils.defaultIfBlank(rule.getName(), null);
}
@CheckForNull
private String ruleDescription(String repositoryKey, org.sonar.api.rules.Rule rule) {
String description = i18n.getDescription(repositoryKey, rule.getKey());
if (StringUtils.isNotBlank(description)) {
return description;
}
return StringUtils.defaultIfBlank(rule.getDescription(), null);
}
@CheckForNull
private String paramDescription(String repositoryKey, String ruleKey, RuleParam param) {
String desc = StringUtils.defaultIfEmpty(
i18n.getParamDescription(repositoryKey, ruleKey, param.getKey()),
param.getDescription());
return StringUtils.defaultIfBlank(desc, null);
}
public List loadRuleDebtList() {
List ruleDebtList = newArrayList();
for (String pluginKey : getContributingPluginListWithoutSqale()) {
ruleDebtList.addAll(loadRuleDebtsFromXml(pluginKey));
}
return ruleDebtList;
}
public List loadRuleDebtsFromXml(String pluginKey) {
Reader xmlFileReader = null;
try {
xmlFileReader = languageModelFinder.createReaderForXMLFile(pluginKey);
ValidationMessages validationMessages = ValidationMessages.create();
List rules = importer.importXML(xmlFileReader, validationMessages);
validationMessages.log(LOG);
return rules;
} finally {
IOUtils.closeQuietly(xmlFileReader);
}
}
private Collection getContributingPluginListWithoutSqale() {
Collection pluginList = newArrayList(languageModelFinder.getContributingPluginList());
pluginList.remove(DebtModelPluginRepository.DEFAULT_MODEL);
return pluginList;
}
@CheckForNull
private static RuleDebt findRequirement(List requirements, final String repoKey, final String ruleKey) {
return Iterables.find(requirements, new RuleDebtMatchRepoKeyAndRuleKey(repoKey, ruleKey), null);
}
private static class RuleDebtMatchRepoKeyAndRuleKey implements Predicate {
private final String repoKey;
private final String ruleKey;
public RuleDebtMatchRepoKeyAndRuleKey(String repoKey, String ruleKey) {
this.repoKey = repoKey;
this.ruleKey = ruleKey;
}
@Override
public boolean apply(@Nonnull RuleDebt input) {
return input.ruleKey().equals(RuleKey.of(repoKey, ruleKey));
}
}
}