summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2013-12-16 16:13:39 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2013-12-16 16:13:39 +0100
commitc8e35b404af75053d5e457f612f8aefe4bda7f5f (patch)
tree61090cca462615cf7fcb9128565cf1436cb6983d
parent705171c0d42cb1fbe930466a6c0a8e5291f7cff7 (diff)
downloadsonarqube-c8e35b404af75053d5e457f612f8aefe4bda7f5f.tar.gz
sonarqube-c8e35b404af75053d5e457f612f8aefe4bda7f5f.zip
SONAR-4535 Projects associate to a quality profile now uses MyBatis
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java10
-rw-r--r--sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java3
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml27
-rw-r--r--sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java19
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml22
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java21
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjects.java43
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfiles.java4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb9
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/profiles/projects.html.erb8
-rw-r--r--sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java11
-rw-r--r--sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesTest.java7
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)