aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server/src/main
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2012-10-01 11:56:14 +0200
committerSimon Brandhof <simon.brandhof@gmail.com>2012-10-01 11:56:53 +0200
commit5a11c25655690c26fb739a204f8e1883f9f12261 (patch)
tree8163cb3c6d501c4f1b5a7b913fb76ff150a9c7ed /sonar-server/src/main
parent08a2dfae36a5f246907e6c37732bb75e7c3ec683 (diff)
downloadsonarqube-5a11c25655690c26fb739a204f8e1883f9f12261.tar.gz
sonarqube-5a11c25655690c26fb739a204f8e1883f9f12261.zip
SONAR-3833 ability to edit/delete the profiles provided by plugins
Diffstat (limited to 'sonar-server/src/main')
-rw-r--r--sonar-server/src/main/java/org/sonar/server/configuration/ProfilesBackup.java2
-rw-r--r--sonar-server/src/main/java/org/sonar/server/configuration/ProfilesManager.java7
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java16
-rw-r--r--sonar-server/src/main/java/org/sonar/server/startup/ActivateDefaultProfiles.java91
-rw-r--r--sonar-server/src/main/java/org/sonar/server/startup/RegisterNewProfiles.java228
-rw-r--r--sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java190
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb14
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb22
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb126
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb64
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/alerts/index.html.erb18
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb12
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/profiles/inheritance.html.erb5
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/profiles/projects.html.erb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_active_rule_note.html.erb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb8
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/334_remove_profiles_default_column.rb41
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/335_remove_profiles_provided_column.rb30
20 files changed, 426 insertions, 458 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesBackup.java b/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesBackup.java
index 825e6fb963c..804f6cc54eb 100644
--- a/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesBackup.java
+++ b/sonar-server/src/main/java/org/sonar/server/configuration/ProfilesBackup.java
@@ -60,6 +60,8 @@ public class ProfilesBackup implements Backupable {
xStream.aliasField("default-profile", RulesProfile.class, "defaultProfile");
xStream.omitField(RulesProfile.class, "id");
xStream.omitField(RulesProfile.class, "projects");
+ xStream.omitField(RulesProfile.class, "provided");
+ xStream.omitField(RulesProfile.class, "defaultProfile");
xStream.omitField(RulesProfile.class, "enabled");
xStream.registerConverter(getActiveRuleConverter());
xStream.registerConverter(getAlertsConverter());
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 f2187326fcf..a969a12ef17 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
@@ -43,8 +43,6 @@ public class ProfilesManager extends BaseDao {
RulesProfile profile = getSession().getSingleResult(RulesProfile.class, "id", profileId);
RulesProfile toImport = (RulesProfile) profile.clone();
toImport.setName(newProfileName);
- toImport.setDefaultProfile(false);
- toImport.setProvided(false);
ProfilesBackup pb = new ProfilesBackup(getSession());
pb.importProfile(rulesDao, toImport);
getSession().commit();
@@ -68,7 +66,7 @@ public class ProfilesManager extends BaseDao {
public ValidationMessages changeParentProfile(Integer profileId, String parentName, String userName) {
ValidationMessages messages = ValidationMessages.create();
RulesProfile profile = getSession().getEntity(RulesProfile.class, profileId);
- if (profile != null && !profile.getProvided()) {
+ if (profile != null) {
RulesProfile oldParent = getParentProfile(profile);
RulesProfile newParent = getProfile(profile.getLanguage(), parentName);
if (isCycle(profile, newParent)) {
@@ -344,8 +342,7 @@ public class ProfilesManager extends BaseDao {
private List<RulesProfile> getChildren(RulesProfile parent) {
return getSession().getResults(RulesProfile.class,
"language", parent.getLanguage(),
- "parentName", parent.getName(),
- "provided", false);
+ "parentName", parent.getName());
}
private void removeActiveRule(RulesProfile profile, ActiveRule 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 81901dffde6..56ae61b787f 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
@@ -78,18 +78,7 @@ import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.qualitymodel.DefaultModelManager;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
-import org.sonar.server.startup.ActivateDefaultProfiles;
-import org.sonar.server.startup.DeleteDeprecatedMeasures;
-import org.sonar.server.startup.GeneratePluginIndex;
-import org.sonar.server.startup.GwtPublisher;
-import org.sonar.server.startup.JdbcDriverDeployer;
-import org.sonar.server.startup.RegisterMetrics;
-import org.sonar.server.startup.RegisterNewDashboards;
-import org.sonar.server.startup.RegisterNewFilters;
-import org.sonar.server.startup.RegisterProvidedProfiles;
-import org.sonar.server.startup.RegisterQualityModels;
-import org.sonar.server.startup.RegisterRules;
-import org.sonar.server.startup.ServerMetadataPersister;
+import org.sonar.server.startup.*;
import org.sonar.server.ui.CodeColorizers;
import org.sonar.server.ui.JRubyI18n;
import org.sonar.server.ui.PageDecorations;
@@ -259,8 +248,7 @@ public final class Platform {
startupContainer.addSingleton(GwtPublisher.class);
startupContainer.addSingleton(RegisterMetrics.class);
startupContainer.addSingleton(RegisterRules.class);
- startupContainer.addSingleton(RegisterProvidedProfiles.class);
- startupContainer.addSingleton(ActivateDefaultProfiles.class);
+ startupContainer.addSingleton(RegisterNewProfiles.class);
startupContainer.addSingleton(JdbcDriverDeployer.class);
startupContainer.addSingleton(ServerMetadataPersister.class);
startupContainer.addSingleton(RegisterQualityModels.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
deleted file mode 100644
index 29d76befbdf..00000000000
--- a/sonar-server/src/main/java/org/sonar/server/startup/ActivateDefaultProfiles.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * 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.sonar.api.database.DatabaseSession;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.Language;
-import org.sonar.api.utils.Logs;
-import org.sonar.jpa.session.DatabaseSessionFactory;
-
-import java.util.Iterator;
-import java.util.List;
-
-public final class ActivateDefaultProfiles {
-
- private final DatabaseSessionFactory sessionFactory;
- private final Language[] languages;
-
- public ActivateDefaultProfiles(DatabaseSessionFactory sessionFactory, Language[] languages, RegisterProvidedProfiles registerProfilesBefore) {// NOSONAR the parameter registerProfilesBefore is used to define the execution order of startup components
- this.sessionFactory = sessionFactory;
- this.languages = languages;
- }
-
- public void start() {
- DatabaseSession session = sessionFactory.getSession();
- for (Language language : languages) {
- Logs.INFO.info("Activate default profile for " + language.getKey());
- activateDefaultProfile(language, session);
- }
- session.commit();
- }
-
- public void activateDefaultProfile(Language language, DatabaseSession session) {
- List<RulesProfile> profiles = session.getResults(RulesProfile.class, "language", language.getKey());
- RulesProfile profileToActivate = null;
- boolean oneProfileIsActivated = false;
- if (profiles.isEmpty()) {
- profileToActivate = RulesProfile.create("Default " + language.getName(), language.getKey());
- profileToActivate.setDefaultProfile(true);
- profileToActivate.setProvided(false);
- } else if (profiles.size() == 1) {
- profileToActivate = profiles.get(0);
- } else if (!activeProfileFoundInDB(profiles)) {
- Iterator<RulesProfile> iterator = profiles.iterator();
- while (iterator.hasNext() && !oneProfileIsActivated) {
- RulesProfile profile = iterator.next();
- oneProfileIsActivated = profile.getDefaultProfile();
- if (RulesProfile.SONAR_WAY_NAME.equals(profile.getName())) {
- profileToActivate = profile;
- }
- }
- if (!oneProfileIsActivated && profileToActivate == null) {
- profileToActivate = profiles.get(0);
- }
- }
- activateProfileIfNeeded(session, profileToActivate, oneProfileIsActivated);
- }
-
- private void activateProfileIfNeeded(DatabaseSession session, RulesProfile profileToActivate, boolean oneProfileIsActivated) {
- if (!oneProfileIsActivated && profileToActivate != null) {
- profileToActivate.setDefaultProfile(true);
- session.saveWithoutFlush(profileToActivate);
- }
- }
-
- private boolean activeProfileFoundInDB(List<RulesProfile> profiles) {
- for (RulesProfile rulesProfile : profiles) {
- if (rulesProfile.getDefaultProfile()) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewProfiles.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewProfiles.java
new file mode 100644
index 00000000000..5c2f5a15480
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewProfiles.java
@@ -0,0 +1,228 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.base.Function;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.profiles.ProfileDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.*;
+import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.TimeProfiler;
+import org.sonar.api.utils.ValidationMessages;
+import org.sonar.core.template.LoadedTemplateDao;
+import org.sonar.core.template.LoadedTemplateDto;
+import org.sonar.jpa.session.DatabaseSessionFactory;
+import org.sonar.server.platform.PersistentSettings;
+
+import java.util.*;
+
+public class RegisterNewProfiles {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(RegisterNewProfiles.class);
+ private static final String DEFAULT_PROFILE_NAME = "Sonar way";
+
+ private final List<ProfileDefinition> definitions;
+ private final LoadedTemplateDao loadedTemplateDao;
+ private final RuleFinder ruleFinder;
+ private final DatabaseSessionFactory sessionFactory;
+ private final PersistentSettings settings;
+ private DatabaseSession session = null;
+
+ public RegisterNewProfiles(List<ProfileDefinition> definitions,
+ PersistentSettings settings,
+ RuleFinder ruleFinder,
+ LoadedTemplateDao loadedTemplateDao,
+ DatabaseSessionFactory sessionFactory,
+ RegisterRules registerRulesBefore) {
+ this.settings = settings;
+ this.ruleFinder = ruleFinder;
+ this.definitions = definitions;
+ this.loadedTemplateDao = loadedTemplateDao;
+ this.sessionFactory = sessionFactory;
+ }
+
+ public RegisterNewProfiles(PersistentSettings settings,
+ RuleFinder ruleFinder,
+ LoadedTemplateDao loadedTemplateDao,
+ DatabaseSessionFactory sessionFactory,
+ RegisterRules registerRulesBefore) {
+ this(Collections.<ProfileDefinition>emptyList(), settings, ruleFinder, loadedTemplateDao, sessionFactory, registerRulesBefore);
+ }
+
+ public void start() {
+ TimeProfiler profiler = new TimeProfiler().start("Register Quality Profiles");
+ session = sessionFactory.getSession();
+ ListMultimap<String, RulesProfile> profilesByLanguage = loadDefinitions();
+ for (String language : profilesByLanguage.keySet()) {
+ List<RulesProfile> profiles = profilesByLanguage.get(language);
+ verifyLanguage(language, profiles);
+
+ for (Map.Entry<String, Collection<RulesProfile>> entry : groupByName(profiles).entrySet()) {
+ String name = entry.getKey();
+ if (shouldRegister(language, name)) {
+ register(language, name, entry.getValue());
+ }
+ }
+
+ setDefault(language, profiles);
+ }
+ session.commit();
+ profiler.stop();
+ }
+
+ private void setDefault(String language, List<RulesProfile> profiles) {
+ String propertyKey = "sonar.profile." + language;
+ if (settings.getString(propertyKey) == null) {
+ String defaultProfileName = defaultProfileName(profiles);
+ LOGGER.info("Set default profile for " + language + ": " + defaultProfileName);
+ settings.saveProperty(propertyKey, defaultProfileName);
+ }
+ }
+
+ private Map<String, Collection<RulesProfile>> groupByName(List<RulesProfile> profiles) {
+ return Multimaps.index(profiles,
+ new Function<RulesProfile, String>() {
+ public String apply(RulesProfile profile) {
+ return profile.getName();
+ }
+ }).asMap();
+ }
+
+ private boolean shouldRegister(String language, String profileName) {
+ return loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.QUALITY_PROFILE_TYPE, templateKey(language, profileName)) == 0;
+ }
+
+ private static String templateKey(String language, String profileName) {
+ return StringUtils.lowerCase(language) + ":" + profileName;
+ }
+
+ private void register(String language, String name, Collection<RulesProfile> profiles) {
+ clean(language, name);
+ insert(language, name, profiles);
+ loadedTemplateDao.insert(new LoadedTemplateDto(templateKey(language, name), LoadedTemplateDto.QUALITY_PROFILE_TYPE));
+ }
+
+
+ private void verifyLanguage(String language, List<RulesProfile> profiles) {
+ if (profiles.isEmpty()) {
+ LOGGER.warn("No Quality Profile defined for language: " + language);
+ }
+
+ Set<String> defaultProfileNames = defaultProfileNames(profiles);
+ if (defaultProfileNames.size() > 1) {
+ throw new SonarException("Several Quality Profiles are flagged as default for the language " + language + ": " +
+ defaultProfileNames);
+ }
+ }
+
+ /**
+ * @return profiles by language
+ */
+ private ListMultimap<String, RulesProfile> loadDefinitions() {
+ ListMultimap<String, RulesProfile> byLang = ArrayListMultimap.create();
+ for (ProfileDefinition definition : definitions) {
+ ValidationMessages validation = ValidationMessages.create();
+ RulesProfile profile = definition.createProfile(validation);
+ validation.log(LOGGER);
+ if (profile != null && !validation.hasErrors()) {
+ byLang.put(StringUtils.lowerCase(profile.getLanguage()), profile);
+ }
+ }
+ return byLang;
+ }
+
+ private static String defaultProfileName(List<RulesProfile> profiles) {
+ String defaultName = null;
+ boolean hasSonarWay = false;
+
+ for (RulesProfile profile : profiles) {
+ if (profile.getDefaultProfile()) {
+ defaultName = profile.getName();
+ } else if (DEFAULT_PROFILE_NAME.equals(profile.getName())) {
+ hasSonarWay = true;
+ }
+ }
+
+ if (StringUtils.isBlank(defaultName) && !hasSonarWay && !profiles.isEmpty()) {
+ defaultName = profiles.get(0).getName();
+ }
+
+ return StringUtils.defaultIfBlank(defaultName, DEFAULT_PROFILE_NAME);
+ }
+
+ private static Set<String> defaultProfileNames(Collection<RulesProfile> profiles) {
+ Set<String> names = Sets.newHashSet();
+ for (RulesProfile profile : profiles) {
+ if (profile.getDefaultProfile()) {
+ names.add(profile.getName());
+ }
+ }
+ return names;
+ }
+
+ //
+ // PERSISTENCE
+ //
+
+ private void insert(String language, String name, Collection<RulesProfile> profiles) {
+ RulesProfile persisted = RulesProfile.create(name, language);
+ for (RulesProfile profile : profiles) {
+ for (ActiveRule activeRule : profile.getActiveRules()) {
+ Rule rule = persistedRule(activeRule);
+ ActiveRule persistedActiveRule = persisted.activateRule(rule, activeRule.getSeverity());
+ for (RuleParam param : rule.getParams()) {
+ String value = StringUtils.defaultString(activeRule.getParameter(param.getKey()), param.getDefaultValue());
+ if (value != null) {
+ persistedActiveRule.setParameter(param.getKey(), value);
+ }
+ }
+ }
+ }
+ session.saveWithoutFlush(persisted);
+ }
+
+ private Rule persistedRule(ActiveRule activeRule) {
+ Rule rule = activeRule.getRule();
+ if (rule != null && rule.getId() == null) {
+ if (rule.getKey() != null) {
+ rule = ruleFinder.findByKey(rule.getRepositoryKey(), rule.getKey());
+
+ } else if (rule.getConfigKey() != null) {
+ rule = ruleFinder.find(RuleQuery.create().withRepositoryKey(rule.getRepositoryKey()).withConfigKey(rule.getConfigKey()));
+ }
+ }
+ return rule;
+ }
+
+ private void clean(String language, String name) {
+ List<RulesProfile> existingProfiles = session.getResults(RulesProfile.class, "language", language, "name", name);
+ for (RulesProfile profile : existingProfiles) {
+ session.removeWithoutFlush(profile);
+ }
+ }
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java
deleted file mode 100644
index d8d504a0f2c..00000000000
--- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * 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 java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.profiles.ProfileDefinition;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.ActiveRule;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.rules.RuleParam;
-import org.sonar.api.rules.RuleQuery;
-import org.sonar.api.utils.SonarException;
-import org.sonar.api.utils.TimeProfiler;
-import org.sonar.api.utils.ValidationMessages;
-import org.sonar.jpa.session.DatabaseSessionFactory;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-public final class RegisterProvidedProfiles {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(RegisterProvidedProfiles.class);
-
- private DatabaseSessionFactory sessionFactory;
- private List<ProfileDefinition> definitions = Lists.newArrayList();
- private RuleFinder ruleFinder;
-
- public RegisterProvidedProfiles(RuleFinder ruleFinder, DatabaseSessionFactory sessionFactory,// NOSONAR the parameter registerRulesBefore is unused must be declared for execution order of tasks
- RegisterRules registerRulesBefore,
- ProfileDefinition[] definitions) {
- this.ruleFinder = ruleFinder;
- this.sessionFactory = sessionFactory;
- this.definitions.addAll(Arrays.asList(definitions));
- }
-
- public RegisterProvidedProfiles(RuleFinder ruleFinder, DatabaseSessionFactory sessionFactory,// NOSONAR the parameter registerRulesBefore is unused must be declared for execution order of tasks
- RegisterRules registerRulesBefore) {
- this.ruleFinder = ruleFinder;
- this.sessionFactory = sessionFactory;
- }
-
- public void start() {
- TimeProfiler profiler = new TimeProfiler().start("Load provided profiles");
-
- List<RulesProfile> profiles = createProfiles();
- DatabaseSession session = sessionFactory.getSession();
- cleanProvidedProfiles(profiles, session);
- saveProvidedProfiles(profiles, session);
- session.commit();
- profiler.stop();
- }
-
- private List<RulesProfile> createProfiles() {
- List<RulesProfile> result = Lists.newArrayList();
- Map<String, RulesProfile> defaultProfilesByLanguage = Maps.newHashMap();
- for (ProfileDefinition definition : definitions) {
- ValidationMessages validation = ValidationMessages.create();
- RulesProfile profile = definition.createProfile(validation);
- validation.log(LOGGER);
- if (profile != null && !validation.hasErrors()) {
- result.add(profile);
- checkIfNoMoreThanOneDefaultProfile(defaultProfilesByLanguage, profile);
- }
- }
- return result;
- }
-
- private void checkIfNoMoreThanOneDefaultProfile(Map<String, RulesProfile> defaultProfilesByLanguage, RulesProfile profile) {
- if (profile.getDefaultProfile()) {
- RulesProfile defaultProfileForLanguage = defaultProfilesByLanguage.get(profile.getLanguage());
- if (defaultProfileForLanguage == null) {
- defaultProfilesByLanguage.put(profile.getLanguage(), profile);
- } else {
- throw new SonarException("Language " + profile.getLanguage() + " can't have 2 default provided profiles: "
- + profile.getName() + " and "
- + defaultProfileForLanguage.getName());
- }
- }
- }
-
- private void cleanProvidedProfiles(List<RulesProfile> profiles, DatabaseSession session) {
- TimeProfiler profiler = new TimeProfiler().start("Clean provided profiles");
- List<RulesProfile> existingProfiles = session.getResults(RulesProfile.class, "provided", true);
- for (RulesProfile existingProfile : existingProfiles) {
- boolean isDeprecated = true;
- for (RulesProfile profile : profiles) {
- if (StringUtils.equals(existingProfile.getName(), profile.getName()) && StringUtils.equals(existingProfile.getLanguage(), profile.getLanguage())) {
- isDeprecated = false;
- break;
- }
- }
- if (isDeprecated) {
- session.removeWithoutFlush(existingProfile);
- } else {
- for (ActiveRule activeRule : existingProfile.getActiveRules()) {
- session.removeWithoutFlush(activeRule);
- }
- existingProfile.setActiveRules(new ArrayList<ActiveRule>());
- session.saveWithoutFlush(existingProfile);
- }
- }
- profiler.stop();
- }
-
- private void saveProvidedProfiles(List<RulesProfile> profiles, DatabaseSession session) {
- Collection<String> languagesWithDefaultProfile = findLanguagesWithDefaultProfile(session);
- for (RulesProfile profile : profiles) {
- TimeProfiler profiler = new TimeProfiler().start("Save profile " + profile);
- RulesProfile persistedProfile = findOrCreate(profile, session, languagesWithDefaultProfile.contains(profile.getLanguage()));
-
- for (ActiveRule activeRule : profile.getActiveRules()) {
- Rule rule = getPersistedRule(activeRule);
- ActiveRule persistedRule = persistedProfile.activateRule(rule, activeRule.getSeverity());
- for (RuleParam param : rule.getParams()) {
- String value = StringUtils.defaultString(activeRule.getParameter(param.getKey()), param.getDefaultValue());
- if (value != null) {
- persistedRule.setParameter(param.getKey(), value);
- }
- }
- }
-
- session.saveWithoutFlush(persistedProfile);
- profiler.stop();
- }
- }
-
- private Collection<String> findLanguagesWithDefaultProfile(DatabaseSession session) {
- Set<String> languagesWithDefaultProfile = Sets.newHashSet();
- List<RulesProfile> defaultProfiles = session.getResults(RulesProfile.class, "defaultProfile", true);
- for (RulesProfile defaultProfile : defaultProfiles) {
- languagesWithDefaultProfile.add(defaultProfile.getLanguage());
- }
- return languagesWithDefaultProfile;
- }
-
- private Rule getPersistedRule(ActiveRule activeRule) {
- Rule rule = activeRule.getRule();
- if (rule != null && rule.getId() == null) {
- if (rule.getKey() != null) {
- rule = ruleFinder.findByKey(rule.getRepositoryKey(), rule.getKey());
-
- } else if (rule.getConfigKey() != null) {
- rule = ruleFinder.find(RuleQuery.create().withRepositoryKey(rule.getRepositoryKey()).withConfigKey(rule.getConfigKey()));
- }
- }
- return rule;
- }
-
- private RulesProfile findOrCreate(RulesProfile profile, DatabaseSession session, boolean defaultProfileAlreadyExist) {
- RulesProfile persistedProfile = session.getSingleResult(RulesProfile.class, "name", profile.getName(), "language", profile.getLanguage());
- if (persistedProfile == null) {
- persistedProfile = RulesProfile.create(profile.getName(), profile.getLanguage());
- persistedProfile.setProvided(true);
- if (!defaultProfileAlreadyExist) {
- persistedProfile.setDefaultProfile(profile.getDefaultProfile());
- }
- }
- return persistedProfile;
- }
-
-}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb
index 3cb66a8cc76..9a7652a0179 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb
@@ -30,9 +30,9 @@ class Api::ProfilesController < Api::ApiController
name=params[:name]
if name.blank?
- @profile=Profile.find(:first, :conditions => ['language=? and default_profile=?', language, true])
+ @profile=Profile.by_default(language)
else
- @profile=Profile.find(:first, :conditions => ['language=? and name=?', language, name])
+ @profile=Profile.find_by_name_and_language(name, language)
end
raise ApiException.new(404, "Profile not found") if @profile.nil?
@@ -60,9 +60,9 @@ class Api::ProfilesController < Api::ApiController
bad_request('Missing parameter: language') if params[:language].blank?
if params[:name].blank?
- profile=Profile.find(:first, :conditions => ['language=? and default_profile=?', params[:language], true])
+ profile=Profile.by_default(params[:language])
else
- profile=Profile.find(:first, :conditions => ['language=? and name=?', params[:language], params[:name]])
+ profile=Profile.find_by_name_and_language(params[:name], params[:language])
end
not_found('Profile not found') unless profile
@@ -124,8 +124,7 @@ class Api::ProfilesController < Api::ApiController
result[:name]=@profile.name
result[:language]=@profile.language
result[:parent]=@profile.parent_name if @profile.parent_name.present?
- result[:default]=@profile.default_profile
- result[:provided]=@profile.provided
+ result[:default]=@profile.default_profile?
rules=[]
@active_rules.each do |active_rule|
@@ -162,8 +161,7 @@ class Api::ProfilesController < Api::ApiController
xml.name(@profile.name)
xml.language(@profile.language)
xml.parent(@profile.parent_name) if @profile.parent_name.present?
- xml.default(@profile.default_profile)
- xml.provided(@profile.provided)
+ xml.default(@profile.default_profile?)
@active_rules.each do |active_rule|
xml.rule do
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb
index 50fbf55c26f..ca6f1f3f325 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb
@@ -25,7 +25,8 @@ class ProfilesController < ApplicationController
# GET /profiles/index
def index
- @profiles = Profile.find(:all, :order => 'name')
+ @profiles = Profile.find(:all)
+ Api::Utils.insensitive_sort!(@profiles){|profile| profile.name}
end
@@ -50,7 +51,7 @@ class ProfilesController < ApplicationController
profile_name=params[:name]
language=params[:language]
- profile = Profile.create(:name => profile_name, :language => language, :default_profile => false)
+ profile = Profile.create(:name => profile_name, :language => language)
ok = profile.errors.empty?
if ok && params[:backup]
params[:backup].each_pair do |importer_key, file|
@@ -92,7 +93,6 @@ class ProfilesController < ApplicationController
profile = Profile.find(params[:id])
profile.set_as_default
- #TODO remove l10n key: flash[:notice]=message('quality_profiles.default_profile_is_x', :params => profile.name)
redirect_to :action => 'index'
end
@@ -113,7 +113,7 @@ class ProfilesController < ApplicationController
@profile = Profile.find(params[:id])
name = params['name']
- target_profile=Profile.new(:name => name, :language => @profile.language, :provided => false, :default_profile => false)
+ target_profile=Profile.new(:name => name, :language => @profile.language)
if target_profile.valid?
java_facade.copyProfile(@profile.id, name)
flash[:notice]= message('quality_profiles.profile_x_not_activated', :params => name)
@@ -257,31 +257,33 @@ class ProfilesController < ApplicationController
end
- # POST /profiles/add_project?id=<profile id>&project_id=<project id>
+ # POST /profiles/add_project?id=<profile id>&project=<project id or key>
def add_project
verify_post_request
- require_parameters 'id', 'project_id'
+ require_parameters 'id', 'project'
admin_required
profile=Profile.find(params[:id])
bad_request('Unknown profile') unless profile
- project=Project.find(params[:project_id])
+ project=Project.by_key(params[:project])
bad_request('Unknown project') unless project
profile.add_project_id(project.id)
redirect_to :action => 'projects', :id => profile.id
end
- # POST /profiles/remove_project?id=<profile id>&project_id=<project id>
+ # POST /profiles/remove_project?id=<profile id>&project=<project id or key>
def remove_project
verify_post_request
- require_parameters 'id', 'project_id'
+ require_parameters 'id', 'project'
admin_required
profile=Profile.find(params[:id])
bad_request('Unknown profile') unless profile
+ project=Project.by_key(params[:project])
+ bad_request('Unknown project') unless project
- Profile.reset_default_profile_for_project_id(profile.language, params[:project_id])
+ Profile.reset_default_profile_for_project_id(profile.language, project.id)
redirect_to :action => 'projects', :id => profile.id
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb
index d9b6b28a323..db30cd8f9c3 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb
@@ -22,18 +22,18 @@ require 'cgi'
class RulesConfigurationController < ApplicationController
SECTION=Navigation::SECTION_CONFIGURATION
-
+
STATUS_ACTIVE = "ACTIVE"
STATUS_INACTIVE = "INACTIVE"
ANY_SELECTION = [["Any", '']]
RULE_PRIORITIES = Sonar::RulePriority.as_options.reverse
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
- verify :method => :post,
- :only => ['activate_rule', 'update_param', 'bulk_edit', 'create', 'update', 'delete', 'revert_rule', 'update_rule_note', 'update_active_rule_note', 'delete_active_rule_note'],
- :redirect_to => { :action => 'index' }
+ verify :method => :post,
+ :only => ['activate_rule', 'update_param', 'bulk_edit', 'create', 'update', 'delete', 'revert_rule', 'update_rule_note', 'update_active_rule_note', 'delete_active_rule_note'],
+ :redirect_to => {:action => 'index'}
- before_filter :admin_required, :except => [ 'index', 'export' ]
+ before_filter :admin_required, :except => ['index', 'export']
def index
unless params[:id].blank?
@@ -50,28 +50,28 @@ class RulesConfigurationController < ApplicationController
else
@profile = Profile.default_profile
end
-
+
init_params()
- @select_plugins = ANY_SELECTION + java_facade.getRuleRepositoriesByLanguage(@profile.language).collect { |repo| [repo.getName(true), repo.getKey()]}.sort
+ @select_plugins = ANY_SELECTION + java_facade.getRuleRepositoriesByLanguage(@profile.language).collect { |repo| [repo.getName(true), repo.getKey()] }.sort
@select_priority = ANY_SELECTION + RULE_PRIORITIES
- @select_status = [[message('any'),''], [message('active'), STATUS_ACTIVE], [message('inactive'), STATUS_INACTIVE]]
- @select_inheritance = [[message('any'),''], [message('rules_configuration.not_inherited'), 'NOT'], [message('rules_configuration.inherited'), 'INHERITED'], [message('rules_configuration.overrides'), 'OVERRIDES']]
+ @select_status = [[message('any'), ''], [message('active'), STATUS_ACTIVE], [message('inactive'), STATUS_INACTIVE]]
+ @select_inheritance = [[message('any'), ''], [message('rules_configuration.not_inherited'), 'NOT'], [message('rules_configuration.inherited'), 'INHERITED'], [message('rules_configuration.overrides'), 'OVERRIDES']]
@rules = Rule.search(java_facade, {
:profile => @profile, :status => @status, :priorities => @priorities, :inheritance => @inheritance,
- :plugins => @plugins, :searchtext => @searchtext, :include_parameters_and_notes => true, :language => @profile.language})
+ :plugins => @plugins, :searchtext => @searchtext, :include_parameters_and_notes => true, :language => @profile.language})
unless @searchtext.blank?
if @status==STATUS_ACTIVE
@hidden_inactives=Rule.search(java_facade, {
:profile => @profile, :status => STATUS_INACTIVE, :priorities => @priorities,
- :plugins => @plugins, :language => @profile.language, :searchtext => @searchtext, :include_parameters_and_notes => false}).size
+ :plugins => @plugins, :language => @profile.language, :searchtext => @searchtext, :include_parameters_and_notes => false}).size
elsif @status==STATUS_INACTIVE
@hidden_actives=Rule.search(java_facade, {
:profile => @profile, :status => STATUS_ACTIVE, :priorities => @priorities,
- :plugins => @plugins, :language => @profile.language, :searchtext => @searchtext, :include_parameters_and_notes => false}).size
+ :plugins => @plugins, :language => @profile.language, :searchtext => @searchtext, :include_parameters_and_notes => false}).size
end
end
@@ -100,7 +100,7 @@ class RulesConfigurationController < ApplicationController
#
def activate_rule
profile = Profile.find(params[:id].to_i)
- if profile && !profile.provided?
+ if profile
rule=Rule.find(:first, :conditions => {:id => params[:rule_id].to_i, :enabled => true})
priority=params[:level]
@@ -117,7 +117,7 @@ class RulesConfigurationController < ApplicationController
activated = false
if active_rule.nil?
active_rule = ActiveRule.new(:profile_id => profile.id, :rule => rule)
- rule.parameters.select{|p| p.default_value.present?}.each do |p|
+ rule.parameters.select { |p| p.default_value.present? }.each do |p|
active_rule.active_rule_parameters.build(:rules_parameter => p, :value => p.default_value)
end
activated = true
@@ -126,9 +126,9 @@ class RulesConfigurationController < ApplicationController
active_rule.failure_level=Sonar::RulePriority.id(priority)
active_rule.save!
if activated
- java_facade.ruleActivated(profile.id, active_rule.id, current_user.name)
+ java_facade.ruleActivated(profile.id, active_rule.id, current_user.name)
else
- java_facade.ruleSeverityChanged(profile.id, active_rule.id, old_severity, active_rule.failure_level, current_user.name)
+ java_facade.ruleSeverityChanged(profile.id, active_rule.id, old_severity, active_rule.failure_level, current_user.name)
end
end
if active_rule
@@ -163,33 +163,33 @@ class RulesConfigurationController < ApplicationController
def create
template=Rule.find(params[:rule_id])
rule=Rule.create(params[:rule].merge(
- {
- :priority => Sonar::RulePriority.id(params[:rule][:priority]),
- :parent_id => template.id,
- :plugin_name => template.plugin_name,
- :cardinality => 'SINGLE',
- :plugin_rule_key => "#{template.plugin_rule_key}_#{Time.now.to_i}",
- :plugin_config_key => template.plugin_config_key,
- :enabled => true}))
+ {
+ :priority => Sonar::RulePriority.id(params[:rule][:priority]),
+ :parent_id => template.id,
+ :plugin_name => template.plugin_name,
+ :cardinality => 'SINGLE',
+ :plugin_rule_key => "#{template.plugin_rule_key}_#{Time.now.to_i}",
+ :plugin_config_key => template.plugin_config_key,
+ :enabled => true}))
template.parameters.each do |template_parameter|
rule.rules_parameters.build(:name => template_parameter.name, :param_type => template_parameter.param_type, :description => template_parameter.description,
- :default_value => params[:rule_param][template_parameter.name])
+ :default_value => params[:rule_param][template_parameter.name])
end
if rule.save
redirect_to :action => 'index', :id => params[:id], :searchtext => rule.name, :rule_status => 'INACTIVE', "plugins[]" => rule.plugin_name
-
+
else
flash[:error]=message('rules_configuration.rule_not_valid_message_x', :params => rule.errors.full_messages.join('<br/>'))
redirect_to :action => 'new', :id => params[:id], :rule_id => params[:rule_id]
- end
+ end
end
# deprecated since 2.3
def export
- redirect_to request.query_parameters.merge({:controller => 'profiles', :action => 'export'})
+ redirect_to request.query_parameters.merge({:controller => 'profiles', :action => 'export'})
end
#
@@ -266,19 +266,19 @@ class RulesConfigurationController < ApplicationController
#
def bulk_edit
profile = Profile.find(params[:id].to_i)
- rule_ids = params[:bulk_rule_ids].split(',').map{|id| id.to_i}
+ rule_ids = params[:bulk_rule_ids].split(',').map { |id| id.to_i }
status=params[:rule_status]
-
+
case params[:bulk_action]
- when 'activate'
- count=activate_rules(profile, rule_ids)
- flash[:notice]=message('rules_configuration.x_rules_have_been_activated', :params => count)
- status=STATUS_ACTIVE if status==STATUS_INACTIVE
-
- when 'deactivate'
- count=deactivate_rules(profile, rule_ids)
- flash[:notice]=message('rules_configuration.x_rules_have_been_deactivated', :params => count)
- status=STATUS_INACTIVE if status==STATUS_ACTIVE
+ when 'activate'
+ count=activate_rules(profile, rule_ids)
+ flash[:notice]=message('rules_configuration.x_rules_have_been_activated', :params => count)
+ status=STATUS_ACTIVE if status==STATUS_INACTIVE
+
+ when 'deactivate'
+ count=deactivate_rules(profile, rule_ids)
+ flash[:notice]=message('rules_configuration.x_rules_have_been_deactivated', :params => count)
+ status=STATUS_INACTIVE if status==STATUS_ACTIVE
end
url_parameters=request.query_parameters.merge({:action => 'index', :bulk_action => nil, :bulk_rule_ids => nil, :id => profile.id, :rule_status => status})
@@ -286,7 +286,6 @@ class RulesConfigurationController < ApplicationController
end
-
def update_param
is_admin=true # security has already been checked by controller filters
profile = Profile.find(params[:profile_id].to_i)
@@ -294,25 +293,23 @@ class RulesConfigurationController < ApplicationController
active_rule = ActiveRule.find(params[:active_rule_id].to_i)
active_param = ActiveRuleParameter.find(params[:id].to_i) if params[:id].to_i > 0
value = params[:value]
- if !profile.provided?
- if value != ""
- active_param = ActiveRuleParameter.new(:rules_parameter => rule_param, :active_rule => active_rule ) if active_param.nil?
- old_value = active_param.value
- active_param.value = value
- if active_param.save! && active_param.valid?
- active_param.reload
- java_facade.ruleParamChanged(profile.id, active_rule.id, rule_param.name, old_value, value, current_user.name)
- end
- elsif !active_param.nil?
- old_value = active_param.value
- active_param.destroy
- active_param = nil
- java_facade.ruleParamChanged(profile.id, active_rule.id, rule_param.name, old_value, nil, current_user.name)
+ if value != ""
+ active_param = ActiveRuleParameter.new(:rules_parameter => rule_param, :active_rule => active_rule) if active_param.nil?
+ old_value = active_param.value
+ active_param.value = value
+ if active_param.save! && active_param.valid?
+ active_param.reload
+ java_facade.ruleParamChanged(profile.id, active_rule.id, rule_param.name, old_value, value, current_user.name)
end
+ elsif !active_param.nil?
+ old_value = active_param.value
+ active_param.destroy
+ active_param = nil
+ java_facade.ruleParamChanged(profile.id, active_rule.id, rule_param.name, old_value, nil, current_user.name)
end
- # let's reload the active rule
+ # let's reload the active rule
active_rule = ActiveRule.find(active_rule.id)
- render :partial => 'rule', :locals => {:profile => profile, :rule => active_rule.rule, :active_rule => active_rule, :is_admin => is_admin }
+ render :partial => 'rule', :locals => {:profile => profile, :rule => active_rule.rule, :active_rule => active_rule, :is_admin => is_admin}
end
@@ -327,7 +324,7 @@ class RulesConfigurationController < ApplicationController
note.text = params[:text]
note.user_login = current_user.login
note.save!
- render :partial => 'rule_note', :locals => {:rule => rule, :is_admin => true }
+ render :partial => 'rule_note', :locals => {:rule => rule, :is_admin => true}
end
@@ -342,27 +339,26 @@ class RulesConfigurationController < ApplicationController
note.text = params[:note]
note.user_login = current_user.login
note.save!
- render :partial => 'active_rule_note', :locals => {:active_rule => active_rule, :is_admin => true, :profile => active_rule.rules_profile }
+ render :partial => 'active_rule_note', :locals => {:active_rule => active_rule, :is_admin => true, :profile => active_rule.rules_profile}
end
-
+
def delete_active_rule_note
active_rule = ActiveRule.find(params[:active_rule_id])
active_rule.note.destroy if active_rule.note
active_rule.note = nil
- render :partial => 'active_rule_note', :locals => {:active_rule => active_rule, :is_admin => true, :profile => active_rule.rules_profile }
+ render :partial => 'active_rule_note', :locals => {:active_rule => active_rule, :is_admin => true, :profile => active_rule.rules_profile}
end
-
-
+
private
# return the number of newly activated rules
def activate_rules(profile, rule_ids)
count=0
- rule_ids_to_activate=(rule_ids - profile.active_rules.map{|ar| ar.rule_id})
+ rule_ids_to_activate=(rule_ids - profile.active_rules.map { |ar| ar.rule_id })
unless rule_ids_to_activate.empty?
- rules_to_activate=Rule.find(:all, :conditions => {:enabled=>true, :id => rule_ids_to_activate})
+ rules_to_activate=Rule.find(:all, :conditions => {:enabled => true, :id => rule_ids_to_activate})
count = rules_to_activate.size
rules_to_activate.each do |rule|
active_rule = profile.active_rules.create(:rule => rule, :failure_level => rule.priority)
@@ -395,7 +391,7 @@ class RulesConfigurationController < ApplicationController
def filter_any(array)
if array && array.size>1 && array.include?('')
- array=[''] #keep only 'any'
+ array=[''] #keep only 'any'
end
array
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 3d61493d36f..0a5cb171b78 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
@@ -60,21 +60,12 @@ class Profile < ActiveRecord::Base
"#{language}_#{name}"
end
- def provided?
- provided
+ def default_profile?
+ Property.value("sonar.profile.#{language}")==name
end
def set_as_default
- Profile.transaction do
- Profile.find(:all, :conditions => {:language => language}).each do |profile|
- if profile.id==id
- profile.default_profile=true
- else
- profile.default_profile=false
- end
- profile.save
- end
- end
+ Property.set("sonar.profile.#{language}", name)
self
end
@@ -105,14 +96,14 @@ class Profile < ActiveRecord::Base
end
def deletable?
- !provided? && !default_profile? && children.empty?
+ !default_profile? && children.empty?
end
def count_overriding_rules
@count_overriding_rules||=
- begin
- active_rules.count(:conditions => ['inheritance=?', 'OVERRIDES'])
- end
+ begin
+ active_rules.count(:conditions => ['inheritance=?', 'OVERRIDES'])
+ end
end
def inherited?
@@ -121,13 +112,13 @@ class Profile < ActiveRecord::Base
def parent
@parent||=
- begin
- if parent_name.present?
- Profile.find(:first, :conditions => ['language=? and name=?', language, parent_name])
- else
- nil
+ begin
+ if parent_name.present?
+ Profile.find(:first, :conditions => ['language=? and name=?', language, parent_name])
+ else
+ nil
+ end
end
- end
end
def count_active_rules
@@ -136,14 +127,14 @@ class Profile < ActiveRecord::Base
def ancestors
@ancestors ||=
- begin
- array=[]
- if parent
- array<<parent
- array.concat(parent.ancestors)
+ begin
+ array=[]
+ if parent
+ array<<parent
+ array.concat(parent.ancestors)
+ end
+ array
end
- array
- end
end
def import_configuration(importer_key, file)
@@ -160,8 +151,8 @@ class Profile < ActiveRecord::Base
end
def before_destroy
+ raise 'This profile can not be deleted' unless deletable?
Property.clear_for_resources("sonar.profile.#{language}", name)
- #TODO clear global property sonar.profile.#{language} with value #{name}
end
def rename(new_name)
@@ -186,14 +177,14 @@ class Profile < ActiveRecord::Base
def projects
@projects ||=
- begin
- Project.find(:all,
- :conditions => ['id in (select prop.resource_id from properties prop where prop.resource_id is not null and prop.prop_key=? and prop.text_value like ?)', "sonar.profile.#{language}", name])
- end
+ begin
+ Project.find(:all,
+ :conditions => ['id in (select prop.resource_id from properties prop where prop.resource_id is not null and prop.prop_key=? and prop.text_value like ?)', "sonar.profile.#{language}", name])
+ end
end
def sorted_projects
- Api::Utils.insensitive_sort(projects){|p| p.name}
+ Api::Utils.insensitive_sort(projects) { |p| p.name }
end
def add_project_id(project_id)
@@ -221,7 +212,8 @@ class Profile < ActiveRecord::Base
end
def self.by_default(language)
- Profile.find(:first, :conditions => {:default_profile => true, :language => language})
+ default_name = Property.value("sonar.profile.#{language}")
+ default_name.present? ? Profile.find(:first, :conditions => {:name => default_name, :language => language}) : nil
end
# Results are NOT sorted
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/alerts/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/alerts/index.html.erb
index c70c6239f28..dbab2ebbca1 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/alerts/index.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/alerts/index.html.erb
@@ -2,17 +2,9 @@
<%= render :partial => 'profiles/tabs', :locals => {:selected_tab=>'Alerts'} %>
<% if is_admin? %>
- <% if @profile.provided? %>
- <div class="tabs-panel marginbottom10 background-gray">
- <div class="line-info note">
- <%= message('rules_configuration.profile_cant_be_updated_description') -%>
- </div>
- </div>
- <% else %>
- <div class="tabs-panel marginbottom10 admin" id="new_alert_form">
- <%= render :partial => 'new' %>
- </div>
- <% end %>
+ <div class="tabs-panel marginbottom10 admin" id="new_alert_form">
+ <%= render :partial => 'new' %>
+ </div>
<% else %>
<div class="break10"> </div>
<% end %>
@@ -28,10 +20,8 @@
<% for alert in @alerts %>
<tr class="<%= cycle('even','odd') -%>">
<td id="row_alert_<%= alert.id -%>">
- <% if is_admin? && !@profile.provided? %>
+ <% if is_admin? %>
<%= render :partial => 'edit', :locals => {:alert => alert} %>
- <% else %>
- <%= render :partial => 'show', :locals => {:alert => alert} %>
<% end %>
</td>
</tr>
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 cba2a1f0be9..2ea6c613a7c 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
@@ -79,17 +79,13 @@
<% if administrator? %>
<td align="right">
- <% if !profile.provided? %>
- <form method="post" action="/dev/profiles/backup/<%= profile.id -%>" id="backup-<%= profile.key.parameterize -%>-form">
- <a href="#" class="link-action" name="button_backup" id="backup_<%= u profile.key %>" onclick="$j('#backup-<%= profile.key.parameterize -%>-form').submit();return false;"><%= message('backup_verb') -%></a>
- </form>
- <% end %>
+ <form method="post" action="/dev/profiles/backup/<%= profile.id -%>" id="backup-<%= profile.key.parameterize -%>-form">
+ <a href="#" class="link-action" name="button_backup" id="backup_<%= u profile.key %>" onclick="$j('#backup-<%= profile.key.parameterize -%>-form').submit();return false;"><%= message('backup_verb') -%></a>
+ </form>
</td>
<td align="right">
- <% if !profile.provided? %>
- <a id="rename-<%= profile.key.parameterize -%>" href="profiles/rename_form/<%= profile.id -%>" class="link-action open-modal"><%= message('rename') -%></a>
- <% end %>
+ <a id="rename-<%= profile.key.parameterize -%>" href="profiles/rename_form/<%= profile.id -%>" class="link-action open-modal"><%= message('rename') -%></a>
</td>
<td align="right">
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/inheritance.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/inheritance.html.erb
index e4186610c66..7a0e624eb73 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/inheritance.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/inheritance.html.erb
@@ -30,10 +30,6 @@
<% if is_admin? %>
<td valign="top" width="300">
<div class="admin">
- <% if @profile.provided? %>
- <p><%= message('quality_profiles.profile_cant_be_edited') -%></p>
-
- <% else %>
<h3><%= message('quality_profiles.set_parent') -%>:</h3>
<p><%= message('quality_profiles.inherit_rules_from_profile') -%>:</p>
<% form_tag({:action => 'change_parent'}, {:method => 'post'}) do %>
@@ -41,7 +37,6 @@
<%= select_tag "parent_name", options_for_select(@select_parent, @profile.parent_name) %>
<%= submit_tag message('change_verb'), :id => 'submit_parent'%>
<% end %>
- <% end %>
</div>
</td>
<% end %>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/projects.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/projects.html.erb
index 3aa33d6a880..17dd9471ece 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/projects.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/projects.html.erb
@@ -8,7 +8,7 @@
<form method="POST" action="<%= ApplicationController.root_context -%>/profiles/add_project" id="add_project_form">
<input type="hidden" name="id" value="<%= @profile.id -%>"/>
- Add project: <%= resource_select_tag 'project_id', {
+ Add project: <%= resource_select_tag 'project', {
:qualifiers => ['TRK'],
:width => '400px',
:html_id => "select-project",
@@ -32,7 +32,7 @@
<tr class="<%= cycle('even', 'odd') -%>">
<td class="thin">
<%= link_to_action message('quality_profiles.remove_project_action'),
- "#{ApplicationController.root_context}/profiles/remove_project?id=#{@profile.id}&project_id=#{project.id}",
+ "#{ApplicationController.root_context}/profiles/remove_project?id=#{@profile.id}&project=#{project.id}",
:class => 'link-action',
:id => "link-remove-#{project.key.parameterize}",
:confirm_title => 'quality_profiles.remove_project_confirm_title',
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_active_rule_note.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_active_rule_note.html.erb
index f961277b52b..bdc7160cec8 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_active_rule_note.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_active_rule_note.html.erb
@@ -28,7 +28,7 @@
</cite>
<p><%= note.html_text -%></p>
</blockquote>
- <% elsif is_admin && !profile.provided? %>
+ <% elsif is_admin %>
<a href="#" onclick="$('<%= active_note_form_div_id -%>').show();$('<%= active_note_detail_div_id -%>').hide();$('<%= active_note_textarea_id -%>').focus(); return false;"
class="link-action spacer-right" id="<%= add_active_note_button_id -%>"><%= message('rules_configuration.add_note') -%></a>
<% end %>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb
index c89b7975006..2476e28d9b5 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb
@@ -1,6 +1,6 @@
<td nowrap valign="top" class="left" x="<%= active_rule.failure_level if active_rule -%>" width="1%">
<form id="levels_<%= rule.id -%>" action="">
- <% enable_modification = is_admin && !profile.provided?
+ <% enable_modification = is_admin
select_box_id = "levels_select_#{rule.id}"
check_box_id = "levels_check_#{rule.id}"
rule_select_box = "$('#{select_box_id}')"
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb
index e18c9baf4c2..12cb97238c1 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb
@@ -2,7 +2,7 @@
param_value = active_parameter.value if active_parameter
active_param_id = active_parameter.id if active_parameter
active_rule_id = active_rule.id if active_rule
- read_only = !active_rule || !is_admin || profile.provided?
+ read_only = !active_rule || !is_admin
%>
<td class="form-key-cell"><%= parameter.name -%></td>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb
index 0077c21985b..0ed9901a709 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb
@@ -30,15 +30,9 @@
<%= render :partial => 'profiles/tabs', :locals => {:selected_tab=>'Coding rules'} %>
-<% enable_modification = is_admin? && !@profile.provided? %>
+<% enable_modification = is_admin? %>
<div class="tabs-panel marginbottom10 background-gray">
- <% if is_admin? && @profile.provided? %>
- <div class="line-info note marginbottom10">
- <%= message('rules_configuration.profile_cant_be_updated_description') -%>
- </div>
- <% end %>
-
<% form_tag({:action => 'index'}, {:method => 'get'}) do %>
<% hidden_field_tag "id", @id %>
<table class="table" id="search_table">
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/334_remove_profiles_default_column.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/334_remove_profiles_default_column.rb
new file mode 100644
index 00000000000..185be1b3a10
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/334_remove_profiles_default_column.rb
@@ -0,0 +1,41 @@
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# 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
+#
+
+#
+# Sonar 3.3
+#
+class RemoveProfilesDefaultColumn < ActiveRecord::Migration
+
+ class Profile < ActiveRecord::Base
+ set_table_name 'rules_profiles'
+ end
+
+ class Property < ActiveRecord::Base
+ end
+
+ def self.up
+ Profile.find(:all, :conditions => ['default_profile=true']).each do |profile|
+ Property.create :prop_key => "sonar.profile.#{profile.language}", :text_value => profile.name
+ end
+
+ remove_column('rules_profiles', 'default_profile')
+ end
+
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/335_remove_profiles_provided_column.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/335_remove_profiles_provided_column.rb
new file mode 100644
index 00000000000..ccd152bcd7f
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/335_remove_profiles_provided_column.rb
@@ -0,0 +1,30 @@
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# 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
+#
+
+#
+# Sonar 3.3
+#
+class RemoveProfilesProvidedColumn < ActiveRecord::Migration
+
+ def self.up
+ remove_column('rules_profiles', 'provided')
+ end
+
+end