diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2012-10-01 11:56:14 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2012-10-01 11:56:53 +0200 |
commit | 5a11c25655690c26fb739a204f8e1883f9f12261 (patch) | |
tree | 8163cb3c6d501c4f1b5a7b913fb76ff150a9c7ed /sonar-server/src/main | |
parent | 08a2dfae36a5f246907e6c37732bb75e7c3ec683 (diff) | |
download | sonarqube-5a11c25655690c26fb739a204f8e1883f9f12261.tar.gz sonarqube-5a11c25655690c26fb739a204f8e1883f9f12261.zip |
SONAR-3833 ability to edit/delete the profiles provided by plugins
Diffstat (limited to 'sonar-server/src/main')
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 |