From 344aa4461ce308745c63f6299145a3d8117d6dea Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Tue, 25 Nov 2014 10:25:06 +0100 Subject: [PATCH] SONAR-5874 Support deprecated org.sonar.api.rules.RuleRepository when extending rules of org.sonar.api.server.rule.RulesDefinition --- .../server/platform/ServerComponents.java | 2 +- ...a => DeprecatedRulesDefinitionLoader.java} | 33 ++++++++++--------- .../org/sonar/server/rule/RegisterRules.java | 12 ++++--- .../server/rule/RuleDefinitionsLoader.java | 13 ++++++-- ... DeprecatedRulesDefinitionLoaderTest.java} | 18 +++++----- .../sonar/server/rule/RegisterRulesTest.java | 4 +-- .../rule/RulesDefinitionLoaderTest.java | 5 +-- 7 files changed, 51 insertions(+), 36 deletions(-) rename server/sonar-server/src/main/java/org/sonar/server/rule/{DeprecatedRulesDefinition.java => DeprecatedRulesDefinitionLoader.java} (85%) rename server/sonar-server/src/test/java/org/sonar/server/rule/{DeprecatedRulesDefinitionTest.java => DeprecatedRulesDefinitionLoaderTest.java} (91%) diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 0041a742d92..c30bf37d6bf 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -344,7 +344,7 @@ class ServerComponents { pico.addSingleton(RuleOperations.class); pico.addSingleton(RubyRuleService.class); pico.addSingleton(RuleRepositories.class); - pico.addSingleton(DeprecatedRulesDefinition.class); + pico.addSingleton(DeprecatedRulesDefinitionLoader.class); pico.addSingleton(RuleDefinitionsLoader.class); pico.addSingleton(RulesDefinitionXmlLoader.class); pico.addSingleton(RuleService.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRulesDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRulesDefinitionLoader.java similarity index 85% rename from server/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRulesDefinition.java rename to server/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRulesDefinitionLoader.java index 8f185baf378..e54002f4bc9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRulesDefinition.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRulesDefinitionLoader.java @@ -25,6 +25,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.ServerComponent; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.RuleParam; @@ -51,9 +52,9 @@ import static org.sonar.server.debt.DebtModelXMLExporter.RuleDebt; /** * Inject deprecated RuleRepository into {@link org.sonar.api.server.rule.RulesDefinition} for backward-compatibility. */ -public class DeprecatedRulesDefinition implements RulesDefinition { +public class DeprecatedRulesDefinitionLoader implements ServerComponent { - private static final Logger LOG = LoggerFactory.getLogger(DeprecatedRulesDefinition.class); + private static final Logger LOG = LoggerFactory.getLogger(DeprecatedRulesDefinitionLoader.class); private final RuleI18nManager i18n; private final RuleRepository[] repositories; @@ -61,33 +62,35 @@ public class DeprecatedRulesDefinition implements RulesDefinition { private final DebtModelPluginRepository languageModelFinder; private final DebtRulesXMLImporter importer; - public DeprecatedRulesDefinition(RuleI18nManager i18n, RuleRepository[] repositories, DebtModelPluginRepository languageModelFinder, DebtRulesXMLImporter importer) { + public DeprecatedRulesDefinitionLoader(RuleI18nManager i18n, DebtModelPluginRepository languageModelFinder, DebtRulesXMLImporter importer, RuleRepository[] repositories) { this.i18n = i18n; this.repositories = repositories; this.languageModelFinder = languageModelFinder; this.importer = importer; } - public DeprecatedRulesDefinition(RuleI18nManager i18n, DebtModelPluginRepository languageModelFinder, DebtRulesXMLImporter importer) { - this(i18n, new RuleRepository[0], languageModelFinder, importer); + /** + * Used when no deprecated repositories + */ + public DeprecatedRulesDefinitionLoader(RuleI18nManager i18n, DebtModelPluginRepository languageModelFinder, DebtRulesXMLImporter importer) { + this(i18n, languageModelFinder, importer, new RuleRepository[0]); } - @Override - public void define(Context context) { + void complete(RulesDefinition.Context context) { // Load rule debt definitions from xml files provided by plugin List ruleDebts = loadRuleDebtList(); for (RuleRepository repository : repositories) { // RuleRepository API does not handle difference between new and extended repositories, - NewRepository newRepository; + RulesDefinition.NewRepository newRepository; if (context.repository(repository.getKey()) == null) { newRepository = context.createRepository(repository.getKey(), repository.getLanguage()); newRepository.setName(repository.getName()); } else { - newRepository = (NewRepository) context.extendRepository(repository.getKey(), repository.getLanguage()); + newRepository = (RulesDefinition.NewRepository) context.extendRepository(repository.getKey(), repository.getLanguage()); } for (org.sonar.api.rules.Rule rule : repository.createRules()) { - NewRule newRule = newRepository.createRule(rule.getKey()); + RulesDefinition.NewRule newRule = newRepository.createRule(rule.getKey()); newRule.setName(ruleName(repository.getKey(), rule)); newRule.setHtmlDescription(ruleDescription(repository.getKey(), rule)); newRule.setInternalKey(rule.getConfigKey()); @@ -96,7 +99,7 @@ public class DeprecatedRulesDefinition implements RulesDefinition { newRule.setStatus(rule.getStatus() == null ? RuleStatus.defaultStatus() : RuleStatus.valueOf(rule.getStatus())); newRule.setTags(rule.getTags()); for (RuleParam param : rule.getParams()) { - NewParam newParam = newRule.createParam(param.getKey()); + 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())); @@ -107,7 +110,7 @@ public class DeprecatedRulesDefinition implements RulesDefinition { } } - private void updateRuleDebtDefinitions(NewRule newRule, String repoKey, String ruleKey, List ruleDebts) { + private void updateRuleDebtDefinitions(RulesDefinition.NewRule newRule, String repoKey, String ruleKey, List ruleDebts) { RuleDebt ruleDebt = findRequirement(ruleDebts, repoKey, ruleKey); if (ruleDebt != null) { newRule.setDebtSubCharacteristic(ruleDebt.subCharacteristicKey()); @@ -116,12 +119,12 @@ public class DeprecatedRulesDefinition implements RulesDefinition { ruleDebt.offset(), newRule.debtRemediationFunctions(), repoKey, ruleKey - )); + )); } } private DebtRemediationFunction remediationFunction(DebtRemediationFunction.Type function, @Nullable String coefficient, @Nullable String offset, - DebtRemediationFunctions functions, String repoKey, String ruleKey) { + 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) { @@ -156,7 +159,7 @@ public class DeprecatedRulesDefinition implements RulesDefinition { String desc = StringUtils.defaultIfEmpty( i18n.getParamDescription(repositoryKey, ruleKey, param.getKey()), param.getDescription() - ); + ); return StringUtils.defaultIfBlank(desc, null); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java b/server/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java index 1cf8dc29103..46609a8b6bd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java @@ -36,7 +36,6 @@ import org.sonar.api.rule.RuleStatus; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.MessageException; -import org.sonar.api.utils.System2; import org.sonar.api.utils.TimeProfiler; import org.sonar.core.persistence.DbSession; import org.sonar.core.qualityprofile.db.ActiveRuleDto; @@ -53,7 +52,12 @@ import org.sonar.server.startup.RegisterDebtModel; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static com.google.common.collect.Lists.newArrayList; @@ -74,12 +78,12 @@ public class RegisterRules implements Startable { * @param registerDebtModel used only to be started after init of the technical debt model */ public RegisterRules(RuleDefinitionsLoader defLoader, RuleActivator ruleActivator, DbClient dbClient, Languages languages, RegisterDebtModel registerDebtModel) { - this(defLoader, ruleActivator, dbClient, languages, System2.INSTANCE); + this(defLoader, ruleActivator, dbClient, languages); } @VisibleForTesting RegisterRules(RuleDefinitionsLoader defLoader, RuleActivator ruleActivator, - DbClient dbClient, Languages languages, System2 system) { + DbClient dbClient, Languages languages) { this.defLoader = defLoader; this.ruleActivator = ruleActivator; this.dbClient = dbClient; diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleDefinitionsLoader.java b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleDefinitionsLoader.java index ac4491e18ae..f64ba522009 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleDefinitionsLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleDefinitionsLoader.java @@ -27,16 +27,22 @@ import org.sonar.api.server.rule.RulesDefinition; * and initializes {@link org.sonar.server.rule.RuleRepositories}. Used at server startup. */ public class RuleDefinitionsLoader implements ServerComponent { + + private final DeprecatedRulesDefinitionLoader deprecatedDefinitionConverter; private final RulesDefinition[] definitions; private final RuleRepositories repositories; - public RuleDefinitionsLoader(RuleRepositories repositories, RulesDefinition[] definitions) { + public RuleDefinitionsLoader(DeprecatedRulesDefinitionLoader deprecatedDefinitionConverter, RuleRepositories repositories, RulesDefinition[] definitions) { + this.deprecatedDefinitionConverter = deprecatedDefinitionConverter; this.repositories = repositories; this.definitions = definitions; } - public RuleDefinitionsLoader(RuleRepositories repositories) { - this(repositories, new RulesDefinition[0]); + /** + * Used when no definitions at all. + */ + public RuleDefinitionsLoader(DeprecatedRulesDefinitionLoader converter, RuleRepositories repositories) { + this(converter, repositories, new RulesDefinition[0]); } public RulesDefinition.Context load() { @@ -44,6 +50,7 @@ public class RuleDefinitionsLoader implements ServerComponent { for (RulesDefinition definition : definitions) { definition.define(context); } + deprecatedDefinitionConverter.complete(context); repositories.register(context); return context; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRulesDefinitionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRulesDefinitionLoaderTest.java similarity index 91% rename from server/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRulesDefinitionTest.java rename to server/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRulesDefinitionLoaderTest.java index 59bfb301f1e..aca4a6157a1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRulesDefinitionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRulesDefinitionLoaderTest.java @@ -50,7 +50,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) -public class DeprecatedRulesDefinitionTest { +public class DeprecatedRulesDefinitionLoaderTest { @Mock RuleI18nManager i18n; @@ -74,7 +74,7 @@ public class DeprecatedRulesDefinitionTest { rule.setConfigKey("Checker/TreeWalker/ConstantName"); rule.setSeverity(RulePriority.BLOCKER); rule.setStatus(Rule.STATUS_BETA); - rule.setTags(new String[]{"style", "security"}); + rule.setTags(new String[] {"style", "security"}); rule.createParameter("format").setDescription("Regular expression").setDefaultValue("A-Z").setType("REGULAR_EXPRESSION"); return Arrays.asList(rule); } @@ -97,7 +97,7 @@ public class DeprecatedRulesDefinitionTest { @Test public void wrap_deprecated_rule_repositories() throws Exception { RulesDefinition.Context context = new RulesDefinition.Context(); - new DeprecatedRulesDefinition(i18n, new RuleRepository[]{new CheckstyleRules()}, debtModelRepository, importer).define(context); + new DeprecatedRulesDefinitionLoader(i18n, debtModelRepository, importer, new RuleRepository[] {new CheckstyleRules()}).complete(context); assertThat(context.repositories()).hasSize(1); RulesDefinition.Repository checkstyle = context.repository("checkstyle"); @@ -129,7 +129,7 @@ public class DeprecatedRulesDefinitionTest { RulesDefinition.Context context = new RulesDefinition.Context(); // no more RuleRepository ! - new DeprecatedRulesDefinition(i18n, debtModelRepository, importer); + new DeprecatedRulesDefinitionLoader(i18n, debtModelRepository, importer); assertThat(context.repositories()).isEmpty(); } @@ -141,7 +141,7 @@ public class DeprecatedRulesDefinitionTest { when(i18n.getDescription("checkstyle", "ConstantName")).thenReturn("Checks that constant names conform to the specified format"); when(i18n.getParamDescription("checkstyle", "ConstantName", "format")).thenReturn("Regular expression"); - new DeprecatedRulesDefinition(i18n, new RuleRepository[]{new UseBundles()}, debtModelRepository, importer).define(context); + new DeprecatedRulesDefinitionLoader(i18n, debtModelRepository, importer, new RuleRepository[] {new UseBundles()}).complete(context); RulesDefinition.Repository checkstyle = context.repository("checkstyle"); RulesDefinition.Rule rule = checkstyle.rule("ConstantName"); @@ -165,14 +165,14 @@ public class DeprecatedRulesDefinitionTest { .setFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) .setCoefficient("1d") .setOffset("10min") - ); + ); Reader javaModelReader = mock(Reader.class); when(debtModelRepository.createReaderForXMLFile("java")).thenReturn(javaModelReader); when(debtModelRepository.getContributingPluginList()).thenReturn(newArrayList("java")); when(importer.importXML(eq(javaModelReader), any(ValidationMessages.class))).thenReturn(ruleDebts); - new DeprecatedRulesDefinition(i18n, new RuleRepository[]{new CheckstyleRules()}, debtModelRepository, importer).define(context); + new DeprecatedRulesDefinitionLoader(i18n, debtModelRepository, importer, new RuleRepository[] {new CheckstyleRules()}).complete(context); assertThat(context.repositories()).hasSize(1); RulesDefinition.Repository checkstyle = context.repository("checkstyle"); @@ -197,7 +197,7 @@ public class DeprecatedRulesDefinitionTest { .setRuleKey(RuleKey.of("checkstyle", "ConstantName")) .setFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) .setCoefficient("1d") - ); + ); Reader javaModelReader = mock(Reader.class); when(debtModelRepository.createReaderForXMLFile("java")).thenReturn(javaModelReader); @@ -205,7 +205,7 @@ public class DeprecatedRulesDefinitionTest { when(importer.importXML(eq(javaModelReader), any(ValidationMessages.class))).thenReturn(ruleDebts); try { - new DeprecatedRulesDefinition(i18n, new RuleRepository[]{new CheckstyleRules()}, debtModelRepository, importer).define(context); + new DeprecatedRulesDefinitionLoader(i18n, debtModelRepository, importer, new RuleRepository[] {new CheckstyleRules()}).complete(context); fail(); } catch (Exception e) { assertThat(e).isInstanceOf(IllegalArgumentException.class); diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java index ac63a246aad..50921c05bad 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java @@ -200,11 +200,11 @@ public class RegisterRulesTest extends AbstractDaoTestCase { } private void execute(RulesDefinition... defs) { - RuleDefinitionsLoader loader = new RuleDefinitionsLoader(mock(RuleRepositories.class), defs); + RuleDefinitionsLoader loader = new RuleDefinitionsLoader(mock(DeprecatedRulesDefinitionLoader.class), new RuleRepositories(),defs); Languages languages = mock(Languages.class); when(languages.get("java")).thenReturn(mock(Language.class)); - RegisterRules task = new RegisterRules(loader, ruleActivator, dbClient, languages, system); + RegisterRules task = new RegisterRules(loader, ruleActivator, dbClient, languages); task.start(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RulesDefinitionLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RulesDefinitionLoaderTest.java index a5e6a23e0b9..74fb2b09d35 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RulesDefinitionLoaderTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/RulesDefinitionLoaderTest.java @@ -23,13 +23,14 @@ import org.junit.Test; import org.sonar.api.server.rule.RulesDefinition; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; public class RulesDefinitionLoaderTest { @Test public void no_definitions() { RuleRepositories repositories = new RuleRepositories(); - RulesDefinition.Context context = new RuleDefinitionsLoader(repositories).load(); + RulesDefinition.Context context = new RuleDefinitionsLoader(mock(DeprecatedRulesDefinitionLoader.class), repositories).load(); assertThat(context.repositories()).isEmpty(); assertThat(repositories.repositories()).isEmpty(); @@ -39,7 +40,7 @@ public class RulesDefinitionLoaderTest { public void load_definitions() { RuleRepositories repositories = new RuleRepositories(); - RulesDefinition.Context context = new RuleDefinitionsLoader(repositories, new RulesDefinition[]{ + RulesDefinition.Context context = new RuleDefinitionsLoader(mock(DeprecatedRulesDefinitionLoader.class), repositories, new RulesDefinition[]{ new FindbugsDefinitions(), new SquidDefinitions() }).load(); -- 2.39.5