From 31af09b42f8aafb2a56522e8670b574603cd9eee Mon Sep 17 00:00:00 2001 From: simonbrandhof Date: Thu, 3 Feb 2011 17:37:34 +0100 Subject: [PATCH] SONAR-2094 Do not delete ACTIVE_RULES rows when rules are disabled --- .../java/org/sonar/batch/ProjectBatch.java | 1 - .../main/java/org/sonar/jpa/dao/RulesDao.java | 51 --------- .../java/org/sonar/jpa/dao/RulesDaoTest.java | 51 --------- .../shouldAddActiveRulesToProfile-result.xml | 19 ---- .../shouldAddActiveRulesToProfile.xml | 13 --- .../shouldSynchronizeRuleOfActiveRule.xml | 13 --- .../org/sonar/api/database/daos/RulesDao.java | 100 ------------------ .../org/sonar/api/profiles/RulesProfile.java | 92 +++++++++++----- .../java/org/sonar/api/rules/ActiveRule.java | 6 ++ .../server/configuration/ProfilesManager.java | 6 +- .../org/sonar/server/platform/Platform.java | 2 +- .../startup/ActivateDefaultProfiles.java | 2 +- .../sonar/server/startup/EnableProfiles.java | 79 ++++++++++++++ .../sonar/server/startup/RegisterRules.java | 20 +--- .../WEB-INF/app/helpers/profiles_helper.rb | 2 +- .../app/models/active_rule_parameter.rb | 30 +++--- .../main/webapp/WEB-INF/app/models/profile.rb | 4 + .../WEB-INF/app/views/profiles/index.html.erb | 2 +- .../configuration/ProfilesBackupTest.java | 4 +- .../server/startup/EnableProfilesTest.java | 63 +++++++++++ ...bleProfilesWithMissingLanguages-result.xml | 9 ++ ...uldDisableProfilesWithMissingLanguages.xml | 7 ++ ...nableProfilesWithKnownLanguages-result.xml | 11 ++ ...shouldEnableProfilesWithKnownLanguages.xml | 7 ++ .../src/main/java/foo/AnonymousClass.java | 9 +- 25 files changed, 285 insertions(+), 318 deletions(-) delete mode 100644 sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile-result.xml delete mode 100644 sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile.xml delete mode 100644 sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldSynchronizeRuleOfActiveRule.xml delete mode 100644 sonar-deprecated/src/main/java/org/sonar/api/database/daos/RulesDao.java create mode 100644 sonar-server/src/main/java/org/sonar/server/startup/EnableProfiles.java create mode 100644 sonar-server/src/test/java/org/sonar/server/startup/EnableProfilesTest.java create mode 100644 sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages-result.xml create mode 100644 sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages.xml create mode 100644 sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages-result.xml create mode 100644 sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages.xml diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java index a0bb1c58dce..9f0e0c4ddc3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java @@ -78,7 +78,6 @@ public class ProjectBatch { batchContainer.as(Characteristics.CACHE) .addComponent(globalContainer.getComponent(DefaultResourcePersister.class).getSnapshot(project)); - batchContainer.as(Characteristics.CACHE).addComponent(org.sonar.api.database.daos.RulesDao.class); batchContainer.as(Characteristics.CACHE).addComponent(org.sonar.api.database.daos.MeasuresDao.class); batchContainer.as(Characteristics.CACHE).addComponent(ProfilesDao.class); batchContainer.as(Characteristics.CACHE).addComponent(AsyncMeasuresDao.class); diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/RulesDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/RulesDao.java index 8cb5151c7f5..b90e8afe852 100644 --- a/sonar-core/src/main/java/org/sonar/jpa/dao/RulesDao.java +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/RulesDao.java @@ -57,60 +57,9 @@ public class RulesDao extends BaseDao { return getSession().getSingleResult(Rule.class, "key", ruleKey, "pluginName", repositoryKey, "enabled", true); } - public Long countRules(List plugins) { - return (Long) getSession().createQuery( - "SELECT COUNT(r) FROM Rule r WHERE r.pluginName IN (:pluginNames) AND r.enabled=true"). - setParameter("pluginNames", plugins). - getSingleResult(); - } - - public List getRuleParams() { - return getSession().getResults(RuleParam.class); - } public RuleParam getRuleParam(Rule rule, String paramKey) { return getSession().getSingleResult(RuleParam.class, "rule", rule, "key", paramKey); } - public void addActiveRulesToProfile(List activeRules, int profileId, String pluginKey) { - RulesProfile rulesProfile = getProfileById(profileId); - for (ActiveRule activeRule : activeRules) { - synchronizeRuleOfActiveRule(activeRule, pluginKey); - activeRule.setRulesProfile(rulesProfile); - getSession().save(activeRule); - } - } - - public List getViolations(Snapshot snapshot) { - return getSession().getResults(RuleFailureModel.class, "snapshotId", snapshot.getId()); - } - - public void synchronizeRuleOfActiveRule(ActiveRule activeRule, String pluginKey) { - Rule rule = activeRule.getRule(); - Rule ruleFromDataBase = getRuleByKey(pluginKey, rule.getKey()); - activeRule.setRule(ruleFromDataBase); - List ruleParamsFromDataBase = getRuleParams(); - for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) { - boolean found = false; - Iterator iterator = ruleParamsFromDataBase.iterator(); - while (iterator.hasNext() && !found) { - RuleParam ruleParamFromDataBase = iterator.next(); - if (isRuleParamEqual(activeRuleParam.getRuleParam(), ruleParamFromDataBase, rule.getKey(), pluginKey)) { - activeRuleParam.setRuleParam(ruleParamFromDataBase); - found = true; - } - } - } - } - - public boolean isRuleParamEqual(RuleParam ruleParam, RuleParam ruleParamFromDatabase, String ruleKey, String pluginKey) { - return ruleParam.getKey().equals(ruleParamFromDatabase.getKey()) && - ruleKey.equals(ruleParamFromDatabase.getRule().getKey()) && - ruleParamFromDatabase.getRule().getPluginName().equals(pluginKey); - } - - public RulesProfile getProfileById(int profileId) { - return getSession().getEntityManager().getReference(RulesProfile.class, profileId); - } - } diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/RulesDaoTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/RulesDaoTest.java index 4656c20bb1b..7d1b0e97a64 100644 --- a/sonar-core/src/test/java/org/sonar/jpa/dao/RulesDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/jpa/dao/RulesDaoTest.java @@ -65,55 +65,4 @@ public class RulesDaoTest extends AbstractDbUnitTestCase { assertThat(rule2, nullValue()); } - @Test - public void shouldGetRuleParams() { - setupData("shouldGetRuleParams"); - - List ruleParams = rulesDao.getRuleParams(); - - assertThat(ruleParams.size(), is(3)); - } - - @Test - public void shouldSynchronizeRuleOfActiveRule() { - setupData("shouldSynchronizeRuleOfActiveRule"); - Rule rule = new Rule(null, "other key", (String) null, null, null); - RuleParam ruleParam = new RuleParam(null, "rule1_param1", null, null); - rule.setParams(Arrays.asList(ruleParam)); - ActiveRule activeRule = new ActiveRule(null, rule, null); - ActiveRuleParam activeRuleParam = new ActiveRuleParam(activeRule, ruleParam, null); - activeRule.setActiveRuleParams(Arrays.asList(activeRuleParam)); - - rulesDao.synchronizeRuleOfActiveRule(activeRule, "plugin"); - - assertThat(activeRule.getRule().getId(), notNullValue()); - assertThat(activeRule.getActiveRuleParams().size(), is(1)); - } - - @Test - public void shouldGetRulesProfileById() { - RulesProfile rulesProfile = new RulesProfile("profil", "java", true, true); - getSession().save(rulesProfile); - - RulesProfile rulesProfileExpected = rulesDao.getProfileById(rulesProfile.getId()); - - assertThat(rulesProfileExpected, is(rulesProfile)); - } - - @Test - public void shouldAddActiveRulesToProfile() { - setupData("shouldAddActiveRulesToProfile"); - - Rule rule = new Rule("rule1", "key1", "config1", null, null); - RuleParam ruleParam = new RuleParam(null, "param1", null, null); - rule.setParams(Arrays.asList(ruleParam)); - - ActiveRule activeRule = new ActiveRule(null, rule, RulePriority.MAJOR); - ActiveRuleParam activeRuleParam = new ActiveRuleParam(activeRule, ruleParam, "20"); - activeRule.setActiveRuleParams(Arrays.asList(activeRuleParam)); - rulesDao.addActiveRulesToProfile(Arrays.asList(activeRule), 1, "plugin"); - - checkTables("shouldAddActiveRulesToProfile", "rules", "active_rules", "rules_profiles"); - } - } diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile-result.xml deleted file mode 100644 index cecf13ba8e1..00000000000 --- a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile-result.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile.xml deleted file mode 100644 index 0851c7441a0..00000000000 --- a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldSynchronizeRuleOfActiveRule.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldSynchronizeRuleOfActiveRule.xml deleted file mode 100644 index 94227fff982..00000000000 --- a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldSynchronizeRuleOfActiveRule.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/sonar-deprecated/src/main/java/org/sonar/api/database/daos/RulesDao.java b/sonar-deprecated/src/main/java/org/sonar/api/database/daos/RulesDao.java deleted file mode 100644 index bc47708c276..00000000000 --- a/sonar-deprecated/src/main/java/org/sonar/api/database/daos/RulesDao.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.api.database.daos; - -import org.sonar.api.database.model.RuleFailureModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.rules.ActiveRule; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleParam; -import org.sonar.api.rules.RulesCategory; - -import java.util.Collections; -import java.util.List; - -/** - * @deprecated since 2.3 - */ -@Deprecated -public class RulesDao { - - private org.sonar.jpa.dao.RulesDao target; - - public RulesDao(org.sonar.jpa.dao.RulesDao target) { - this.target = target; - } - - public List getRules() { - return target.getRules(); - } - - public List getRulesByPlugin(String pluginKey) { - return target.getRulesByPlugin(pluginKey); - } - - public List getRulesByCategory(RulesCategory categ) { - return Collections.emptyList(); - } - - public Rule getRuleByKey(String pluginKey, String ruleKey) { - return target.getRuleByKey(pluginKey, ruleKey); - } - - public Long countRules(List plugins, String categoryName) { - return target.countRules(plugins); - } - - public List getCategories() { - return Collections.emptyList(); - } - - public RulesCategory getCategory(String key) { - return null; - } - - public List getRuleParams() { - return target.getRuleParams(); - } - - public RuleParam getRuleParam(Rule rule, String paramKey) { - return target.getRuleParam(rule, paramKey); - } - - public void addActiveRulesToProfile(List activeRules, int profileId, String pluginKey) { - target.addActiveRulesToProfile(activeRules, profileId, pluginKey); - } - - public List getViolations(Snapshot snapshot) { - return target.getViolations(snapshot); - } - - public void synchronizeRuleOfActiveRule(ActiveRule activeRule, String pluginKey) { - target.synchronizeRuleOfActiveRule(activeRule, pluginKey); - } - - public boolean isRuleParamEqual(RuleParam ruleParam, RuleParam ruleParamFromDatabase, String ruleKey, String pluginKey) { - return target.isRuleParamEqual(ruleParam, ruleParamFromDatabase, ruleKey, pluginKey); - } - - public RulesProfile getProfileById(int profileId) { - return target.getProfileById(profileId); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java index 4a5cfa80b62..9427f0c1765 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java @@ -19,6 +19,7 @@ */ package org.sonar.api.profiles; +import com.google.common.collect.Lists; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Transformer; import org.apache.commons.lang.StringUtils; @@ -78,14 +79,14 @@ public class RulesProfile implements Cloneable { @Column(name = "parent_name", updatable = true, nullable = true) private String parentName; - @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }) - private List activeRules = new ArrayList(); + @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}) + private List activeRules = Lists.newArrayList(); - @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }) - private List alerts = new ArrayList(); + @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}) + private List alerts = Lists.newArrayList(); @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY) - private List projects = new ArrayList(); + private List projects = Lists.newArrayList(); /** * @deprecated use the factory method create() @@ -101,9 +102,9 @@ public class RulesProfile implements Cloneable { public RulesProfile(String name, String language) { this.name = name; this.language = language; - this.activeRules = new ArrayList(); - this.alerts = new ArrayList(); - this.projects = new ArrayList(); + this.activeRules = Lists.newArrayList(); + this.alerts = Lists.newArrayList(); + this.projects = Lists.newArrayList(); } /** @@ -139,7 +140,33 @@ public class RulesProfile implements Cloneable { * @return the list of active rules */ public List getActiveRules() { - return activeRules; + return getActiveRules(false); + } + + /** + * @return the list of active rules + */ + public List getActiveRules(boolean acceptDisabledRules) { + if (acceptDisabledRules) { + return activeRules; + } + List result = Lists.newArrayList(); + for (ActiveRule activeRule : activeRules) { + if (activeRule.isEnabled()) { + result.add(activeRule); + } + } + return result; + } + + public RulesProfile removeActiveRule(ActiveRule activeRule) { + activeRules.remove(activeRule); + return this; + } + + public RulesProfile addActiveRule(ActiveRule activeRule) { + activeRules.add(activeRule); + return this; } /** @@ -184,7 +211,7 @@ public class RulesProfile implements Cloneable { } public boolean isEnabled() { - return enabled==Boolean.TRUE; + return enabled == Boolean.TRUE; } public RulesProfile setEnabled(Boolean b) { @@ -209,7 +236,7 @@ public class RulesProfile implements Cloneable { /** * For internal use only. - * + * * @since 2.5 */ public String getParentName() { @@ -218,7 +245,7 @@ public class RulesProfile implements Cloneable { /** * For internal use only. - * + * * @since 2.5 */ public void setParentName(String parentName) { @@ -254,12 +281,13 @@ public class RulesProfile implements Cloneable { } /** - * @return the list of active rules for a given priority + * Note: disabled rules are excluded. + * @return the list of active rules for a given severity */ - public List getActiveRules(RulePriority priority) { - List result = new ArrayList(); - for (ActiveRule activeRule : getActiveRules()) { - if (activeRule.getSeverity().equals(priority)) { + public List getActiveRules(RulePriority severity) { + List result = Lists.newArrayList(); + for (ActiveRule activeRule : activeRules) { + if (activeRule.getSeverity().equals(severity) && activeRule.isEnabled()) { result.add(activeRule); } } @@ -274,10 +302,14 @@ public class RulesProfile implements Cloneable { return getActiveRulesByRepository(repositoryKey); } + /** + * Get the active rules of a specific repository. + * Only enabled rules are selected. Disabled rules are excluded. + */ public List getActiveRulesByRepository(String repositoryKey) { - List result = new ArrayList(); - for (ActiveRule activeRule : getActiveRules()) { - if (repositoryKey.equals(activeRule.getRepositoryKey())) { + List result = Lists.newArrayList(); + for (ActiveRule activeRule : activeRules) { + if (repositoryKey.equals(activeRule.getRepositoryKey()) && activeRule.isEnabled()) { result.add(activeRule); } } @@ -285,26 +317,34 @@ public class RulesProfile implements Cloneable { } /** + * Note: disabled rules are excluded. * @return an active rule from a plugin key and a rule key if the rule is activated, null otherwise */ public ActiveRule getActiveRule(String repositoryKey, String ruleKey) { - for (ActiveRule activeRule : getActiveRules()) { - if (StringUtils.equals(activeRule.getRepositoryKey(), repositoryKey) && StringUtils.equals(activeRule.getRuleKey(), ruleKey)) { + for (ActiveRule activeRule : activeRules) { + if (StringUtils.equals(activeRule.getRepositoryKey(), repositoryKey) && StringUtils.equals(activeRule.getRuleKey(), ruleKey) && activeRule.isEnabled()) { return activeRule; } } return null; } + /** + * Note: disabled rules are excluded. + */ public ActiveRule getActiveRuleByConfigKey(String repositoryKey, String configKey) { - for (ActiveRule activeRule : getActiveRules()) { - if (StringUtils.equals(activeRule.getRepositoryKey(), repositoryKey) && StringUtils.equals(activeRule.getConfigKey(), configKey)) { + for (ActiveRule activeRule : activeRules) { + if (StringUtils.equals(activeRule.getRepositoryKey(), repositoryKey) && StringUtils.equals(activeRule.getConfigKey(), configKey) && activeRule.isEnabled()) { return activeRule; } } return null; } + /** + * Note: disabled rules are excluded. + */ + public ActiveRule getActiveRule(Rule rule) { return getActiveRule(rule.getRepositoryKey(), rule.getKey()); } @@ -344,8 +384,8 @@ public class RulesProfile implements Cloneable { clone.setDefaultProfile(getDefaultProfile()); clone.setProvided(getProvided()); clone.setParentName(getParentName()); - if (CollectionUtils.isNotEmpty(getActiveRules())) { - clone.setActiveRules(new ArrayList(CollectionUtils.collect(getActiveRules(), new Transformer() { + if (CollectionUtils.isNotEmpty(activeRules)) { + clone.setActiveRules(new ArrayList(CollectionUtils.collect(activeRules, new Transformer() { public Object transform(Object input) { return ((ActiveRule) input).clone(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java index 8fe4e0aea91..5fe233feb0d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java @@ -284,4 +284,10 @@ public class ActiveRule implements Cloneable { return clone; } + /** + * @since 2.6 + */ + public boolean isEnabled() { + return getRule().isEnabled(); + } } diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesManager.java b/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesManager.java index 96f55348b17..02564ab0475 100644 --- a/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesManager.java +++ b/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesManager.java @@ -163,7 +163,7 @@ public class ProfilesManager extends BaseDao { activeRule = (ActiveRule) parentActiveRule.clone(); activeRule.setRulesProfile(profile); activeRule.setInheritance(ActiveRule.INHERITED); - profile.getActiveRules().add(activeRule); + profile.addActiveRule(activeRule); getSession().saveWithoutFlush(activeRule); for (RulesProfile child : getChildren(profile)) { @@ -188,7 +188,7 @@ public class ProfilesManager extends BaseDao { activeRule = (ActiveRule) parentActiveRule.clone(); activeRule.setRulesProfile(profile); activeRule.setInheritance(ActiveRule.INHERITED); - profile.getActiveRules().add(activeRule); + profile.addActiveRule(activeRule); getSession().saveWithoutFlush(activeRule); for (RulesProfile child : getChildren(profile)) { @@ -227,7 +227,7 @@ public class ProfilesManager extends BaseDao { } private void removeActiveRule(RulesProfile profile, ActiveRule activeRule) { - profile.getActiveRules().remove(activeRule); + profile.removeActiveRule(activeRule); getSession().removeWithoutFlush(activeRule); } diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 3850ae6d799..1d0ab614b67 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -163,7 +163,6 @@ public final class Platform { servicesContainer.as(Characteristics.CACHE).addComponent(Views.class); servicesContainer.as(Characteristics.CACHE).addComponent(CodeColorizers.class); servicesContainer.as(Characteristics.NO_CACHE).addComponent(RulesDao.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(org.sonar.api.database.daos.RulesDao.class); servicesContainer.as(Characteristics.NO_CACHE).addComponent(MeasuresDao.class); servicesContainer.as(Characteristics.NO_CACHE).addComponent(org.sonar.api.database.daos.MeasuresDao.class); servicesContainer.as(Characteristics.NO_CACHE).addComponent(ProfilesDao.class); @@ -200,6 +199,7 @@ public final class Platform { startupContainer.as(Characteristics.CACHE).addComponent(RegisterMetrics.class); startupContainer.as(Characteristics.CACHE).addComponent(RegisterRules.class); startupContainer.as(Characteristics.CACHE).addComponent(RegisterProvidedProfiles.class); + startupContainer.as(Characteristics.CACHE).addComponent(EnableProfiles.class); startupContainer.as(Characteristics.CACHE).addComponent(ActivateDefaultProfiles.class); startupContainer.as(Characteristics.CACHE).addComponent(JdbcDriverDeployer.class); startupContainer.as(Characteristics.CACHE).addComponent(ServerMetadataPersister.class); diff --git a/sonar-server/src/main/java/org/sonar/server/startup/ActivateDefaultProfiles.java b/sonar-server/src/main/java/org/sonar/server/startup/ActivateDefaultProfiles.java index 38b87772f90..b608d35cbf0 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/ActivateDefaultProfiles.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/ActivateDefaultProfiles.java @@ -62,7 +62,7 @@ public final class ActivateDefaultProfiles { Iterator iterator = profiles.iterator(); while (iterator.hasNext() && !oneProfileIsActivated) { RulesProfile profile = iterator.next(); - oneProfileIsActivated |= profile.getDefaultProfile(); + oneProfileIsActivated = profile.getDefaultProfile(); if (RulesProfile.SONAR_WAY_NAME.equals(profile.getName())) { profileToActivate = profile; } diff --git a/sonar-server/src/main/java/org/sonar/server/startup/EnableProfiles.java b/sonar-server/src/main/java/org/sonar/server/startup/EnableProfiles.java new file mode 100644 index 00000000000..9dc2fcccf81 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/startup/EnableProfiles.java @@ -0,0 +1,79 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.startup; + +import com.google.common.collect.Sets; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Language; +import org.sonar.api.utils.TimeProfiler; +import org.sonar.jpa.session.DatabaseSessionFactory; + +import javax.persistence.Query; +import java.util.Set; + +/** + * @since 2.6 + */ +public final class EnableProfiles { + + private Language[] languages; + private DatabaseSessionFactory sessionFactory; + + // NOSONAR the parameter registerProfilesBefore is used to define the execution order of startup components + public EnableProfiles(Language[] languages, DatabaseSessionFactory sessionFactory, RegisterProvidedProfiles registerProfilesBefore) { + this.languages = languages; + this.sessionFactory = sessionFactory; + } + + public void start() { + TimeProfiler profiler = new TimeProfiler().start("Enable profiles"); + DatabaseSession session = sessionFactory.getSession(); + Set languages = getLanguageKeys(); + + enableProfilesOnKnownLanguages(languages, session); + disableProfilesOnMissingLanguages(languages, session); + + session.commit(); + profiler.stop(); + } + + private void enableProfilesOnKnownLanguages(Set languages, DatabaseSession session) { + Query query = session.createQuery("update " + RulesProfile.class.getSimpleName() + " set enabled=:enabled where language in (:languages)"); + query.setParameter("enabled", true); + query.setParameter("languages", languages); + query.executeUpdate(); + } + + private void disableProfilesOnMissingLanguages(Set languages, DatabaseSession session) { + Query query = session.createQuery("update " + RulesProfile.class.getSimpleName() + " set enabled=:enabled where language not in (:languages)"); + query.setParameter("enabled", false); + query.setParameter("languages", languages); + query.executeUpdate(); + } + + private Set getLanguageKeys() { + Set keys = Sets.newLinkedHashSet(); + for (Language language : languages) { + keys.add(language.getKey()); + } + return keys; + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterRules.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterRules.java index 6f01506b6bc..2e2d31defed 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterRules.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterRules.java @@ -19,6 +19,8 @@ */ package org.sonar.server.startup; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.apache.commons.lang.StringUtils; import org.sonar.api.database.DatabaseSession; import org.sonar.api.rules.*; @@ -61,15 +63,11 @@ public final class RegisterRules { disableDeprecatedUserRules(session); profiler.stop(); - profiler.start("Disable deprecated active rules"); - deleteDisabledActiveRules(session); - profiler.stop(); - session.commit(); } private void disableDeprecatedUserRules(DatabaseSession session) { - List deprecatedUserRuleIds = new ArrayList(); + List deprecatedUserRuleIds = Lists.newLinkedList(); deprecatedUserRuleIds.addAll(session.createQuery( "SELECT r.id FROM " + Rule.class.getSimpleName() + " r WHERE r.parent IS NOT NULL AND NOT EXISTS(FROM " + Rule.class.getSimpleName() + " p WHERE r.parent=p)").getResultList()); @@ -91,7 +89,7 @@ public final class RegisterRules { } private void registerRepository(RuleRepository repository, DatabaseSession session) { - Map rulesByKey = new HashMap(); + Map rulesByKey = Maps.newHashMap(); for (Rule rule : repository.createRules()) { rule.setRepositoryKey(repository.getKey()); rulesByKey.put(rule.getKey(), rule); @@ -110,16 +108,6 @@ public final class RegisterRules { saveNewRules(rulesByKey.values(), session); } - private void deleteDisabledActiveRules(DatabaseSession session) { - List deprecatedActiveRules = session - .createQuery("from " + ActiveRule.class.getSimpleName() + " where rule.enabled=:enabled") - .setParameter("enabled", false) - .getResultList(); - for (ActiveRule deprecatedActiveRule : deprecatedActiveRules) { - session.removeWithoutFlush(deprecatedActiveRule); - } - } - private void updateRule(Rule persistedRule, Rule rule, DatabaseSession session) { persistedRule.setName(rule.getName()); persistedRule.setConfigKey(rule.getConfigKey()); diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/profiles_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/profiles_helper.rb index bfd0fbcb3c1..ad7044b24a8 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/profiles_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/profiles_helper.rb @@ -23,7 +23,7 @@ module ProfilesHelper end def label_for_rules_count(profile) - label="#{profile.active_rules.count} rules" + label="#{profile.count_active_rules} rules" count_overriding=profile.count_overriding_rules if count_overriding>0 diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_parameter.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_parameter.rb index 85904b4ace9..6b47d8fd407 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_parameter.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_parameter.rb @@ -18,23 +18,23 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 # class ActiveRuleParameter < ActiveRecord::Base - belongs_to :active_rule - belongs_to :rules_parameter + belongs_to :active_rule + belongs_to :rules_parameter - def name - rules_parameter.name - end + def name + rules_parameter.name + end - def parameter - rules_parameter - end + def parameter + rules_parameter + end - def validate_on_update - rules_parameter.validate_value(value, errors, "value" ) - end - - def copy - ActiveRuleParameter.new(:rules_parameter => rules_parameter, :value => value) - end + def validate_on_update + rules_parameter.validate_value(value, errors, "value" ) + end + + def copy + ActiveRuleParameter.new(:rules_parameter => rules_parameter, :value => value) + end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb index 493a56da9e0..52e986162b4 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb @@ -126,6 +126,10 @@ class Profile < ActiveRecord::Base end end + def count_active_rules + active_rules.select{|ar| ar.rule.enabled}.size + end + def ancestors @ancestors ||= begin diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb index 0c75209fe57..48cb7947eb3 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb @@ -86,7 +86,7 @@ <%= h profile.name %> - <%= profile.active_rules.count -%> + <%= profile.count_active_rules -%> <%= profile.alerts.size -%> diff --git a/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesBackupTest.java b/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesBackupTest.java index dfec8d7d3a1..2387aba138f 100644 --- a/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesBackupTest.java +++ b/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesBackupTest.java @@ -119,8 +119,8 @@ public class ProfilesBackupTest extends AbstractDbUnitTestCase { RulesProfile testProfile = new RulesProfile("testProfile", "lang", false, false); ActiveRule ar = new ActiveRule(null, new Rule("testPlugin", "testKey"), RulePriority.MAJOR); ar.getActiveRuleParams().add(new ActiveRuleParam(null, new RuleParam(null, "paramKey", null, null), "testValue")); - testProfile.getActiveRules().add(ar); - testProfile.getActiveRules().add(new ActiveRule(null, new Rule("testPlugin", "testKey2"), RulePriority.MINOR)); + testProfile.addActiveRule(ar); + testProfile.addActiveRule(new ActiveRule(null, new Rule("testPlugin", "testKey2"), RulePriority.MINOR)); testProfile.getAlerts().add(new Alert(null, new Metric("testKey"), Alert.OPERATOR_EQUALS, "10", "22")); testProfile.getAlerts().add(new Alert(null, new Metric("testKey2"), Alert.OPERATOR_GREATER, "10", "22")); diff --git a/sonar-server/src/test/java/org/sonar/server/startup/EnableProfilesTest.java b/sonar-server/src/test/java/org/sonar/server/startup/EnableProfilesTest.java new file mode 100644 index 00000000000..c7ec1fec395 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/startup/EnableProfilesTest.java @@ -0,0 +1,63 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.startup; + +import org.junit.Test; +import org.sonar.api.resources.AbstractLanguage; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Language; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +public class EnableProfilesTest extends AbstractDbUnitTestCase { + + @Test + public void shouldDisableProfilesWithMissingLanguages() { + setupData("shouldDisableProfilesWithMissingLanguages"); + + Language[] languages = new Language[]{Java.INSTANCE, new Php()}; + EnableProfiles task = new EnableProfiles(languages, getSessionFactory(), null); + task.start(); + + checkTables("shouldDisableProfilesWithMissingLanguages", "rules_profiles"); + } + + @Test + public void shouldEnableProfilesWithKnownLanguages() { + setupData("shouldEnableProfilesWithKnownLanguages"); + + Language[] languages = new Language[]{Java.INSTANCE, new Php()}; + EnableProfiles task = new EnableProfiles(languages, getSessionFactory(), null); + task.start(); + + checkTables("shouldEnableProfilesWithKnownLanguages", "rules_profiles"); + } + + private static class Php extends AbstractLanguage { + + public Php() { + super("php"); + } + + public String[] getFileSuffixes() { + return new String[0]; + } + } +} + diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages-result.xml new file mode 100644 index 00000000000..62dce741d80 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages-result.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages.xml b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages.xml new file mode 100644 index 00000000000..f2c684b5735 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldDisableProfilesWithMissingLanguages.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages-result.xml new file mode 100644 index 00000000000..d89acc7ae0b --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages-result.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages.xml b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages.xml new file mode 100644 index 00000000000..c32281a33db --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/startup/EnableProfilesTest/shouldEnableProfilesWithKnownLanguages.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/tests/integration/tests/maven-projects/java-complexity/src/main/java/foo/AnonymousClass.java b/tests/integration/tests/maven-projects/java-complexity/src/main/java/foo/AnonymousClass.java index a7572a6d5a5..61b755b16c6 100644 --- a/tests/integration/tests/maven-projects/java-complexity/src/main/java/foo/AnonymousClass.java +++ b/tests/integration/tests/maven-projects/java-complexity/src/main/java/foo/AnonymousClass.java @@ -3,12 +3,13 @@ package foo; import java.io.Serializable; import java.lang.Runnable; -// class complexity: 4 public class AnonymousClass { - // method complexity: 3 - public void anonymousClassWithComplexity() { + // method complexity: 1 or 3 ? + public void hasComplexAnonymousClass() { Runnable runnable = new Runnable() { + + // method complexity: 2 public void run() { if (true) { System.out.println("true"); @@ -18,7 +19,7 @@ public class AnonymousClass { } // method complexity: 1 - public void anonymousClassWithZeroComplexity() { + public void hasEmptyAnonymousClass() { Serializable serializable = new Serializable() { }; -- 2.39.5