From b0903c3790a72643840e147501a739604e3083de Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 9 Oct 2014 14:37:47 +0200 Subject: [PATCH] SONAR-5575 Fix missing parameter when creating and updating custom rule with empty parameter --- .../db/migrations/DatabaseMigrations.java | 18 +-- ...dMissingCustomRuleParametersMigration.java | 118 ++++++++++++++++++ .../org/sonar/server/rule/RuleCreator.java | 11 +- .../org/sonar/server/rule/RuleUpdater.java | 60 +++------ ...singCustomRuleParametersMigrationTest.java | 78 ++++++++++++ .../server/rule/RuleCreatorMediumTest.java | 85 +++++++------ .../server/rule/RuleUpdaterMediumTest.java | 58 +++++++-- .../execute-result.xml | 31 +++++ .../execute.xml | 29 +++++ ...n_custom_rule_have_no_parameter-result.xml | 31 +++++ ...ute_when_custom_rule_have_no_parameter.xml | 27 ++++ .../no_changes.xml | 25 ++++ .../schema.sql | 40 ++++++ .../601_add_missing_custom_rule_parameters.rb | 30 +++++ .../core/persistence/DatabaseVersion.java | 2 +- .../org/sonar/core/persistence/MyBatis.java | 4 +- .../migration/v45/Migration45Mapper.java | 61 +++++++++ .../core/persistence/migration/v45/Rule.java | 113 +++++++++++++++++ .../migration/v45/RuleParameter.java | 114 +++++++++++++++++ .../migration/v45/package-info.java | 23 ++++ .../org/sonar/core/rule/RuleParamDto.java | 6 +- .../migration/v45/Migration45Mapper.xml | 7 ++ .../org/sonar/core/persistence/rows-h2.sql | 1 + 23 files changed, 863 insertions(+), 109 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigration.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest.java create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute-result.xml create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute.xml create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/no_changes.xml create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/schema.sql create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/db/migrate/601_add_missing_custom_rule_parameters.rb create mode 100644 sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Migration45Mapper.java create mode 100644 sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Rule.java create mode 100644 sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/RuleParameter.java create mode 100644 sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/package-info.java create mode 100644 sonar-core/src/main/resources/org/sonar/core/persistence/migration/v45/Migration45Mapper.xml diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java index 5d280b4f7a2..d27f85f8344 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java @@ -23,18 +23,9 @@ import com.google.common.collect.ImmutableList; import org.sonar.server.db.migrations.v36.ViolationMigration; import org.sonar.server.db.migrations.v42.CompleteIssueMessageMigration; import org.sonar.server.db.migrations.v42.PackageKeysMigration; -import org.sonar.server.db.migrations.v43.ConvertIssueDebtToMinutesMigration; -import org.sonar.server.db.migrations.v43.DevelopmentCostMeasuresMigration; -import org.sonar.server.db.migrations.v43.IssueChangelogMigration; -import org.sonar.server.db.migrations.v43.NotResolvedIssuesOnRemovedComponentsMigration; -import org.sonar.server.db.migrations.v43.RequirementMeasuresMigration; -import org.sonar.server.db.migrations.v43.TechnicalDebtMeasuresMigration; -import org.sonar.server.db.migrations.v44.ChangeLogMigration; -import org.sonar.server.db.migrations.v44.ConvertProfileMeasuresMigration; -import org.sonar.server.db.migrations.v44.FeedQProfileDatesMigration; -import org.sonar.server.db.migrations.v44.FeedQProfileKeysMigration; -import org.sonar.server.db.migrations.v44.IssueActionPlanKeyMigration; -import org.sonar.server.db.migrations.v44.MeasureDataMigration; +import org.sonar.server.db.migrations.v43.*; +import org.sonar.server.db.migrations.v44.*; +import org.sonar.server.db.migrations.v45.AddMissingCustomRuleParametersMigration; import org.sonar.server.db.migrations.v45.AddMissingRuleParameterDefaultValuesMigration; import org.sonar.server.db.migrations.v45.DeleteMeasuresOnDeletedProfilesMigration; @@ -67,7 +58,8 @@ public interface DatabaseMigrations { // 4.5 AddMissingRuleParameterDefaultValuesMigration.class, - DeleteMeasuresOnDeletedProfilesMigration.class + DeleteMeasuresOnDeletedProfilesMigration.class, + AddMissingCustomRuleParametersMigration.class ); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigration.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigration.java new file mode 100644 index 00000000000..4df912365da --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigration.java @@ -0,0 +1,118 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.migrations.v45; + +import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.migration.v45.Migration45Mapper; +import org.sonar.core.persistence.migration.v45.Rule; +import org.sonar.core.persistence.migration.v45.RuleParameter; +import org.sonar.server.db.DbClient; +import org.sonar.server.db.migrations.DatabaseMigration; + +import javax.annotation.Nullable; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * See http://jira.codehaus.org/browse/SONAR-5575 + * + * Add missing parameters (with no value) on each custom rules + * + * @since 4.5 + */ +public class AddMissingCustomRuleParametersMigration implements DatabaseMigration { + + private final DbClient db; + private final System2 system; + + public AddMissingCustomRuleParametersMigration(DbClient db, System2 system) { + this.db = db; + this.system = system; + } + + @Override + public void execute() { + DbSession session = db.openSession(false); + try { + Migration45Mapper mapper = session.getMapper(Migration45Mapper.class); + + List templateRuleParams = mapper.selectAllTemplateRuleParameters(); + Multimap templateRuleParamsByRuleId = ArrayListMultimap.create(); + for (RuleParameter templateRuleParam : templateRuleParams) { + templateRuleParamsByRuleId.put(templateRuleParam.getRuleId(), templateRuleParam); + } + + List customRules = mapper.selectAllCustomRules(); + Multimap customRuleIdsByTemplateRuleId = HashMultimap.create(); + for (Rule customRule : customRules) { + customRuleIdsByTemplateRuleId.put(customRule.getTemplateId(), customRule.getId()); + } + + List customRuleParams = mapper.selectAllCustomRuleParameters(); + Multimap customRuleParamsByRuleId = ArrayListMultimap.create(); + for (RuleParameter customRuleParam : customRuleParams) { + customRuleParamsByRuleId.put(customRuleParam.getRuleId(), customRuleParam); + } + + // For each parameters of template rules, verify that each custom rules has the parameter + for (Integer templateRuleId : templateRuleParamsByRuleId.keySet()) { + for (RuleParameter templateRuleParam : templateRuleParamsByRuleId.get(templateRuleId)) { + // Each custom rule should have this parameter + for (Integer customRuleId : customRuleIdsByTemplateRuleId.get(templateRuleId)) { + if (!hasParameter(templateRuleParam.getName(), customRuleParamsByRuleId.get(customRuleId))) { + // Insert new custom rule parameter + mapper.insertRuleParameter(new RuleParameter() + .setRuleId(customRuleId) + .setRuleTemplateId(templateRuleId) + .setName(templateRuleParam.getName()) + .setDescription(templateRuleParam.getDescription()) + .setType(templateRuleParam.getType()) + ); + + // Update updated at date of custom rule in order to allow E/S indexation + mapper.updateRuleUpdateAt(customRuleId, new Date(system.now())); + } + } + } + } + + session.commit(); + } finally { + session.close(); + } + } + + private boolean hasParameter(final String parameter, Collection customRuleParams) { + return Iterables.any(customRuleParams, new Predicate() { + @Override + public boolean apply(@Nullable RuleParameter input) { + return input != null && input.getName().equals(parameter); + } + }); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java index 0a60c46eca9..aa17fafdffc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java @@ -33,6 +33,7 @@ import org.sonar.server.db.DbClient; import org.sonar.server.rule.index.RuleDoc; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; public class RuleCreator implements ServerComponent { @@ -168,20 +169,18 @@ public class RuleCreator implements ServerComponent { dbClient.ruleDao().insert(dbSession, ruleDto); for (RuleParamDto templateRuleParamDto : dbClient.ruleDao().findRuleParamsByRuleKey(dbSession, templateRuleDto.getKey())) { - String newRuleParam = newRule.parameter(templateRuleParamDto.getName()); - if (newRuleParam != null) { - createCustomRuleParams(newRuleParam, ruleDto, templateRuleParamDto, dbSession); - } + String customRuleParamValue = Strings.emptyToNull(newRule.parameter(templateRuleParamDto.getName())); + createCustomRuleParams(customRuleParamValue, ruleDto, templateRuleParamDto, dbSession); } return ruleKey; } - private void createCustomRuleParams(String param, RuleDto ruleDto, RuleParamDto templateRuleParam, DbSession dbSession){ + private void createCustomRuleParams(@Nullable String paramValue, RuleDto ruleDto, RuleParamDto templateRuleParam, DbSession dbSession){ RuleParamDto ruleParamDto = RuleParamDto.createFor(ruleDto) .setName(templateRuleParam.getName()) .setType(templateRuleParam.getType()) .setDescription(templateRuleParam.getDescription()) - .setDefaultValue(param); + .setDefaultValue(paramValue); dbClient.ruleDao().addRuleParam(dbSession, ruleDto, ruleParamDto); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdater.java index adeeabfa2bd..69f7f2a5db5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdater.java @@ -39,7 +39,12 @@ import org.sonar.core.technicaldebt.db.CharacteristicDto; import org.sonar.server.db.DbClient; import org.sonar.server.user.UserSession; -import java.util.*; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Set; + +import static com.google.common.collect.Lists.newArrayList; public class RuleUpdater implements ServerComponent { @@ -265,8 +270,7 @@ public class RuleUpdater implements ServerComponent { throw new IllegalStateException(String.format("Template %s of rule %s does not exist", customRule.getTemplateId(), customRule.getKey())); } - List templateRuleParams = dbClient.ruleDao().findRuleParamsByRuleKey(dbSession, templateRule.getKey()); - List paramKeys = new ArrayList(); + List paramKeys = newArrayList(); // Load active rules and its parameters in cache Multimap activeRules = ArrayListMultimap.create(); @@ -278,36 +282,33 @@ public class RuleUpdater implements ServerComponent { } } - // Browse custom rule parameters to update or delete them + // Browse custom rule parameters to create, update or delete them deleteOrUpdateParameters(dbSession, update, customRule, paramKeys, activeRules, activeRuleParams); - - // Browse template rule parameters to create new parameters - createNewParameters(dbSession, update, customRule, templateRuleParams, paramKeys, activeRules); } } private void deleteOrUpdateParameters(DbSession dbSession, RuleUpdate update, RuleDto customRule, List paramKeys, - Multimap activeRules, Multimap activeRuleParams) { + Multimap activeRules, Multimap activeRuleParams) { for (RuleParamDto ruleParamDto : dbClient.ruleDao().findRuleParamsByRuleKey(dbSession, update.getRuleKey())) { String key = ruleParamDto.getName(); - String value = update.parameter(key); - if (!Strings.isNullOrEmpty(value)) { - // Update rule param - ruleParamDto.setDefaultValue(value); - dbClient.ruleDao().updateRuleParam(dbSession, customRule, ruleParamDto); + String value = Strings.emptyToNull(update.parameter(key)); + + // Update rule param + ruleParamDto.setDefaultValue(value); + dbClient.ruleDao().updateRuleParam(dbSession, customRule, ruleParamDto); - // Update linked active rule params + if (value != null) { + // Update linked active rule params or create new one for (ActiveRuleDto activeRuleDto : activeRules.get(customRule)) { for (ActiveRuleParamDto activeRuleParamDto : activeRuleParams.get(activeRuleDto)) { if (activeRuleParamDto.getKey().equals(key)) { dbClient.activeRuleDao().updateParam(dbSession, activeRuleDto, activeRuleParamDto.setValue(value)); + } else { + dbClient.activeRuleDao().addParam(dbSession, activeRuleDto, ActiveRuleParamDto.createFor(ruleParamDto).setValue(value)); } } } } else { - // Delete rule param - dbClient.ruleDao().removeRuleParam(dbSession, customRule, ruleParamDto); - // Delete linked active rule params for (ActiveRuleDto activeRuleDto : activeRules.get(customRule)) { for (ActiveRuleParamDto activeRuleParamDto : activeRuleParams.get(activeRuleDto)) { @@ -321,31 +322,6 @@ public class RuleUpdater implements ServerComponent { } } - private void createNewParameters(DbSession dbSession, RuleUpdate update, RuleDto customRule, List templateRuleParams, List paramKeys, - Multimap activeRules) { - for (RuleParamDto templateRuleParam : templateRuleParams) { - String key = templateRuleParam.getName(); - if (!paramKeys.contains(key)) { - String value = update.parameter(key); - if (!Strings.isNullOrEmpty(value)) { - - // Create new param - RuleParamDto paramDto = RuleParamDto.createFor(customRule) - .setName(key) - .setDescription(templateRuleParam.getDescription()) - .setDefaultValue(value) - .setType(templateRuleParam.getType()); - dbClient.ruleDao().addRuleParam(dbSession, customRule, paramDto); - - // Create new active rule param - for (ActiveRuleDto activeRuleDto : activeRules.get(customRule)) { - dbClient.activeRuleDao().addParam(dbSession, activeRuleDto, ActiveRuleParamDto.createFor(paramDto).setValue(value)); - } - } - } - } - } - /** * Data loaded before update */ diff --git a/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest.java b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest.java new file mode 100644 index 00000000000..f1db25496b6 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest.java @@ -0,0 +1,78 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.db.migrations.v45; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.TestDatabase; +import org.sonar.server.db.DbClient; +import org.sonar.server.db.migrations.DatabaseMigration; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AddMissingCustomRuleParametersMigrationTest { + + @ClassRule + public static TestDatabase db = new TestDatabase().schema(AddMissingCustomRuleParametersMigrationTest.class, "schema.sql"); + + DatabaseMigration migration; + System2 system = mock(System2.class); + + @Before + public void setUp() throws Exception { + db.executeUpdateSql("truncate table rules"); + db.executeUpdateSql("truncate table rules_parameters"); + DbClient dbClient = new DbClient(db.database(), db.myBatis()); + migration = new AddMissingCustomRuleParametersMigration(dbClient, system); + when(system.now()).thenReturn(DateUtils.parseDate("2014-10-09").getTime()); + } + + @Test + public void execute() throws Exception { + db.prepareDbUnit(getClass(), "execute.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "execute-result.xml", "rules", "rules_parameters"); + } + + @Test + public void execute_when_custom_rule_have_no_parameter() throws Exception { + db.prepareDbUnit(getClass(), "execute_when_custom_rule_have_no_parameter.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "execute_when_custom_rule_have_no_parameter-result.xml", "rules", "rules_parameters"); + } + + @Test + public void no_changes() throws Exception { + db.prepareDbUnit(getClass(), "no_changes.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "no_changes.xml", "rules", "rules_parameters"); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorMediumTest.java index 8751f33e0c2..4eee09b2ffe 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorMediumTest.java @@ -112,6 +112,55 @@ public class RuleCreatorMediumTest { assertThat(param.getDefaultValue()).isEqualTo("a.*"); } + @Test + public void create_custom_rule_with_empty_parameter_value() throws Exception { + // insert template rule + RuleDto templateRule = createTemplateRule(); + + NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) + .setName("My custom") + .setHtmlDescription("Some description") + .setSeverity(Severity.MAJOR) + .setStatus(RuleStatus.READY) + .setParameters(ImmutableMap.of("regex", "")); + + RuleKey customRuleKey = creator.create(newRule); + dbSession.clearCache(); + + List params = db.ruleDao().findRuleParamsByRuleKey(dbSession, customRuleKey); + assertThat(params).hasSize(1); + + RuleParamDto param = params.get(0); + assertThat(param.getName()).isEqualTo("regex"); + assertThat(param.getDescription()).isEqualTo("Reg ex"); + assertThat(param.getType()).isEqualTo("STRING"); + assertThat(param.getDefaultValue()).isNull(); + } + + @Test + public void create_custom_rule_with_no_parameter_value() throws Exception { + // insert template rule + RuleDto templateRule = createTemplateRule(); + + NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) + .setName("My custom") + .setHtmlDescription("Some description") + .setSeverity(Severity.MAJOR) + .setStatus(RuleStatus.READY); + + RuleKey customRuleKey = creator.create(newRule); + dbSession.clearCache(); + + List params = db.ruleDao().findRuleParamsByRuleKey(dbSession, customRuleKey); + assertThat(params).hasSize(1); + + RuleParamDto param = params.get(0); + assertThat(param.getName()).isEqualTo("regex"); + assertThat(param.getDescription()).isEqualTo("Reg ex"); + assertThat(param.getType()).isEqualTo("STRING"); + assertThat(param.getDefaultValue()).isNull(); + } + @Test public void reactivate_custom_rule_if_already_exists_in_removed_status() throws Exception { String key = "CUSTOM_RULE"; @@ -193,42 +242,6 @@ public class RuleCreatorMediumTest { } } - @Test - public void not_fail_to_create_custom_rule_when_a_param_is_missing() throws Exception { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY); - - RuleKey customRuleKey = creator.create(newRule); - dbSession.clearCache(); - - List params = db.ruleDao().findRuleParamsByRuleKey(dbSession, customRuleKey); - assertThat(params).hasSize(0); - } - - @Test - public void fail_to_create_custom_rule_when_missing_key() throws Exception { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - try { - NewRule newRule = NewRule.createForCustomRule("", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - fail(); - } catch (Exception e) { - assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Custom key should be set"); - } - } - @Test public void fail_to_create_custom_rule_when_invalid_key() throws Exception { // insert template rule diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterMediumTest.java index 18fb0f0f6f7..c387a7b8851 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterMediumTest.java @@ -400,8 +400,10 @@ public class RuleUpdaterMediumTest { // Create template rule RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")); ruleDao.insert(dbSession, templateRule); - RuleParamDto templateRuleParam = RuleParamDto.createFor(templateRule).setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*"); - ruleDao.addRuleParam(dbSession, templateRule, templateRuleParam); + RuleParamDto templateRuleParam1 = RuleParamDto.createFor(templateRule).setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*"); + RuleParamDto templateRuleParam2 = RuleParamDto.createFor(templateRule).setName("format").setType("STRING").setDescription("Format"); + ruleDao.addRuleParam(dbSession, templateRule, templateRuleParam1); + ruleDao.addRuleParam(dbSession, templateRule, templateRuleParam2); // Create custom rule RuleDto customRule = RuleTesting.newCustomRule(templateRule) @@ -410,7 +412,8 @@ public class RuleUpdaterMediumTest { .setSeverity(Severity.MINOR) .setStatus(RuleStatus.BETA); ruleDao.insert(dbSession, customRule); - ruleDao.addRuleParam(dbSession, customRule, templateRuleParam.setDefaultValue("a.*")); + ruleDao.addRuleParam(dbSession, customRule, templateRuleParam1.setDefaultValue("a.*")); + ruleDao.addRuleParam(dbSession, customRule, templateRuleParam2.setDefaultValue(null)); dbSession.commit(); @@ -432,10 +435,45 @@ public class RuleUpdaterMediumTest { assertThat(customRuleReloaded.htmlDescription()).isEqualTo("New description"); assertThat(customRuleReloaded.severity()).isEqualTo("MAJOR"); assertThat(customRuleReloaded.status()).isEqualTo(RuleStatus.READY); - assertThat(customRuleReloaded.params()).hasSize(1); + assertThat(customRuleReloaded.params()).hasSize(2); + + assertThat(customRuleReloaded.params().get(0).defaultValue()).isEqualTo("b.*"); + assertThat(customRuleReloaded.params().get(1).defaultValue()).isNull(); + } + + @Test + public void update_custom_rule_with_empty_parameter() throws Exception { + // Create template rule + RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")); + ruleDao.insert(dbSession, templateRule); + RuleParamDto templateRuleParam = RuleParamDto.createFor(templateRule).setName("regex").setType("STRING").setDescription("Reg ex"); + ruleDao.addRuleParam(dbSession, templateRule, templateRuleParam); + // Create custom rule + RuleDto customRule = RuleTesting.newCustomRule(templateRule) + .setName("Old name") + .setDescription("Old description") + .setSeverity(Severity.MINOR) + .setStatus(RuleStatus.BETA); + ruleDao.insert(dbSession, customRule); + ruleDao.addRuleParam(dbSession, customRule, templateRuleParam); + + dbSession.commit(); + + // Update custom rule without setting a value for the parameter + RuleUpdate update = RuleUpdate.createForCustomRule(customRule.getKey()) + .setName("New name") + .setMarkdownDescription("New description") + .setSeverity("MAJOR") + .setStatus(RuleStatus.READY); + updater.update(update, UserSession.get()); + + dbSession.clearCache(); + + // Verify custom rule is updated + Rule customRuleReloaded = ruleIndex.getByKey(customRule.getKey()); RuleParam param = customRuleReloaded.params().get(0); - assertThat(param.defaultValue()).isEqualTo("b.*"); + assertThat(param.defaultValue()).isNull(); } @Test @@ -450,11 +488,12 @@ public class RuleUpdaterMediumTest { RuleParamDto templateRuleParam3 = RuleParamDto.createFor(templateRule).setName("message").setType("STRING").setDescription("message"); ruleDao.addRuleParam(dbSession, templateRule, templateRuleParam3); - // Create custom rule with 2 parameters + // Create custom rule RuleDto customRule = RuleTesting.newCustomRule(templateRule).setSeverity(Severity.MAJOR).setLanguage("xoo"); ruleDao.insert(dbSession, customRule); ruleDao.addRuleParam(dbSession, customRule, templateRuleParam1.setDefaultValue("a.*")); ruleDao.addRuleParam(dbSession, customRule, templateRuleParam2.setDefaultValue("txt")); + ruleDao.addRuleParam(dbSession, customRule, templateRuleParam3); // Create a quality profile QualityProfileDto profileDto = QProfileTesting.newXooP1(); @@ -476,12 +515,13 @@ public class RuleUpdaterMediumTest { // Verify custom rule parameters has been updated Rule customRuleReloaded = ruleIndex.getByKey(customRule.getKey()); - assertThat(customRuleReloaded.params()).hasSize(2); + assertThat(customRuleReloaded.params()).hasSize(3); assertThat(customRuleReloaded.param("regex")).isNotNull(); assertThat(customRuleReloaded.param("regex").defaultValue()).isEqualTo("b.*"); assertThat(customRuleReloaded.param("message")).isNotNull(); assertThat(customRuleReloaded.param("message").defaultValue()).isEqualTo("a message"); - assertThat(customRuleReloaded.param("format")).isNull(); + assertThat(customRuleReloaded.param("format")).isNotNull(); + assertThat(customRuleReloaded.param("format").defaultValue()).isNull(); RuleParam param = customRuleReloaded.params().get(0); assertThat(param.defaultValue()).isEqualTo("b.*"); @@ -490,8 +530,8 @@ public class RuleUpdaterMediumTest { ActiveRule activeRule = tester.get(ActiveRuleIndex.class).getByKey(ActiveRuleKey.of(profileDto.getKey(), customRule.getKey())); assertThat(activeRule.params()).hasSize(2); assertThat(activeRule.params().get("regex")).isEqualTo("b.*"); - assertThat(activeRule.params().get("format")).isNull(); assertThat(activeRule.params().get("message")).isEqualTo("a message"); + assertThat(activeRule.params().get("format")).isNull(); // Verify that severity has not changed assertThat(activeRule.severity()).isEqualTo(Severity.BLOCKER); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute-result.xml new file mode 100644 index 00000000000..a4b4ab4411b --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute-result.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute.xml new file mode 100644 index 00000000000..58b9732cf61 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml new file mode 100644 index 00000000000..76c7c186008 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml new file mode 100644 index 00000000000..dd676e5d869 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/no_changes.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/no_changes.xml new file mode 100644 index 00000000000..ed072ad9461 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/no_changes.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/schema.sql b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/schema.sql new file mode 100644 index 00000000000..0bf38617681 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v45/AddMissingCustomRuleParametersMigrationTest/schema.sql @@ -0,0 +1,40 @@ +CREATE TABLE "RULES_PARAMETERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "RULE_ID" INTEGER NOT NULL, + "NAME" VARCHAR(128) NOT NULL, + "PARAM_TYPE" VARCHAR(512) NOT NULL, + "DEFAULT_VALUE" VARCHAR(4000), + "DESCRIPTION" VARCHAR(4000) +); + +CREATE TABLE "RULES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PLUGIN_RULE_KEY" VARCHAR(200) NOT NULL, + "PLUGIN_NAME" VARCHAR(255) NOT NULL, + "DESCRIPTION" VARCHAR(16777215), + "DESCRIPTION_FORMAT" VARCHAR(20), + "PRIORITY" INTEGER, + "IS_TEMPLATE" BOOLEAN DEFAULT FALSE, + "TEMPLATE_ID" INTEGER, + "PLUGIN_CONFIG_KEY" VARCHAR(500), + "NAME" VARCHAR(200), + "STATUS" VARCHAR(40), + "LANGUAGE" VARCHAR(20), + "NOTE_DATA" CLOB(2147483647), + "NOTE_USER_LOGIN" VARCHAR(255), + "NOTE_CREATED_AT" TIMESTAMP, + "NOTE_UPDATED_AT" TIMESTAMP, + "CHARACTERISTIC_ID" INTEGER, + "DEFAULT_CHARACTERISTIC_ID" INTEGER, + "REMEDIATION_FUNCTION" VARCHAR(20), + "DEFAULT_REMEDIATION_FUNCTION" VARCHAR(20), + "REMEDIATION_COEFF" VARCHAR(20), + "DEFAULT_REMEDIATION_COEFF" VARCHAR(20), + "REMEDIATION_OFFSET" VARCHAR(20), + "DEFAULT_REMEDIATION_OFFSET" VARCHAR(20), + "EFFORT_TO_FIX_DESCRIPTION" VARCHAR(4000), + "TAGS" VARCHAR(4000), + "SYSTEM_TAGS" VARCHAR(4000), + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP +); diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/601_add_missing_custom_rule_parameters.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/601_add_missing_custom_rule_parameters.rb new file mode 100644 index 00000000000..55d04675c93 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/601_add_missing_custom_rule_parameters.rb @@ -0,0 +1,30 @@ +# +# SonarQube, open source software quality management tool. +# Copyright (C) 2008-2014 SonarSource +# mailto:contact AT sonarsource DOT com +# +# SonarQube 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. +# +# SonarQube 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. +# + +# +# SonarQube 4.5.1 +# SONAR-5575 +# +class AddMissingCustomRuleParameters < ActiveRecord::Migration + + def self.up + execute_java_migration 'org.sonar.server.db.migrations.v45.AddMissingCustomRuleParametersMigration' + end +end diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java index dcb5e436527..af91a6ae928 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java @@ -33,7 +33,7 @@ import java.util.List; */ public class DatabaseVersion implements BatchComponent, ServerComponent { - public static final int LAST_VERSION = 600; + public static final int LAST_VERSION = 601; public static enum Status { UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index 3e9c9d2f5f4..58cf793f0e1 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -53,6 +53,7 @@ import org.sonar.core.notification.db.NotificationQueueDto; import org.sonar.core.notification.db.NotificationQueueMapper; import org.sonar.core.permission.*; import org.sonar.core.persistence.migration.v44.Migration44Mapper; +import org.sonar.core.persistence.migration.v45.Migration45Mapper; import org.sonar.core.properties.PropertiesMapper; import org.sonar.core.properties.PropertyDto; import org.sonar.core.purge.PurgeMapper; @@ -170,7 +171,8 @@ public class MyBatis implements BatchComponent, ServerComponent { org.sonar.api.database.model.MeasureMapper.class, SnapshotDataMapper.class, SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class, NotificationQueueMapper.class, CharacteristicMapper.class, GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class, - MeasureMapper.class, MetricMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, ProjectQgateAssociationMapper.class + MeasureMapper.class, MetricMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, ProjectQgateAssociationMapper.class, + Migration45Mapper.class }; loadMappers(conf, mappers); configureLogback(mappers); diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Migration45Mapper.java b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Migration45Mapper.java new file mode 100644 index 00000000000..4f78491095a --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Migration45Mapper.java @@ -0,0 +1,61 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.core.persistence.migration.v45; + +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Select; + +import java.util.Date; +import java.util.List; + +public interface Migration45Mapper { + + @Select("SELECT rules_parameters.id, rules_parameters.rule_id as \"ruleId\", rules_parameters.name as \"name\", rules_parameters.param_type as \"type\", " + + " rules_parameters.default_value as \"defaultValue\", rules_parameters.description, rules.template_id as \"ruleTemplateId\" " + + "FROM rules_parameters " + + " INNER JOIN rules ON rules.id = rules_parameters.rule_id " + + "WHERE rules.is_template = ${_true}") + @Result(javaType = RuleParameter.class) + List selectAllTemplateRuleParameters(); + + @Select("SELECT rules_parameters.id, rules_parameters.rule_id as \"ruleId\", rules_parameters.name as \"name\", rules_parameters.param_type as \"type\", " + + " rules_parameters.default_value as \"defaultValue\", rules_parameters.description, rules.template_id as \"ruleTemplateId\" " + + "FROM rules_parameters " + + " INNER JOIN rules ON rules.id = rules_parameters.rule_id " + + "WHERE rules.template_id IS NOT NULL") + @Result(javaType = RuleParameter.class) + List selectAllCustomRuleParameters(); + + @Select("SELECT id, plugin_rule_key as \"ruleKey\", plugin_name as \"repositoryKey\", is_template as \"isTemplate\", template_id as \"templateId\"" + + "FROM rules " + + "WHERE rules.template_id IS NOT NULL") + @Result(javaType = Rule.class) + List selectAllCustomRules(); + + @Insert("INSERT INTO rules_parameters (rule_id, name, param_type, default_value, description)" + + " VALUES (#{ruleId}, #{name}, #{type}, #{defaultValue}, #{description})") + void insertRuleParameter(RuleParameter ruleParameter); + + @Insert("UPDATE rules SET updated_at=#{date} WHERE id=#{id}") + void updateRuleUpdateAt(@Param("id") Integer ruleId, @Param("date") Date updatedAt); + +} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Rule.java b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Rule.java new file mode 100644 index 00000000000..a54d2f3cf61 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/Rule.java @@ -0,0 +1,113 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.core.persistence.migration.v45; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +/** + * SONAR-5575 + *

+ * Used in the Active Record Migration 601. + * + * @since 4.5 + */ +public final class Rule { + + private Integer id; + private String repositoryKey; + private String ruleKey; + private boolean isTemplate; + private Integer templateId; + + public Integer getId() { + return id; + } + + public Rule setId(Integer id) { + this.id = id; + return this; + } + + public String getRepositoryKey() { + return repositoryKey; + } + + public Rule setRepositoryKey(String repositoryKey) { + this.repositoryKey = repositoryKey; + return this; + } + + public String getRuleKey() { + return ruleKey; + } + + public Rule setRuleKey(String ruleKey) { + this.ruleKey = ruleKey; + return this; + } + + public boolean isTemplate() { + return isTemplate; + } + + public Rule setIsTemplate(boolean isTemplate) { + this.isTemplate = isTemplate; + return this; + } + + @CheckForNull + public Integer getTemplateId() { + return templateId; + } + + public Rule setTemplateId(@Nullable Integer templateId) { + this.templateId = templateId; + return this; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Rule)) { + return false; + } + if (this == obj) { + return true; + } + Rule other = (Rule) obj; + return new EqualsBuilder() + .append(repositoryKey, other.getRepositoryKey()) + .append(ruleKey, other.getRuleKey()) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(repositoryKey) + .append(ruleKey) + .toHashCode(); + } + + +} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/RuleParameter.java b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/RuleParameter.java new file mode 100644 index 00000000000..c930518ab81 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/RuleParameter.java @@ -0,0 +1,114 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.core.persistence.migration.v45; + +import org.apache.commons.lang.builder.ReflectionToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +/** + * SONAR-5575 + *

+ * Used in the Active Record Migration 601. + * + * @since 4.5 + */ +public class RuleParameter { + + private Integer id; + private Integer ruleId; + private Integer ruleTemplateId; + private String name; + private String type; + private String defaultValue; + private String description; + + public Integer getId() { + return id; + } + + public RuleParameter setId(Integer id) { + this.id = id; + return this; + } + + public Integer getRuleId() { + return ruleId; + } + + public RuleParameter setRuleId(Integer ruleId) { + this.ruleId = ruleId; + return this; + } + + @CheckForNull + public Integer getRuleTemplateId() { + return ruleTemplateId; + } + + public RuleParameter setRuleTemplateId(@Nullable Integer ruleTemplateId) { + this.ruleTemplateId = ruleTemplateId; + return this; + } + + public String getName() { + return name; + } + + public RuleParameter setName(String name) { + this.name = name; + return this; + } + + public String getType() { + return type; + } + + public RuleParameter setType(String type) { + this.type = type; + return this; + } + + @CheckForNull + public String getDefaultValue() { + return defaultValue; + } + + public RuleParameter setDefaultValue(@Nullable String defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + public String getDescription() { + return description; + } + + public RuleParameter setDescription(String description) { + this.description = description; + return this; + } + + @Override + public String toString() { + return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString(); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/package-info.java b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/package-info.java new file mode 100644 index 00000000000..4e661d78b28 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v45/package-info.java @@ -0,0 +1,23 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.core.persistence.migration.v45; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-core/src/main/java/org/sonar/core/rule/RuleParamDto.java b/sonar-core/src/main/java/org/sonar/core/rule/RuleParamDto.java index 7d1436974bc..ddddb819bed 100644 --- a/sonar-core/src/main/java/org/sonar/core/rule/RuleParamDto.java +++ b/sonar-core/src/main/java/org/sonar/core/rule/RuleParamDto.java @@ -23,6 +23,9 @@ package org.sonar.core.rule; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + public class RuleParamDto { private Integer id; @@ -68,11 +71,12 @@ public class RuleParamDto { return this; } + @CheckForNull public String getDefaultValue() { return defaultValue; } - public RuleParamDto setDefaultValue(String defaultValue) { + public RuleParamDto setDefaultValue(@Nullable String defaultValue) { this.defaultValue = defaultValue; return this; } diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/migration/v45/Migration45Mapper.xml b/sonar-core/src/main/resources/org/sonar/core/persistence/migration/v45/Migration45Mapper.xml new file mode 100644 index 00000000000..ea7778ed475 --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/migration/v45/Migration45Mapper.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql index 687099904a9..53b8dcc9d12 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql @@ -255,6 +255,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('582'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('583'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('584'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('600'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('601'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; -- 2.39.5