From 8872c32eec2b8bb07dba35d566f1135c50843383 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 27 Sep 2012 15:17:59 +0200 Subject: [PATCH] SONAR-2602 support project modules with different languages --- .../resources/org/sonar/l10n/core.properties | 14 +- .../ReferenceAnalysisTest/shared.xml | 2 +- .../shared.xml | 2 +- ...rmanentIdFromReferenceViolation-result.xml | 2 +- .../shouldSaveViolations-result.xml | 2 +- .../org/sonar/batch/DefaultProfileLoader.java | 22 +-- .../java/org/sonar/batch/ProfileProvider.java | 2 +- .../org/sonar/batch/ProjectConfigurator.java | 9 +- .../sonar/batch/config/ProjectSettings.java | 8 + .../sonar/batch/DefaultProfileLoaderTest.java | 79 +++------ .../sonar/batch/ProjectConfiguratorTest.java | 19 --- .../loadMeasuresFromDate.xml | 4 +- .../TimeMachineConfigurationTest/shared.xml | 6 +- .../DefaultResourcePersisterTest/shared.xml | 2 +- ...oveRootIndexIfResourceIsProject-result.xml | 2 +- ...ouldRemoveRootIndexIfResourceIsProject.xml | 2 +- .../shouldSaveNewDirectory-result.xml | 6 +- .../shouldSaveNewLibrary-result.xml | 6 +- ...houldSaveNewMultiModulesProject-result.xml | 10 +- .../shouldSaveNewProject-result.xml | 4 +- .../shouldUpdateExistingResource-result.xml | 2 +- .../shouldUpdateExistingResource.xml | 2 +- .../index/SourcePersisterTest/shared.xml | 2 +- .../shouldSaveSource-result.xml | 2 +- .../core/persistence/DatabaseVersion.java | 2 +- .../org/sonar/core/resource/ResourceDto.java | 10 -- .../java/org/sonar/jpa/dao/ProfilesDao.java | 11 +- .../org/sonar/core/persistence/rows-h2.sql | 1 + .../org/sonar/core/persistence/schema-h2.ddl | 1 - .../sonar/core/resource/ResourceMapper.xml | 11 +- .../org/sonar/jpa/dao/ProfilesDaoTest.java | 34 ++-- .../shouldDeleteResource.xml | 2 +- .../shouldDeleteAbortedBuilds-result.xml | 2 +- .../shouldDeleteAbortedBuilds.xml | 2 +- ...oricalDataOfDirectoriesAndFiles-result.xml | 6 +- ...eteHistoricalDataOfDirectoriesAndFiles.xml | 6 +- .../PurgeDaoTest/shouldDeleteProject.xml | 8 +- ...bleResourcesWithoutLastSnapshot-result.xml | 6 +- ...uldDisableResourcesWithoutLastSnapshot.xml | 6 +- .../shouldPurgeProject-result.xml | 2 +- .../purge/PurgeDaoTest/shouldPurgeProject.xml | 2 +- .../ResourceDaoTest/insert-result.xml | 4 +- .../ResourceDaoTest/update-result.xml | 2 +- .../core/resource/ResourceDaoTest/update.xml | 2 +- .../ResourceKeyUpdaterDaoTest/shared.xml | 16 +- .../shouldBulkUpdateKey-result.xml | 32 ++-- ...BulkUpdateKeyOnOnlyOneSubmodule-result.xml | 32 ++-- .../shouldNotUpdateAllSubmodules-result.xml | 28 ++-- .../shouldNotUpdateAllSubmodules.xml | 28 ++-- .../shouldUpdateKey-result.xml | 18 +- .../api/database/model/ResourceModel.java | 14 -- .../org/sonar/api/profiles/RulesProfile.java | 25 --- .../server/configuration/ProfilesManager.java | 30 ---- .../java/org/sonar/server/ui/JRubyFacade.java | 8 - .../app/controllers/application_controller.rb | 17 ++ .../app/controllers/profiles_controller.rb | 154 ++++++++++-------- .../app/controllers/project_controller.rb | 28 ++-- .../WEB-INF/app/helpers/application_helper.rb | 6 +- .../webapp/WEB-INF/app/models/api/utils.rb | 4 + .../main/webapp/WEB-INF/app/models/profile.rb | 147 +++++++++++------ .../main/webapp/WEB-INF/app/models/project.rb | 5 +- .../webapp/WEB-INF/app/models/property.rb | 16 +- .../app/views/layouts/_layout.html.erb | 4 +- .../app/views/profiles/_copy_form.html.erb | 14 +- .../app/views/profiles/_rename_form.html.erb | 6 +- .../WEB-INF/app/views/profiles/index.html.erb | 9 +- .../app/views/profiles/projects.html.erb | 115 ++++++++----- .../app/views/project/profile.html.erb | 40 +++++ .../views/project/quality_profile.html.erb | 23 --- .../migrate/331_remove_projects_profile_id.rb | 45 +++++ .../configuration/InheritedProfilesTest.java | 14 -- .../configuration/ProfilesManagerTest.java | 33 +--- ...shouldNotDeleteInheritedProfile-result.xml | 12 -- .../shouldRenameInheritedProfile-result.xml | 12 -- .../filters/FilterExecutorTest/measures.xml | 4 +- .../filters/FilterExecutorTest/shared.xml | 6 +- .../filters/FilterExecutorTest/views.xml | 8 +- 77 files changed, 632 insertions(+), 652 deletions(-) create mode 100644 sonar-server/src/main/webapp/WEB-INF/app/views/project/profile.html.erb delete mode 100644 sonar-server/src/main/webapp/WEB-INF/app/views/project/quality_profile.html.erb create mode 100644 sonar-server/src/main/webapp/WEB-INF/db/migrate/331_remove_projects_profile_id.rb delete mode 100644 sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldNotDeleteInheritedProfile-result.xml delete mode 100644 sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldRenameInheritedProfile-result.xml diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties index bafe68fcfaa..267ccceeffe 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -75,6 +75,7 @@ min=Min minor=Minor more_actions=More actions name=Name +name_too_long_x=Name is too long (maximum is {0} characters) none=None off=Off on=On @@ -94,6 +95,7 @@ plugin=Plugin project=Project projects=Projects raw=Raw +remove=Remove rename=Rename reset_verb=Reset result=Result @@ -132,6 +134,7 @@ unselect_all=Unselect all unselect_verb=Unselect updated=Updated update_verb=Update +updating=Updating user=User value=Value variation=Variation @@ -141,6 +144,7 @@ views=Views violations=Violations + #------------------------------------------------------------------------------ # # GENERIC EXPRESSIONS, sorted alphabetically @@ -1094,10 +1098,7 @@ update_key.no_key_to_update=No key contains the string to replace ("{0}"). # PROJECT QUALITY PROFILE PAGE # #------------------------------------------------------------------------------ -project_quality_profile.select_profile_for_x=Select the quality profile to be used when analyzing the "{0}" project: -project_quality_profile.project_cannot_be_update_with_profile_x=The current project can not be updated with the following profile: "{0}". -project_quality_profile.profile_successfully_updated=Quality profile successfully updated. -project_quality_profile.default_profile=default +project_quality_profile.default_profile=Default #------------------------------------------------------------------------------ @@ -1153,7 +1154,6 @@ quality_profiles.are_you_sure_want_x_profile_as_default=Are you sure that you wa quality_profiles.profile_x_created=Profile "{0}" created. Set it as default or link it to a project to use it for next measures. quality_profiles.already_exists=This profile already exists. quality_profiles.please_type_profile_name=Please type a profile name. -quality_profiles.delete_confirm_title=Delete Profile quality_profiles.profile_x_deleted=Profile "{0}" is deleted. quality_profiles.default_profile_is_x=Default profile is "{0}". quality_profiles.profile_x_not_activated=Profile "{0}" is created but not activated. @@ -1193,7 +1193,9 @@ quality_profiles.with_same_configuration=With same configuration quality_profiles.x_rules_only_in={0} rules only in quality_profiles.x_rules_have_different_configuration={0} rules have a different configuration quality_profiles.export_all_rules=All rules - +quality_profiles.remove_projects_action=Remove All +quality_profiles.copy_x_title=Copy Profile {0} +quality_profiles.copy_new_name=New Name #------------------------------------------------------------------------------ # diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ReferenceAnalysisTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ReferenceAnalysisTest/shared.xml index dd96aeecbf1..cca1757cb78 100644 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ReferenceAnalysisTest/shared.xml +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ReferenceAnalysisTest/shared.xml @@ -2,7 +2,7 @@ + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> " profile would have been created by ActivateDefaultProfiles class. - throw new SonarException("You must intall a Sonar plugin that supports language '" + root.getLanguageKey() - + "' in order to analyse the following project: " + root.getKey()); + throw new SonarException("You must install a plugin that supports the language '" + project.getLanguageKey() + "'"); } - } else { profile = dao.getProfile(project.getLanguageKey(), profileName); if (profile == null) { @@ -56,6 +57,7 @@ public class DefaultProfileLoader implements ProfileLoader { // hack to lazy initialize the profile collections profile.getActiveRules().size(); + for (ActiveRule activeRule : profile.getActiveRules()) { activeRule.getActiveRuleParams().size(); activeRule.getRule().getParams().size(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java b/sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java index a274827ee36..22a8c030108 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java @@ -34,7 +34,7 @@ public class ProfileProvider extends ProviderAdapter { public RulesProfile provide(Project project, ProfileLoader profileLoader) { if (profile == null) { profile = profileLoader.load(project); - LOG.info("Selected quality profile : {}", profile); + LOG.info("Quality profile : {}", profile); } return profile; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectConfigurator.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfigurator.java index 139c296fad7..1ea83f62df9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectConfigurator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfigurator.java @@ -73,8 +73,7 @@ public class ProjectConfigurator implements BatchComponent { .setAnalysisDate(analysisDate) .setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate)) .setAnalysisVersion(loadAnalysisVersion()) - .setAnalysisType(loadAnalysisType()) - .setLanguageKey(loadLanguageKey()); + .setAnalysisType(loadAnalysisType()); return this; } @@ -88,7 +87,7 @@ public class ProjectConfigurator implements BatchComponent { } Date loadAnalysisDate() { - Date date = null; + Date date; try { // sonar.projectDate may have been specified as a time date = settings.getDateTime(CoreProperties.PROJECT_DATE_PROPERTY); @@ -119,8 +118,4 @@ public class ProjectConfigurator implements BatchComponent { String loadAnalysisVersion() { return settings.getString(CoreProperties.PROJECT_VERSION_PROPERTY); } - - String loadLanguageKey() { - return StringUtils.defaultIfBlank(settings.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY), Java.KEY); - } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java b/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java index d470a9cdb02..aca22d363f4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java @@ -26,6 +26,7 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; +import org.sonar.api.resources.Java; import org.sonar.api.resources.Project; import org.sonar.core.config.ConfigurationUtils; import org.sonar.core.properties.PropertiesDao; @@ -48,6 +49,13 @@ public class ProjectSettings extends Settings { this.projectDefinition = projectDefinition; this.propertiesDao = propertiesDao; load(); + updateProject(project); + } + + private void updateProject(Project project) { + // The class org.sonar.api.batch.Project should be deeply refactored and should load language from settings. + // Meanwhile the language must be updated : + project.setLanguageKey(StringUtils.defaultIfBlank(getString("sonar.language"), Java.KEY)); } public ProjectSettings load() { diff --git a/sonar-batch/src/test/java/org/sonar/batch/DefaultProfileLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/DefaultProfileLoaderTest.java index 735c21c7130..9d50aadfb9b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/DefaultProfileLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/DefaultProfileLoaderTest.java @@ -19,104 +19,75 @@ */ package org.sonar.batch; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Collections; -import java.util.HashMap; - -import org.apache.commons.configuration.MapConfiguration; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.profiles.Alert; +import org.sonar.api.config.Settings; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.Java; import org.sonar.api.resources.Project; -import org.sonar.api.rules.ActiveRule; import org.sonar.api.utils.SonarException; import org.sonar.jpa.dao.ProfilesDao; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + public class DefaultProfileLoaderTest { @Rule public ExpectedException thrown = ExpectedException.none(); private ProfilesDao dao; - private ProfileLoader loader; + private Project javaProject = new Project("project").setLanguageKey(Java.KEY); @Before public void setUp() { dao = mock(ProfilesDao.class); - loader = new DefaultProfileLoader(dao); } @Test - public void shouldGetProjectProfile() { - Project project = new Project("project").setLanguageKey(Java.KEY); - Project module = new Project("module").setParent(project).setLanguageKey(Java.KEY); + public void should_get_configured_profile() { + Settings settings = new Settings(); + settings.setProperty("sonar.profile.java", "legacy profile"); + when(dao.getProfile(Java.KEY, "legacy profile")).thenReturn(RulesProfile.create("legacy profile", "java")); - when(dao.getActiveProfile(Java.KEY, "project")).thenReturn(newProfile()); + RulesProfile profile = new DefaultProfileLoader(dao, settings).load(javaProject); - assertNotNull(loader.load(module)); - - verify(dao, never()).getActiveProfile(Java.KEY, "module"); - verify(dao).getActiveProfile(Java.KEY, "project"); - } - - private RulesProfile newProfile() { - RulesProfile profile = new RulesProfile(); - profile.setAlerts(Collections. emptyList()); - profile.setActiveRules(Collections. emptyList()); - return profile; + assertThat(profile.getName()).isEqualTo("legacy profile"); } @Test - public void mavenPropertyShouldOverrideProfile() { - Project project = new Project("project").setLanguageKey(Java.KEY); - - MapConfiguration conf = new MapConfiguration(new HashMap()); - conf.addProperty(DefaultProfileLoader.PARAM_PROFILE, "profile1"); - project.setConfiguration(conf); + public void should_get_default_profile() { + Settings settings = new Settings(); + when(dao.getDefaultProfile(Java.KEY)).thenReturn(RulesProfile.create("default profile", "java")); - when(dao.getProfile(Java.KEY, "profile1")).thenReturn(newProfile()); + RulesProfile profile = new DefaultProfileLoader(dao, settings).load(javaProject); - loader.load(project); - - verify(dao).getProfile(Java.KEY, "profile1"); - verify(dao, never()).getActiveProfile(Java.KEY, "project"); + assertThat(profile.getName()).isEqualTo("default profile"); } @Test - public void shouldFailIfProfileIsNotFound() { - Project project = new Project("project").setLanguageKey(Java.KEY); - - MapConfiguration conf = new MapConfiguration(new HashMap()); - conf.addProperty(DefaultProfileLoader.PARAM_PROFILE, "unknown"); - project.setConfiguration(conf); - - when(dao.getProfile(Java.KEY, "profile1")).thenReturn(null); + public void should_fail_if_not_found() { + Settings settings = new Settings(); + settings.setProperty("sonar.profile.java", "unknown"); thrown.expect(SonarException.class); thrown.expectMessage("Quality profile not found : unknown, language java"); - loader.load(project); + new DefaultProfileLoader(dao, settings).load(javaProject); } /** * SONAR-3125 */ @Test - public void shouldGiveExplicitMessageIfNoProfileFound() { - Project project = new Project("foo:project").setLanguageKey("unknown-language"); - when(dao.getProfile(Java.KEY, "profile1")).thenReturn(null); + public void should_give_explicit_message_if_default_profile_not_found() { + Project cobolProject = new Project("cobol-javaProject").setLanguageKey("cobol"); thrown.expect(SonarException.class); - thrown.expectMessage("You must intall a Sonar plugin that supports language 'unknown-language' in order to analyse the following project: foo:project"); - loader.load(project); + thrown.expectMessage("You must install a plugin that supports the language 'cobol'"); + new DefaultProfileLoader(dao, new Settings()).load(cobolProject); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectConfiguratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectConfiguratorTest.java index 1d60f84f59b..4db0e9f4c5a 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/ProjectConfiguratorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/ProjectConfiguratorTest.java @@ -36,25 +36,6 @@ import static org.junit.Assert.assertTrue; public class ProjectConfiguratorTest extends AbstractDbUnitTestCase { - @Test - public void getLanguageFromConfiguration() { - Settings configuration = new Settings(); - configuration.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "foo"); - - Project project = new Project("key"); - new ProjectConfigurator(getSession(), configuration).configure(project); - - assertThat(project.getLanguageKey(), is("foo")); - } - - @Test - public void defaultLanguageIsJava() { - Project project = new Project("key"); - new ProjectConfigurator(getSession(), new Settings()).configure(project); - - assertThat(project.getLanguageKey(), is(Java.KEY)); - } - @Test public void analysisIsTodayByDefault() { Project project = new Project("key"); diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultTimeMachineTest/loadMeasuresFromDate.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultTimeMachineTest/loadMeasuresFromDate.xml index 3a6d76cabaf..fef06b0f60d 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/DefaultTimeMachineTest/loadMeasuresFromDate.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultTimeMachineTest/loadMeasuresFromDate.xml @@ -6,10 +6,10 @@ + description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/TimeMachineConfigurationTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/TimeMachineConfigurationTest/shared.xml index 65c8a495038..c8796e2bb80 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/components/TimeMachineConfigurationTest/shared.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/TimeMachineConfigurationTest/shared.xml @@ -1,12 +1,12 @@ + root_id="[null]" description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> + root_id="[null]" description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> + root_id="2" description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> diff --git a/sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shared.xml index cff08ac82fe..4eaddace0e1 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shared.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shared.xml @@ -3,7 +3,7 @@ + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> + enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" /> - @@ -86,11 +85,11 @@ insert into projects - (name, long_name, description, scope, qualifier, kee, language, root_id, copy_resource_id, person_id, profile_id, enabled, created_at) + (name, long_name, description, scope, qualifier, kee, language, root_id, copy_resource_id, person_id, enabled, created_at) values ( #{name}, #{longName}, #{description}, #{scope}, #{qualifier}, #{key}, #{language}, #{rootId}, #{copyResourceId}, - #{personId}, #{profileId}, #{enabled}, #{createdAt} + #{personId}, #{enabled}, #{createdAt} ) @@ -100,11 +99,11 @@ select projects_seq.NEXTVAL from DUAL insert into projects - (id, name, long_name, description, scope, qualifier, kee, language, root_id, copy_resource_id, person_id, profile_id, enabled, created_at) + (id, name, long_name, description, scope, qualifier, kee, language, root_id, copy_resource_id, person_id, enabled, created_at) values ( #{id}, #{name}, #{longName}, #{description}, #{scope}, #{qualifier}, #{key}, #{language}, #{rootId}, #{copyResourceId}, - #{personId}, #{profileId}, #{enabled}, #{createdAt} + #{personId}, #{enabled}, #{createdAt} ) @@ -112,7 +111,7 @@ update projects set name=#{name}, long_name=#{longName}, description=#{description}, scope=#{scope}, qualifier=#{qualifier}, kee=#{key}, language=#{language}, root_id=#{rootId}, copy_resource_id=#{copyResourceId}, - person_id=#{personId}, profile_id=#{profileId}, enabled=#{enabled} where id=#{id} + person_id=#{personId}, enabled=#{enabled} where id=#{id} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/ProfilesDaoTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/ProfilesDaoTest.java index 0ab2cf17506..01f7310fca0 100644 --- a/sonar-core/src/test/java/org/sonar/jpa/dao/ProfilesDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/jpa/dao/ProfilesDaoTest.java @@ -21,12 +21,10 @@ package org.sonar.jpa.dao; import org.junit.Before; import org.junit.Test; -import org.sonar.api.database.model.ResourceModel; import org.sonar.api.profiles.RulesProfile; import org.sonar.jpa.test.AbstractDbUnitTestCase; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.fest.assertions.Assertions.assertThat; public class ProfilesDaoTest extends AbstractDbUnitTestCase { @@ -37,22 +35,24 @@ public class ProfilesDaoTest extends AbstractDbUnitTestCase { profilesDao = new ProfilesDao(getSession()); } + @Test + public void should_get_profile_by_name() { + RulesProfile profile = RulesProfile.create("my profile", "java"); + getSession().save(profile); + + assertThat(profilesDao.getProfile("unknown language", "my profile")).isNull(); + assertThat(profilesDao.getProfile("java", "my profile").getName()).isEqualTo("my profile"); + } @Test - public void testGetActiveProfile() { - RulesProfile testDefaultProfile = new RulesProfile("default", "java", true, true); - RulesProfile testProfile = new RulesProfile("not default", "java", false, false); - getSession().save(testDefaultProfile, testProfile); - - ResourceModel testResourceWithProfile = new ResourceModel(ResourceModel.SCOPE_PROJECT, "withProfile", "TRK", null, "test"); - testResourceWithProfile.setRulesProfile(testProfile); - ResourceModel testResourceWithNoProfile = new ResourceModel(ResourceModel.SCOPE_PROJECT, "withoutProfile", "TRK", null, "test"); - getSession().save(testResourceWithProfile, testResourceWithNoProfile); - - assertNull(profilesDao.getActiveProfile("wrongLanguage", "withoutProfile")); - assertEquals(testDefaultProfile.getId(), profilesDao.getActiveProfile("java", "wrongKey").getId()); - assertEquals(testDefaultProfile.getId(), profilesDao.getActiveProfile("java", "withoutProfile").getId()); - assertEquals(testProfile.getId(), profilesDao.getActiveProfile("java", "withProfile").getId()); + public void should_get_default_profile() { + RulesProfile defaultProfile = RulesProfile.create("default profile", "java"); + defaultProfile.setDefaultProfile(true); + RulesProfile otherProfile = RulesProfile.create("other profile", "java"); + otherProfile.setDefaultProfile(false); + getSession().save(defaultProfile, otherProfile); + + assertThat(profilesDao.getDefaultProfile("java").getName()).isEqualTo("default profile"); } } diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml index d9fe0172ed6..ff3b37a56ea 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml @@ -2,7 +2,7 @@ + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> + root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml index a38c88faa59..23490655cbe 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml @@ -3,7 +3,7 @@ + root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" /> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/insert-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/insert-result.xml index 0b7b9325056..27016ad3471 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/insert-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/insert-result.xml @@ -2,10 +2,10 @@ + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" /> + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" /> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update-result.xml index 05ef16cbee5..4a59dd793f1 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update-result.xml @@ -2,6 +2,6 @@ + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update.xml index 74ff92ef743..dcd5ae6480b 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update.xml @@ -2,6 +2,6 @@ + enabled="[false]" language="old" copy_resource_id="2" person_id="3" created_at="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shared.xml index dff49673540..4613c167d31 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shared.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shared.xml @@ -2,49 +2,49 @@ diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKey-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKey-result.xml index a4b3fdd195e..b9fc934e546 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKey-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKey-result.xml @@ -2,49 +2,49 @@ + description="[null]" long_name="Apache Struts" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts UI" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Foo Struts Core" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml index 40bb3ed144d..71ed68a61ae 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml @@ -2,49 +2,49 @@ + description="[null]" long_name="Apache Struts" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts UI" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Foo Struts Core" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules-result.xml index 6ebe224cfaf..54bf43d5802 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules-result.xml @@ -2,43 +2,43 @@ + description="[null]" long_name="Apache Struts" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts UI" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules.xml index 1b33265baeb..93f747e9d72 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules.xml @@ -2,43 +2,43 @@ + description="[null]" long_name="Apache Struts" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + scope="PRJ" qualifier="BRC" long_name="Struts UI" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> + description="[null]" + enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldUpdateKey-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldUpdateKey-result.xml index 5680e1d1814..178b172ddd0 100644 --- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldUpdateKey-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldUpdateKey-result.xml @@ -2,7 +2,7 @@ @@ -10,43 +10,43 @@ + scope="PRJ" qualifier="BRC" long_name="Struts Core" + description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java index 35a6e481340..59b735a0138 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java @@ -25,7 +25,6 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.hibernate.annotations.BatchSize; import org.sonar.api.database.BaseIdentifiable; -import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.ProjectLink; import org.sonar.api.resources.Resource; @@ -99,10 +98,6 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { @BatchSize(size = 8) private List projectLinks = new ArrayList(); - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "profile_id", updatable = true, nullable = true) - private RulesProfile rulesProfile; - /** * Default constructor */ @@ -264,14 +259,6 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { this.rootId = rootId; } - public RulesProfile getRulesProfile() { - return rulesProfile; - } - - public void setRulesProfile(RulesProfile rulesProfile) { - this.rulesProfile = rulesProfile; - } - public String getQualifier() { return qualifier; } @@ -337,7 +324,6 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { clone.setDescription(getDescription()); clone.setEnabled(getEnabled()); clone.setProjectLinks(getProjectLinks()); - clone.setRulesProfile(getRulesProfile()); clone.setLanguageKey(getLanguageKey()); clone.setCopyResourceId(getCopyResourceId()); clone.setLongName(getLongName()); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java index a06e887c02d..171f2e92219 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java @@ -91,9 +91,6 @@ public class RulesProfile implements Cloneable { @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}) private List alerts = Lists.newArrayList(); - @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY) - private List projects = Lists.newArrayList(); - /** * @deprecated use the factory method create() */ @@ -110,7 +107,6 @@ public class RulesProfile implements Cloneable { this.language = language; this.activeRules = Lists.newArrayList(); this.alerts = Lists.newArrayList(); - this.projects = Lists.newArrayList(); } /** @@ -290,20 +286,6 @@ public class RulesProfile implements Cloneable { this.alerts = alerts; } - /** - * @return the list of projects attached to the profile - */ - public List getProjects() { - return projects; - } - - /** - * Sets the list of projects attached to the profile - */ - public void setProjects(List projects) { - this.projects = projects; - } - /** * Note: disabled rules are excluded. * @@ -424,13 +406,6 @@ public class RulesProfile implements Cloneable { } }))); } - if (CollectionUtils.isNotEmpty(getProjects())) { - clone.setProjects(new ArrayList(CollectionUtils.collect(getProjects(), new Transformer() { - public Object transform(Object input) { - return ((ResourceModel) input).clone(); - } - }))); - } return clone; } 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 bd7b1921eb0..54fbae8b538 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 @@ -22,7 +22,6 @@ package org.sonar.server.configuration; import org.apache.commons.lang.ObjectUtils; import org.codehaus.plexus.util.StringUtils; import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.ResourceModel; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.rules.*; import org.sonar.api.utils.ValidationMessages; @@ -40,20 +39,6 @@ public class ProfilesManager extends BaseDao { this.rulesDao = rulesDao; } - public void renameProfile(int profileId, String newProfileName) { - RulesProfile profile = getSession().getSingleResult(RulesProfile.class, "id", profileId); - if (profile != null && !profile.getProvided()) { - String hql = "UPDATE " + RulesProfile.class.getSimpleName() + " o SET o.parentName=:newName WHERE o.parentName=:oldName"; - getSession().getEntityManager().createQuery(hql) - .setParameter("oldName", profile.getName()) - .setParameter("newName", newProfileName) - .executeUpdate(); - profile.setName(newProfileName); - getSession().save(profile); - getSession().commit(); - } - } - public void copyProfile(int profileId, String newProfileName) { RulesProfile profile = getSession().getSingleResult(RulesProfile.class, "id", profileId); RulesProfile toImport = (RulesProfile) profile.clone(); @@ -65,27 +50,12 @@ public class ProfilesManager extends BaseDao { getSession().commit(); } - public void deleteProfile(int profileId) { - RulesProfile profile = getSession().getEntity(RulesProfile.class, profileId); - if (profile != null && !profile.getProvided() && getChildren(profile).isEmpty()) { - // Remove history of rule changes - String hqlDeleteRc = "DELETE " + ActiveRuleChange.class.getSimpleName() + " rc WHERE rc.rulesProfile=:rulesProfile"; - getSession().createQuery(hqlDeleteRc).setParameter("rulesProfile", profile).executeUpdate(); - - String hql = "UPDATE " + ResourceModel.class.getSimpleName() + " o SET o.rulesProfile=null WHERE o.rulesProfile=:rulesProfile"; - getSession().createQuery(hql).setParameter("rulesProfile", profile).executeUpdate(); - getSession().remove(profile); - getSession().commit(); - } - } public void deleteAllProfiles() { // Remove history of rule changes String hqlDeleteRc = "DELETE " + ActiveRuleChange.class.getSimpleName() + " rc"; getSession().createQuery(hqlDeleteRc).executeUpdate(); - String hql = "UPDATE " + ResourceModel.class.getSimpleName() + " o SET o.rulesProfile = null WHERE o.rulesProfile IS NOT NULL"; - getSession().createQuery(hql).executeUpdate(); List profiles = getSession().createQuery("FROM " + RulesProfile.class.getSimpleName()).getResultList(); for (Object profile : profiles) { getSession().removeWithoutFlush(profile); diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 85f177aaec9..3738332bdcc 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -280,18 +280,10 @@ public final class JRubyFacade { return get(ProfilesConsole.class).getProfileExporter(exporterKey).getMimeType(); } - public void renameProfile(int profileId, String newProfileName) { - getProfilesManager().renameProfile(profileId, newProfileName); - } - public void copyProfile(long profileId, String newProfileName) { getProfilesManager().copyProfile((int) profileId, newProfileName); } - public void deleteProfile(long profileId) { - getProfilesManager().deleteProfile((int) profileId); - } - public ValidationMessages changeParentProfile(int profileId, String parentName, String userName) { return getProfilesManager().changeParentProfile(profileId, parentName, userName); } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/application_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/application_controller.rb index 8636de40e54..e125aaefe2d 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/application_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/application_controller.rb @@ -125,6 +125,23 @@ class ApplicationController < ActionController::Base raise Errors::AccessDenied end + # since 3.3 + def require_parameters(*keys) + keys.each do |key| + bad_request("Missing parameter: #{key}") if params[key].blank? + end + end + + # since 3.3 + def verify_post_request + bad_request('Not a POST request') unless request.post? + end + + # since 3.3 + def verify_ajax_request + bad_request('Not an AJAX request') unless request.xhr? + end + def render_not_found(error) render :file => "#{Rails.public_path}/404.html", :status => 404 end 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 d380dbff837..50fbf55c26f 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 @@ -20,38 +20,37 @@ class ProfilesController < ApplicationController SECTION=Navigation::SECTION_CONFIGURATION - # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) - verify :method => :post, :only => ['create', 'delete', 'copy', 'set_as_default', 'restore', 'set_projects', 'rename', 'change_parent'], :redirect_to => {:action => 'index'} - # the backup action is allow to non-admin users : see http://jira.codehaus.org/browse/SONAR-2039 before_filter :admin_required, :only => ['create', 'delete', 'set_as_default', 'copy', 'restore', 'change_parent', 'set_projects', 'rename_form', 'rename'] # GET /profiles/index def index - @profiles = Profile.find(:all, :conditions => ['enabled=?', true], :order => 'name') + @profiles = Profile.find(:all, :order => 'name') end # GET /profiles/show/ def show + require_parameters 'id' @profile = Profile.find(params[:id]) end # GET /profiles/create_form?language= def create_form - language = params[:language] - bad_request 'Missing parameter: language' if language.blank? - profile = Profile.new(:language => language) - render :partial => 'profiles/create_form', :locals => {:language_key => language} + require_parameters 'language' + render :partial => 'profiles/create_form', :locals => {:language_key => params[:language]} end # POST /profiles/create?name=&language=&[backup=] def create + verify_post_request + require_parameters 'language' + profile_name=params[:name] language=params[:language] - profile = Profile.create(:name => profile_name, :language => language, :default_profile => false, :enabled => true) + profile = Profile.create(:name => profile_name, :language => language, :default_profile => false) ok = profile.errors.empty? if ok && params[:backup] params[:backup].each_pair do |importer_key, file| @@ -75,9 +74,12 @@ class ProfilesController < ApplicationController # POST /profiles/delete/ def delete + verify_post_request + require_parameters 'id' + @profile = Profile.find(params[:id]) if @profile && @profile.deletable? - java_facade.deleteProfile(@profile.id) + @profile.destroy end redirect_to(:controller => 'profiles', :action => 'index') end @@ -85,40 +87,50 @@ class ProfilesController < ApplicationController # POST /profiles/set_as_default/ def set_as_default + verify_post_request + require_parameters 'id' + profile = Profile.find(params[:id]) profile.set_as_default - flash[:notice]=message('quality_profiles.default_profile_is_x', :params => profile.name) + #TODO remove l10n key: flash[:notice]=message('quality_profiles.default_profile_is_x', :params => profile.name) redirect_to :action => 'index' end # GET /profiles/copy_form/ def copy_form + require_parameters 'id' @profile = Profile.find(params[:id]) render :partial => 'profiles/copy_form' end # POST /profiles/copy/?name= def copy - render :text => 'Not an ajax request', :status => '400' unless request.xhr? + verify_post_request + verify_ajax_request + require_parameters 'id' @profile = Profile.find(params[:id]) name = params['name'] - validation_errors = @profile.validate_copy(name) - if validation_errors.empty? + target_profile=Profile.new(:name => name, :language => @profile.language, :provided => false, :default_profile => false) + if target_profile.valid? java_facade.copyProfile(@profile.id, name) flash[:notice]= message('quality_profiles.profile_x_not_activated', :params => name) render :text => 'ok', :status => 200 else - @error = validation_errors.full_messages.first + @errors = [] + target_profile.errors.each{|attr,msg| @errors< 'profiles/copy_form', :status => 400 end end - # POST /profiles/backup/ + # POST /profiles/backup?id= def backup + verify_post_request + require_parameters 'id' + profile = Profile.find(params[:id]) xml = java_facade.backupProfile(profile.id) filename=profile.name.gsub(' ', '_') @@ -129,11 +141,13 @@ class ProfilesController < ApplicationController # Modal window to restore profile backup # GET /profiles/restore_form/ def restore_form + verify_ajax_request render :partial => 'profiles/restore_form' end # POST /profiles/restore?backup= def restore + verify_post_request if params[:backup].blank? flash[:warning]=message('quality_profiles.please_upload_backup_file') else @@ -148,7 +162,7 @@ class ProfilesController < ApplicationController def export language = params[:language] if (params[:name].blank?) - profile = Profile.find_active_profile_by_language(language) + profile = Profile.by_default(language) else profile = Profile.find_by_name_and_language(CGI::unescape(params[:name]), language) end @@ -165,24 +179,18 @@ class ProfilesController < ApplicationController end end - # - # # GET /profiles/inheritance?id= - # - # def inheritance + require_parameters 'id' @profile = Profile.find(params[:id]) - profiles=Profile.find(:all, :conditions => ['language=? and id<>? and (parent_name is null or parent_name<>?) and enabled=?', @profile.language, @profile.id, @profile.name, true], :order => 'name') + profiles=Profile.find(:all, :conditions => ['language=? and id<>? and (parent_name is null or parent_name<>?)', @profile.language, @profile.id, @profile.name], :order => 'name') @select_parent = [[message('none'), nil]] + profiles.collect { |profile| [profile.name, profile.name] } end - # - # # GET /profiles/changelog?id= - # - # def changelog + require_parameters 'id' @profile = Profile.find(params[:id]) versions = ActiveRuleChange.find(:all, :select => 'profile_version, MAX(change_date) AS change_date', :conditions => ['profile_id=?', @profile.id], :group => 'profile_version') @@ -210,12 +218,11 @@ class ProfilesController < ApplicationController end - # - # # POST /profiles/change_parent?id=&parent_name= - # - # def change_parent + verify_post_request + require_parameters 'id' + id = params[:id].to_i parent_name = params[:parent_name] if parent_name.blank? @@ -234,6 +241,7 @@ class ProfilesController < ApplicationController # # def permalinks + require_parameters 'id' @profile = Profile.find(params[:id]) end @@ -244,62 +252,68 @@ class ProfilesController < ApplicationController # # def projects + require_parameters 'id' @profile = Profile.find(params[:id]) - @available_projects=Project.find(:all, - :include => ['profile', 'snapshots'], - :conditions => ['projects.qualifier=? AND projects.scope=? AND snapshots.islast=?', Project::QUALIFIER_PROJECT, Project::SCOPE_SET, true], - :order => 'projects.name asc') - @available_projects-=@profile.projects end - # - # - # POST /profiles/set_projects/?projects= - # - # - def set_projects - @profile = Profile.find(params[:id]) - @profile.projects.clear + # POST /profiles/add_project?id=&project_id= + def add_project + verify_post_request + require_parameters 'id', 'project_id' + admin_required + + profile=Profile.find(params[:id]) + bad_request('Unknown profile') unless profile + project=Project.find(params[:project_id]) + bad_request('Unknown project') unless project - projects=Project.find(params[:projects] || []) - @profile.projects=projects - flash[:notice]=message('quality_profiles.profile_x_associated_to_x_projects', :params => [@profile.name, projects.size]) - redirect_to :action => 'projects', :id => @profile.id + profile.add_project_id(project.id) + redirect_to :action => 'projects', :id => profile.id end + # POST /profiles/remove_project?id=&project_id= + def remove_project + verify_post_request + require_parameters 'id', 'project_id' + admin_required + + profile=Profile.find(params[:id]) + bad_request('Unknown profile') unless profile + + Profile.reset_default_profile_for_project_id(profile.language, params[:project_id]) + redirect_to :action => 'projects', :id => profile.id + end + + # POST /profiles/remove_projects?id= + def remove_projects + verify_post_request + require_parameters 'id' + admin_required + + profile=Profile.find(params[:id]) + bad_request('Unknown profile') unless profile + + profile.remove_projects + redirect_to :action => 'projects', :id => profile.id + end # GET /profiles/rename_form?id= def rename_form + require_parameters 'id' @profile = Profile.find(params[:id]) render :partial => 'profiles/rename_form' end - # - # # POST /profiles/rename?id=&name= - # - # def rename - render :text => 'Not an ajax request', :status => '400' unless request.xhr? + verify_post_request + verify_ajax_request + require_parameters 'id' @profile = Profile.find(params[:id]) - name = params[:name] - success=false - if name.blank? - @error=message('quality_profiles.profile_name_cant_be_blank') - else - existing=Profile.find(:first, :conditions => {:name => name, :language => @profile.language, :enabled => true}) - if existing - @error=message('quality_profiles.already_exists') - elsif !@profile.provided? - java_facade.renameProfile(@profile.id, name) - success=true - end - end - - if success + if @profile.rename(params[:name]).errors.empty? render :text => 'ok', :status => 200 else render :partial => 'profiles/rename_form', :status => 400 @@ -307,13 +321,9 @@ class ProfilesController < ApplicationController end - # - # # GET /profiles/compare?id1=&id2= - # - # def compare - @profiles = Profile.find(:all, :conditions => ['enabled=?', true], :order => 'language asc, name') + @profiles = Profile.find(:all, :order => 'language asc, name') if params[:id1].present? && params[:id2].present? @profile1 = Profile.find(params[:id1]) @profile2 = Profile.find(params[:id2]) diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb index a993d5331ec..5e59296c6e3 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb @@ -18,7 +18,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 # class ProjectController < ApplicationController - verify :method => :post, :only => [:set_links, :set_exclusions, :delete_exclusions, :update_key, :perform_key_bulk_update, :update_quality_profile], + verify :method => :post, :only => [:set_links, :set_exclusions, :delete_exclusions, :update_key, :perform_key_bulk_update], :redirect_to => {:action => :index} verify :method => :delete, :only => [:delete], :redirect_to => {:action => :index} @@ -75,25 +75,29 @@ class ProjectController < ApplicationController redirect_to :action => 'deletion', :id => params[:id] end - def quality_profile + # GET /project/profile?id= + def profile + require_parameters :id @project = get_current_project(params[:id]) - @profiles = Profile.find(:all, :conditions => {:language => @project.language, :enabled => true}) end - def update_quality_profile + # POST /project/set_profile?id=&language=[&profile_id=] + def set_profile + require_parameters :id, :language + verify_post_request + + language=params[:language] project = get_current_project(params[:id]) - selected_profile = Profile.find(:first, :conditions => {:id => params[:quality_profile].to_i}) - if selected_profile && selected_profile.language == project.language - project.profile = selected_profile - project.save! - flash[:notice] = message('project_quality_profile.profile_successfully_updated') + if params[:profile_id].blank? + Profile.reset_default_profile_for_project_id(language, project.id) else - selected_profile_name = selected_profile ? selected_profile.name + "(" + selected_profile.language + ")" : "Unknown profile" - flash[:error] = message('project_quality_profile.project_cannot_be_update_with_profile_x', :params => selected_profile_name) + profile = Profile.find(params[:profile_id]) + bad_request('Bad language') if profile.language!=language + profile.add_project_id(project.id) end - redirect_to :action => 'quality_profile', :id => project.id + redirect_to :action => 'profile', :id => project.id end def key diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb index 39b9ac0f3ab..8720d718e20 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb @@ -721,7 +721,7 @@ module ApplicationHelper end # - # Creates a button linked to a POST action. A confirmation popup is opened when user clicks on the button. + # Creates a link linked to a POST action. A confirmation popup is opened when user clicks on the button. # ==== Options # * :id - HTML ID of the button # * :class - Additional CSS class, generally 'red-button' for deletions @@ -731,7 +731,7 @@ module ApplicationHelper # * :message_params - # * :width - width in pixels # - def button_to_action(label, post_url, options={}) + def link_to_action(label, post_url, options={}) clazz = options[:class] id = "id='#{options[:id]}'" if options[:id] title_key = options[:title_key] @@ -750,6 +750,6 @@ module ApplicationHelper url += "&bk=#{button_key}" end - "#{h label}" + "#{h label}" end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb index ddf214b88e2..81e74632ca9 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb @@ -169,4 +169,8 @@ class Api::Utils def self.java_facade Java::OrgSonarServerUi::JRubyFacade.getInstance() end + + def self.languages + java_facade.getLanguages() + end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb index 079645ff6c6..a9bb3d3a20e 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 @@ -22,13 +22,21 @@ class Profile < ActiveRecord::Base has_many :alerts, :dependent => :delete_all has_many :active_rules, :class_name => 'ActiveRule', :foreign_key => 'profile_id', :dependent => :destroy, :include => ['rule'] - has_many :projects, :order => 'name asc' - has_many :active_rules_with_params, :class_name => 'ActiveRule', :foreign_key => 'profile_id', - :include => ['active_rule_parameters', 'active_rule_note'] + has_many :active_rules_with_params, :class_name => 'ActiveRule', :foreign_key => 'profile_id', :include => ['active_rule_parameters', 'active_rule_note'] + has_many :projects, :class_name => 'Project', :finder_sql => %q( + select prj.* from projects prj, properties prop where prj.id=prop.resource_id and prop.resource_id is not null and prop.prop_key='sonar.profile.#{language}' and prop.text_value='#{name}' + ) + has_many :changes, :class_name => 'ActiveRuleChange', :dependent => :destroy + has_many :children, :class_name => 'Profile', :finder_sql => %q( + select c.* from rules_profiles c where c.parent_name='#{name}' and c.language='#{language}' + ) validates_uniqueness_of :name, :scope => :language, :case_sensitive => false, :message => Api::Utils.message('quality_profiles.already_exists') validates_presence_of :name, :message => Api::Utils.message('quality_profiles.please_type_profile_name') + MAX_NAME_LENGTH = 100 + validates_length_of :name, :maximum => MAX_NAME_LENGTH, :message => Api::Utils.message('name_too_long_x', :params => [MAX_NAME_LENGTH]) + # The warnings that are set on this record, equivalent to normal ActiveRecord errors but does not prevent # the record from saving. def warnings @@ -36,7 +44,7 @@ class Profile < ActiveRecord::Base end def warnings? - not warnings.empty? + !warnings.empty? end def notices @@ -59,34 +67,16 @@ class Profile < ActiveRecord::Base provided end - def validate_copy(name) - new_rule_profile = Profile.new(:name => name, :provided => false, :default_profile => false, :language => language) - new_rule_profile.valid? - new_rule_profile.errors - end - - def self.find_by_name_and_language(name, language) - Profile.find(:first, :conditions => {:name => name, :language => language, :enabled => true}) - end - - def self.find_active_profile_by_language(language) - Profile.find(:first, :conditions => {:default_profile => true, :language => language, :enabled => true}) - end - - def self.default_profile - Profile.find(:first, :conditions => {:default_profile => true, :enabled => true}) - end - def set_as_default - default_profile=nil - Profile.find(:all, :conditions => {:language => language, :enabled => true}).each do |profile| - if profile.id==id - profile.default_profile=true - default_profile=profile - else - profile.default_profile=false + 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 - profile.save end self end @@ -97,7 +87,7 @@ class Profile < ActiveRecord::Base def self.options_for_select array=[] - Profile.find(:all, :conditions => {:enabled => true}, :order => 'name').each do |profile| + Profile.find(:all, :order => 'name').each do |profile| label = profile.name label = label + ' (active)' if profile.default_profile? array<<[label, profile.id] @@ -123,9 +113,9 @@ class Profile < ActiveRecord::Base 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? @@ -134,13 +124,13 @@ class Profile < ActiveRecord::Base def parent @parent||= - begin - if parent_name.present? - Profile.find(:first, :conditions => ['language=? and name=? and enabled=?', language, parent_name, true]) - else - nil - end + begin + if parent_name.present? + Profile.find(:first, :conditions => ['language=? and name=?', language, parent_name]) + else + nil end + end end def count_active_rules @@ -149,21 +139,14 @@ class Profile < ActiveRecord::Base def ancestors @ancestors ||= - begin - array=[] - if parent - array< ['language=? and parent_name=? and enabled=?', language, name, true], :order => 'name') + begin + array=[] + if parent + array< {:default_profile => true, :language => language}) + end + + # Results are NOT sorted + def self.all_by_language(language) + Profile.find(:all, :conditions => {:language => language}) + end + + def self.find_by_name_and_language(name, language) + Profile.find(:first, :conditions => {:name => name, :language => language}) + end end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/project.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/project.rb index 07e3a251282..4acf953c17c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/project.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/project.rb @@ -25,7 +25,6 @@ class Project < ActiveRecord::Base has_many :processed_snapshots, :class_name => 'Snapshot', :conditions => "status='#{Snapshot::STATUS_PROCESSED}' AND qualifier<>'LIB'", :order => 'created_at asc' has_many :events, :foreign_key => 'resource_id', :order => 'event_date DESC' has_many :project_links, :dependent => :delete_all, :order => 'link_type' - belongs_to :profile, :class_name => 'Profile', :foreign_key => 'profile_id' has_many :user_roles, :foreign_key => 'resource_id' has_many :group_roles, :foreign_key => 'resource_id' has_many :manual_measures, :foreign_key => 'resource_id' @@ -182,6 +181,10 @@ class Project < ActiveRecord::Base last_snapshot ? last_snapshot.path_name : nil end + def profile(lang, returns_default_if_nil=false) + Profile.by_project_id(lang, id, returns_default_if_nil) + end + private def create_chart_measures(results, date_column_name, value_column_name) diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb index 976fdf7480a..6371b51242d 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb @@ -21,9 +21,11 @@ class Property < ActiveRecord::Base validates_presence_of :prop_key named_scope :with_key, lambda { |value| {:conditions => {:prop_key, value}} } + named_scope :with_value, lambda { |value| {:conditions => {:text_value, value}} } named_scope :with_resource, lambda { |value| {:conditions => {:resource_id => value}} } named_scope :with_user, lambda { |value| {:conditions => {:user_id => value}} } - named_scope :on_resource, :conditions => ['resource_id is not ?', nil] + named_scope :with_resources, :conditions => 'resource_id is not null' + named_scope :with_users, :conditions => 'user_id is not null' def key prop_key @@ -47,6 +49,18 @@ class Property < ActiveRecord::Base end end + def self.clear_for_resources(key, value=nil) + scope=Property.with_resources().with_key(key) + if value + scope.with_value(value) + end + scope.delete_all + end + + def self.clear_for_users(key) + Property.with_users().with_key(key).delete_all + end + def self.by_key(key, resource_id=nil, user_id=nil) all(key, resource_id, user_id).first end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb index 9788893ab96..96d831919b5 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb @@ -89,8 +89,8 @@ <% if has_role?(:admin, @project) %>
  • <%= message('sidebar.project_settings') -%>
  • <% if (@project.project?) %> -
  • - <%= message('project_quality_profile.page') -%>
  • +
  • + <%= message('project_quality_profile.page') -%>
  • <% end %>
  • <%= message('manual_measures.page') -%>
  • diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_copy_form.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_copy_form.html.erb index bff1d8c7bfc..535ea549a10 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_copy_form.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_copy_form.html.erb @@ -2,14 +2,18 @@
    -

    Copy Profile: <%= h @profile.name -%>

    +

    <%= message('quality_profiles.copy_x_title', :params => [h @profile.name]) -%>

    - <% if @error %> -

    <%= h @error -%>

    - <% end %> + <% if @errors + @errors.each do |error| + %> +

    <%= h error -%>

    + <% end + end + %>
    - +
    diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_rename_form.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_rename_form.html.erb index 4da833e138d..b7c11aa4ac7 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_rename_form.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_rename_form.html.erb @@ -3,12 +3,12 @@
    -

    Rename Profile: <%= h @profile.name -%>

    +

    Rename Profile: <%= h @profile.name_was -%>

    - <% if @error %> -

    <%= h @error -%>

    + <% @profile.errors.each do |attr, msg| %> +

    <%= h msg -%>

    <% end %>
    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 201a7718682..50efc517ad0 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 @@ -49,7 +49,7 @@ - <%= profile.count_active_rules -%> + <%= profile.active_rules.count -%> <%= profile.alerts.size -%> @@ -62,8 +62,9 @@ <% if !profile.default_profile? && administrator? %> - <%= button_to_action message('set_as_default'), "profiles/set_as_default?id=#{profile.id}", + <%= link_to_action message('set_as_default'), "profiles/set_as_default?id=#{profile.id}", :id => "activate_#{profile.key.parameterize}", + :class => 'button', :title_key => 'set_as_default', :message_key => 'quality_profiles.are_you_sure_want_x_profile_as_default', :message_params => [profile.name] -%> @@ -96,8 +97,8 @@ <% if profile.deletable? %> - <%= button_to_action message('delete'), "profiles/delete/#{profile.id}", - :class => 'red-button', + <%= link_to_action message('delete'), "profiles/delete/#{profile.id}", + :class => 'button red-button', :id => "delete_#{profile.key.parameterize}", :button_key => 'delete', :title_key => 'quality_profiles.delete_confirm_title', 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 8a155a8adbd..df77976eb84 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 @@ -1,54 +1,79 @@ -

    <%= link_to message('quality_profiles.quality_profiles'), :controller => 'profiles', :action => 'index' -%> / <%= h @profile.language -%> / <%= h @profile.name %>

    -<%= render :partial => 'profiles/tabs', :locals => {:selected_tab=>'Projects'} %> +

    <%= link_to message('quality_profiles.quality_profiles'), :controller => 'profiles', :action => 'index' -%> / <%= h @profile.language -%> + / <%= h @profile.name %>

    +<%= render :partial => 'profiles/tabs', :locals => {:selected_tab => 'Projects'} %>
    -<% if is_admin? %> -
    - - - - + + + + + +
    -

    <%= message('quality_profiles.available_projects') -%>

    - + + Add project: <%= resource_select_tag 'project_id', { + :qualifiers => ['TRK'], + :width => '400px', + :html_id => "select-project", + } -%> + + + + <% unless @profile.projects.empty? %> + + + + + + + + + <% @profile.projects.each do |project| %> + + + + <% end %> - - - - - -
    + <%= link_to_action message('remove'), + "#{ApplicationController.root_context}/profiles/remove_project?id=#{@profile.id}&project_id=#{project.id}", + :class => 'link-action', + :id => "link-remove-#{project.key.parameterize}" -%> + <%= h project.name -%> <%= h project.key -%>
    -
    -

    -
    - -
    -

    <%= message('quality_profiles.associated_projects') -%>

    -
    -
    - -
    -
    - - +
    + <%= link_to_action message('quality_profiles.remove_projects_action'), + "#{ApplicationController.root_context}/profiles/remove_projects?id=#{@profile.id}", + :class => 'link-action', + :id => "link-remove-projects" -%> +
    -<% else %> - <% if @profile.projects.empty? %> -

    <%= message('quality_profiles.no_projects_associated_to_profile_x', :params => @profile.name) -%>

    + <% end %> <% else %> -

    <%= message('quality_profiles.projects_warning') -%>

    -
      - <% @profile.projects.each do |project| %> -
    1. <%= project.name %>
    2. + + <% if @profile.projects.empty? %> +

      <%= message('quality_profiles.no_projects_associated_to_profile_x', :params => @profile.name) -%>

      + <% else %> +

      <%= message('quality_profiles.projects_warning') -%>

      + + + + + + + + + <% @profile.projects.each do |project| %> + + + + <% end %> + +
      <%= h project.name -%> <%= h project.key -%>
      <% end %> -
    <% end %> -<% end %>
    \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/project/profile.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/project/profile.html.erb new file mode 100644 index 00000000000..a52e06af2ec --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/project/profile.html.erb @@ -0,0 +1,40 @@ +

    <%= message('project_quality_profile.page') -%>

    + + + + + + + + + + <% + Api::Utils.languages.sort_by { |l| l.getKey() }.each do |language| + selected_profile=@project.profile(language.getKey(), false) + %> + + + + + <% end %> + +
    <%= message 'language' -%>Quality Profile
    <%= h language.getName() -%> +
    + + + + + + <%= submit_tag message('update_verb'), :id => "submit-#{language.getKey()}", :disable_with => message('updating') %> +
    +
    diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/project/quality_profile.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/project/quality_profile.html.erb deleted file mode 100644 index f75218f7db9..00000000000 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/project/quality_profile.html.erb +++ /dev/null @@ -1,23 +0,0 @@ -

    <%= message('project_quality_profile.page') -%>

    -
    -<% - form_tag( {:action => 'update_quality_profile', :id => @project.id }) do - project_profile = @project.profile -%> - - <%= message('project_quality_profile.select_profile_for_x', :params => @project.name) -%> - - - - <%= submit_tag message('update_verb'), :id => 'update_profile' %> - -<% end %> diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/331_remove_projects_profile_id.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/331_remove_projects_profile_id.rb new file mode 100644 index 00000000000..68fc65062e4 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/331_remove_projects_profile_id.rb @@ -0,0 +1,45 @@ +# +# 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 RemoveProjectsProfileId < ActiveRecord::Migration + + class Profile < ActiveRecord::Base + set_table_name 'rules_profiles' + end + + class Project < ActiveRecord::Base + belongs_to :profile + end + + class Property < ActiveRecord::Base + end + + def self.up + projects=Project.find(:all, :conditions => ['profile_id is not null and copy_resource_id is null'], :include => :profile) + projects.each do |project| + Property.create(:prop_key => "sonar.profile.#{project.profile.language}", :text_value => project.profile.name, :resource_id => project.id) + end + remove_column('projects', 'profile_id') + end + +end diff --git a/sonar-server/src/test/java/org/sonar/server/configuration/InheritedProfilesTest.java b/sonar-server/src/test/java/org/sonar/server/configuration/InheritedProfilesTest.java index 8674f421d4a..461caa5efb8 100644 --- a/sonar-server/src/test/java/org/sonar/server/configuration/InheritedProfilesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/configuration/InheritedProfilesTest.java @@ -53,20 +53,6 @@ public class InheritedProfilesTest extends AbstractDbUnitTestCase { assertThat(profilesManager.isCycle(level2, level3), is(true)); } - @Test - public void shouldNotDeleteInheritedProfile() { - setupData("shouldCheckCycles"); - profilesManager.deleteProfile(1); - checkTables("shouldNotDeleteInheritedProfile", "rules_profiles"); - } - - @Test - public void shouldRenameInheritedProfile() { - setupData("shouldCheckCycles"); - profilesManager.renameProfile(1, "newName"); - checkTables("shouldRenameInheritedProfile", "rules_profiles"); - } - @Test public void shouldSetParent() { setupData("shouldSetParent"); diff --git a/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesManagerTest.java b/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesManagerTest.java index 917cc55bfbc..162600f7871 100644 --- a/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesManagerTest.java +++ b/sonar-server/src/test/java/org/sonar/server/configuration/ProfilesManagerTest.java @@ -21,13 +21,10 @@ package org.sonar.server.configuration; import org.junit.Before; import org.junit.Test; -import org.sonar.api.database.model.ResourceModel; import org.sonar.api.profiles.RulesProfile; import org.sonar.jpa.test.AbstractDbUnitTestCase; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; public class ProfilesManagerTest extends AbstractDbUnitTestCase { @@ -38,32 +35,6 @@ public class ProfilesManagerTest extends AbstractDbUnitTestCase { manager = new ProfilesManager(getSession(), null); } - @Test - public void testDeleteProfile() { - RulesProfile testDefaultProfile = RulesProfile.create("default", "java"); - testDefaultProfile.setDefaultProfile(true); - testDefaultProfile.setProvided(true); - RulesProfile testProfile = RulesProfile.create("not default", "java"); - ResourceModel testResourceWithProfile = new ResourceModel(ResourceModel.SCOPE_PROJECT, "withProfile", "TRK", null, "test"); - testResourceWithProfile.setRulesProfile(testProfile); - getSession().save(testDefaultProfile, testProfile, testResourceWithProfile); - - getSession().commit(); - getSession().getEntityManager().clear(); - - manager.deleteProfile(testDefaultProfile.getId()); - // default profiles cannot be deleted - assertNotNull(getSession().getEntity(RulesProfile.class, testDefaultProfile.getId())); - - manager.deleteProfile(testProfile.getId()); - // default profiles cannot be deleted - assertNull(getSession().getEntity(RulesProfile.class, testProfile.getId())); - - testResourceWithProfile = getSession().getEntity(ResourceModel.class, testResourceWithProfile.getId()); - assertNull(testResourceWithProfile.getRulesProfile()); - - } - @Test public void testDeleteAllProfiles() { RulesProfile test1 = RulesProfile.create("test1", "java"); @@ -71,9 +42,7 @@ public class ProfilesManagerTest extends AbstractDbUnitTestCase { test1.setProvided(true); RulesProfile test2 = RulesProfile.create("test2", "java"); - ResourceModel testResourceWithProfile = new ResourceModel(ResourceModel.SCOPE_PROJECT, "withProfile", "TRK", null, "test"); - testResourceWithProfile.setRulesProfile(test1); - getSession().save(test1, test2, testResourceWithProfile); + getSession().save(test1, test2); assertEquals(new Long(2), getHQLCount(RulesProfile.class)); diff --git a/sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldNotDeleteInheritedProfile-result.xml b/sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldNotDeleteInheritedProfile-result.xml deleted file mode 100644 index 5200875be21..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldNotDeleteInheritedProfile-result.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldRenameInheritedProfile-result.xml b/sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldRenameInheritedProfile-result.xml deleted file mode 100644 index c7a2355a55a..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/configuration/InheritedProfilesTest/shouldRenameInheritedProfile-result.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/measures.xml b/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/measures.xml index daf3a4cf609..73a9937f781 100644 --- a/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/measures.xml +++ b/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/measures.xml @@ -15,11 +15,11 @@ + description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="php" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> diff --git a/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/views.xml b/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/views.xml index aac9b0863b0..2b6a2036717 100644 --- a/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/views.xml +++ b/sonar-server/src/test/resources/org/sonar/server/filters/FilterExecutorTest/views.xml @@ -2,21 +2,21 @@ + description="[null]" enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]"/> + description="[null]" enabled="true" language="java" copy_resource_id="1"/> -- 2.39.5