diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2013-12-16 16:13:39 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2013-12-16 16:13:39 +0100 |
commit | c8e35b404af75053d5e457f612f8aefe4bda7f5f (patch) | |
tree | 61090cca462615cf7fcb9128565cf1436cb6983d | |
parent | 705171c0d42cb1fbe930466a6c0a8e5291f7cff7 (diff) | |
download | sonarqube-c8e35b404af75053d5e457f612f8aefe4bda7f5f.tar.gz sonarqube-c8e35b404af75053d5e457f612f8aefe4bda7f5f.zip |
SONAR-4535 Projects associate to a quality profile now uses MyBatis
14 files changed, 165 insertions, 25 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index 2fb00f2a0bc..55e112bee13 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -34,6 +34,7 @@ import org.sonar.api.config.Settings; import org.sonar.api.database.model.MeasureData; import org.sonar.api.database.model.MeasureMapper; import org.sonar.api.database.model.MeasureModel; +import org.sonar.core.component.ComponentDto; import org.sonar.core.config.Logback; import org.sonar.core.dashboard.*; import org.sonar.core.dependency.DependencyDto; @@ -98,6 +99,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadAlias(conf, "ActiveDashboard", ActiveDashboardDto.class); loadAlias(conf, "Author", AuthorDto.class); + loadAlias(conf, "Component", ComponentDto.class); loadAlias(conf, "Dashboard", DashboardDto.class); loadAlias(conf, "Dependency", DependencyDto.class); loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class); diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java index 38be39d73d2..7335a08f6e4 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java +++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java @@ -23,6 +23,7 @@ package org.sonar.core.qualityprofile.db; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.SqlSession; import org.sonar.api.ServerComponent; +import org.sonar.core.component.ComponentDto; import org.sonar.core.persistence.MyBatis; import java.util.List; @@ -62,6 +63,15 @@ public class QualityProfileDao implements ServerComponent { } } + public List<ComponentDto> selectProjects(String propertyKey, String propertyValue) { + SqlSession session = mybatis.openSession(); + try { + return session.getMapper(QualityProfileMapper.class).selectProjects(propertyKey, propertyValue); + } finally { + MyBatis.closeQuietly(session); + } + } + public void insert(QualityProfileDto dto, SqlSession session) { session.getMapper(QualityProfileMapper.class).insert(dto); } diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java index 743841117b4..4ed5e64361a 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java @@ -21,6 +21,7 @@ package org.sonar.core.qualityprofile.db; import org.apache.ibatis.annotations.Param; +import org.sonar.core.component.ComponentDto; import javax.annotation.CheckForNull; @@ -36,6 +37,8 @@ public interface QualityProfileMapper { @CheckForNull QualityProfileDto selectById(@Param("id") Integer id); + List<ComponentDto> selectProjects(@Param("key") String propertyKey, @Param("value") String propertyValue); + void insert(QualityProfileDto dto); void update(QualityProfileDto dto); diff --git a/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml b/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml index 9afaeaffab1..d41f6b02ae4 100644 --- a/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml @@ -13,24 +13,35 @@ </sql> <select id="selectAll" parameterType="map" resultType="QualityProfile"> - select <include refid="profilesColumns"/> - from rules_profiles p + SELECT <include refid="profilesColumns"/> + FROM rules_profiles p </select> <select id="selectByNameAndLanguage" parameterType="map" resultType="QualityProfile"> - select <include refid="profilesColumns"/> - from rules_profiles p + SELECT <include refid="profilesColumns"/> + FROM rules_profiles p <where> AND UPPER(p.name)=#{name} - and p.language=#{language} + AND p.language=#{language} </where> </select> <select id="selectById" parameterType="Integer" resultType="QualityProfile"> - select <include refid="profilesColumns"/> - from rules_profiles p + SELECT <include refid="profilesColumns"/> + FROM rules_profiles p <where> - and p.id=#{id} + AND p.id=#{id} + </where> + </select> + + <select id="selectProjects" parameterType="Integer" resultType="Component"> + SELECT projects.id as id, projects.name as name, projects.kee as key + FROM projects projects + LEFT JOIN properties ON properties.resource_id = projects.id + <where> + AND properties.resource_id IS NOT NULL + AND properties.prop_key=#{key} + AND properties.text_value like #{value} </where> </select> diff --git a/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java b/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java index bf65dcab7c3..47e37e05c6e 100644 --- a/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java @@ -22,6 +22,7 @@ package org.sonar.core.qualityprofile.db; import org.junit.Before; import org.junit.Test; +import org.sonar.core.component.ComponentDto; import org.sonar.core.persistence.AbstractDaoTestCase; import java.util.List; @@ -94,6 +95,24 @@ public class QualityProfileDaoTest extends AbstractDaoTestCase { } @Test + public void select_projects() { + setupData("projects"); + + List<ComponentDto> dtos = dao.selectProjects("sonar.profile.java", "Sonar Way"); + assertThat(dtos).hasSize(2); + + ComponentDto componentDto1 = dtos.get(0); + assertThat(componentDto1.getId()).isEqualTo(1); + assertThat(componentDto1.key()).isEqualTo("org.codehaus.sonar:sonar"); + assertThat(componentDto1.name()).isEqualTo("SonarQube"); + + ComponentDto componentDto2 = dtos.get(1); + assertThat(componentDto2.getId()).isEqualTo(2); + assertThat(componentDto2.key()).isEqualTo("org.codehaus.sonar-plugins.java:java"); + assertThat(componentDto2.name()).isEqualTo("SonarQube Java"); + } + + @Test public void insert() { setupData("shared"); diff --git a/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml new file mode 100644 index 00000000000..d2727cc36ba --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml @@ -0,0 +1,22 @@ +<dataset> + + <rules_profiles id="1" name="Sonar way" language="java" parent_name="[null]" version="1" + used_profile="[false]"/> + + <rules_profiles id="2" name="Sonar way" language="js" parent_name="[null]" version="1" + used_profile="[false]"/> + + <projects id="1" kee="org.codehaus.sonar:sonar" name="SonarQube"/> + <projects id="2" kee="org.codehaus.sonar-plugins.java:java" name="SonarQube Java"/> + + <properties id="1" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="1"/> + <properties id="2" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="2"/> + + <!-- Property used to know the default profile, should not be returned when searching for projects --> + <properties id="3" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="[null]"/> + + <properties id="4" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="3"/> + <properties id="5" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="4"/> + <properties id="6" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="[null]"/> + +</dataset> diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java index e66f93bcd56..c7f6af0355b 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java @@ -20,11 +20,14 @@ package org.sonar.server.qualityprofile; +import com.google.common.base.Function; import com.google.common.base.Strings; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.SqlSession; import org.sonar.api.ServerComponent; +import org.sonar.api.component.Component; import org.sonar.api.profiles.ProfileExporter; import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.profiles.RulesProfile; @@ -32,6 +35,7 @@ import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.ActiveRuleParam; import org.sonar.api.rules.RulePriority; import org.sonar.api.utils.ValidationMessages; +import org.sonar.core.component.ComponentDto; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.MyBatis; import org.sonar.core.preview.PreviewCache; @@ -43,6 +47,7 @@ import org.sonar.server.user.UserSession; import org.sonar.server.util.Validation; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import java.io.StringReader; import java.util.List; @@ -52,6 +57,8 @@ import static com.google.common.collect.Lists.newArrayList; public class QProfileOperations implements ServerComponent { + private static final String PROPERTY_PREFIX = "sonar.profile."; + private final MyBatis myBatis; private final QualityProfileDao dao; private final ActiveRuleDao activeRuleDao; @@ -105,13 +112,25 @@ public class QProfileOperations implements ServerComponent { public void updateDefaultProfile(Integer id, UserSession userSession) { QualityProfileDto qualityProfile = validateUpdateDefaultProfile(id, userSession); - persistentSettings.saveProperty("sonar.profile." + qualityProfile.getLanguage(), qualityProfile.getName()); + persistentSettings.saveProperty(PROPERTY_PREFIX + qualityProfile.getLanguage(), qualityProfile.getName()); } public void updateDefaultProfile(String name, String language, UserSession userSession) { updateDefaultProfile(findNeverNull(name, language).getId(), userSession); } + public QProfileProjects projects(Integer profileId) { + QualityProfileDto dto = findNeverNull(profileId); + List<ComponentDto> componentDtos = dao.selectProjects(PROPERTY_PREFIX + dto.getLanguage(), dto.getName()); + List<Component> projects = newArrayList(Iterables.transform(componentDtos, new Function<ComponentDto, Component>() { + @Override + public Component apply(@Nullable ComponentDto dto) { + return (Component) dto; + } + })); + return new QProfileProjects(QProfile.from(dto), projects); + } + private List<RulesProfile> readProfilesFromXml(NewProfileResult result, Map<String, String> xmlProfilesByPlugin) { List<RulesProfile> profiles = newArrayList(); ValidationMessages messages = ValidationMessages.create(); diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjects.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjects.java new file mode 100644 index 00000000000..ee89854fe45 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjects.java @@ -0,0 +1,43 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.qualityprofile; + +import org.sonar.api.component.Component; + +import java.util.List; + +public class QProfileProjects { + + private QProfile profile; + private List<Component> projects; + + public QProfileProjects(QProfile profile, List<Component> projects) { + this.profile = profile; + this.projects = projects; + } + + public QProfile profile() { + return profile; + } + + public List<Component> projects() { + return projects; + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfiles.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfiles.java index 749320cce1b..43c3b87acbb 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfiles.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfiles.java @@ -103,8 +103,8 @@ public class QProfiles implements ServerComponent { // PROJECTS - public void projects(Integer profileId) { - throw new UnsupportedOperationException(); + public QProfileProjects projects(Integer profileId) { + return operations.projects(profileId); } public void addProject(Integer profileId, String projectKey) { 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 72590af02fb..492db1f6e0e 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 @@ -267,9 +267,12 @@ class ProfilesController < ApplicationController # # def projects - require_parameters 'id' - @profile = Profile.find(params[:id]) - set_profile_breadcrumbs + call_backend do + result = Internal.qprofiles.projects(params[:id].to_i) + @profile = result.profile + @projects = Api::Utils.insensitive_sort(result.projects.to_a) { |p| p.name } + set_profile_breadcrumbs + 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 202cc3d3a1f..217be41cd8c 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 @@ -174,10 +174,6 @@ class Profile < ActiveRecord::Base end end - def sorted_projects - Api::Utils.insensitive_sort(projects) { |p| p.name } - end - def add_project_id(project_id) Property.set("sonar.profile.#{language}", name, project_id) @projects = nil 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 e637bc7441e..fc7c7e703b3 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 @@ -17,7 +17,7 @@ })</script> </form> - <% if @profile.projects? %> + <% unless @projects.empty? %> <table class="data" id="projects-table"> <thead> <tr> @@ -26,7 +26,7 @@ </tr> </thead> <tbody> - <% @profile.sorted_projects.each do |project| %> + <% @projects.each do |project| %> <tr class="<%= cycle('even', 'odd') -%>"> <td class="thin"> <%= link_to_action message('quality_profiles.remove_project_action'), @@ -61,7 +61,7 @@ <% end %> <% else %> - <% if !@profile.projects? %> + <% if @projects.empty? %> <p><%= message('quality_profiles.no_projects_associated_to_profile_x', :params => @profile.name) -%></p> <% else %> <p><%= message('quality_profiles.projects_warning') -%></p> @@ -73,7 +73,7 @@ </tr> </thead> <tbody> - <% @profile.sorted_projects.each do |project| %> + <% @projects.each do |project| %> <tr class="<%= cycle('even', 'odd') -%>"> <td><%= h project.name -%> <span class="small gray"><%= h project.key -%></span></td> </tr> diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java index a509e9be600..1c7df7e4580 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java @@ -37,6 +37,7 @@ import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.api.utils.ValidationMessages; +import org.sonar.core.component.ComponentDto; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.MyBatis; import org.sonar.core.preview.PreviewCache; @@ -267,4 +268,14 @@ public class QProfileOperationsTest { verify(persistentSettings).saveProperty("sonar.profile.java", "My profile"); } + + @Test + public void search_projects() throws Exception { + when(dao.selectById(1)).thenReturn(new QualityProfileDto().setId(1).setName("My profile").setLanguage("java")); + when(dao.selectProjects("sonar.profile.java", "My profile")).thenReturn(newArrayList(new ComponentDto().setId(1L).setKey("org.codehaus.sonar:sonar").setName("SonarQube"))); + + QProfileProjects result = operations.projects(1); + assertThat(result.profile()).isNotNull(); + assertThat(result.projects()).hasSize(1); + } } diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesTest.java index 9f59f3e8b46..31b2a0b64d9 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesTest.java @@ -125,9 +125,10 @@ public class QProfilesTest { qProfiles.changelog(null); } - @Test(expected = UnsupportedOperationException.class) - public void testProjects() throws Exception { - qProfiles.projects(null); + @Test + public void projects() throws Exception { + qProfiles.projects(1); + verify(operations).projects(1); } @Test(expected = UnsupportedOperationException.class) |