]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4535 Set default profile now use MyBatis
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 16 Dec 2013 10:40:20 +0000 (11:40 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 16 Dec 2013 10:40:20 +0000 (11:40 +0100)
14 files changed:
sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java
sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java
sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml
sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfiles.java
sonar-server/src/main/webapp/WEB-INF/app/controllers/api/api_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/controllers/application_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/models/profile.rb
sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_rename_form.html.erb
sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java
sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesTest.java

index a364ae1fcc797e956aff4932cb7a9af4863726d4..5f8be747d2512e58b41913a427857d178b17d651 100644 (file)
@@ -43,6 +43,15 @@ public class QualityProfileDao implements ServerComponent {
     }
   }
 
+  public QualityProfileDto selectById(Integer id) {
+    SqlSession session = mybatis.openSession();
+    try {
+      return session.getMapper(QualityProfileMapper.class).selectById(id);
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
   public QualityProfileDto selectByNameAndLanguage(String name, String language) {
     SqlSession session = mybatis.openSession();
     try {
index dcfe0b93337c5929bed64d62822bae277532088b..743841117b4188024decb781d5e62d8d35db1c77 100644 (file)
@@ -33,6 +33,9 @@ public interface QualityProfileMapper {
   @CheckForNull
   QualityProfileDto selectByNameAndLanguage(@Param("name") String name, @Param("language") String language);
 
+  @CheckForNull
+  QualityProfileDto selectById(@Param("id") Integer id);
+
   void insert(QualityProfileDto dto);
 
   void update(QualityProfileDto dto);
index cd44060bef08c85bc52f7cec6c6eb9052140f252..7fce1aff56bd0d0f945c6be2d7e4fe9090ac31a4 100644 (file)
     </where>
   </select>
 
+  <select id="selectById" parameterType="Integer" resultType="QualityProfile">
+    select <include refid="profilesColumns"/>
+    from rules_profiles p
+    <where>
+      and p.id=#{id}
+    </where>
+  </select>
+
   <insert id="insert" parameterType="QualityProfile" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
     INSERT INTO rules_profiles (name, language, parent_name, version, used_profile)
     VALUES (#{name}, #{language}, #{parent}, #{version}, #{used})
index 69761aaef1d3383ebf0a3eba830362066ddecb14..d56d3da0e5db558b199d636e08d5a1d55147590c 100644 (file)
@@ -74,7 +74,22 @@ public class QualityProfileDaoTest extends AbstractDaoTestCase {
     assertThat(dto.getVersion()).isEqualTo(1);
     assertThat(dto.isUsed()).isFalse();
 
-    assertThat(dao.selectByNameAndLanguage("Sonar way", "unknown"));
+    assertThat(dao.selectByNameAndLanguage("Sonar way", "unknown")).isNull();
+  }
+
+  @Test
+  public void select_by_id() {
+    setupData("shared");
+
+    QualityProfileDto dto = dao.selectById(1);
+    assertThat(dto.getId()).isEqualTo(1);
+    assertThat(dto.getName()).isEqualTo("Sonar way");
+    assertThat(dto.getLanguage()).isEqualTo("java");
+    assertThat(dto.getParent()).isNull();
+    assertThat(dto.getVersion()).isEqualTo(1);
+    assertThat(dto.isUsed()).isFalse();
+
+    assertThat(dao.selectById(555)).isNull();
   }
 
   @Test
index b6ed6b8c7a4489eeaae46e0805c1831d6d2b7c9b..e66f93bcd56d4c630279e8aa9fe818538ee84301 100644 (file)
@@ -38,9 +38,12 @@ import org.sonar.core.preview.PreviewCache;
 import org.sonar.core.qualityprofile.db.*;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.platform.PersistentSettings;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.util.Validation;
 
+import javax.annotation.CheckForNull;
+
 import java.io.StringReader;
 import java.util.List;
 import java.util.Map;
@@ -55,19 +58,21 @@ public class QProfileOperations implements ServerComponent {
   private final List<ProfileExporter> exporters;
   private final List<ProfileImporter> importers;
   private final PreviewCache dryRunCache;
+  private final PersistentSettings persistentSettings;
 
-  public QProfileOperations(MyBatis myBatis, QualityProfileDao dao, ActiveRuleDao activeRuleDao, PreviewCache dryRunCache) {
-    this(myBatis, dao, activeRuleDao, Lists.<ProfileExporter>newArrayList(), Lists.<ProfileImporter>newArrayList(), dryRunCache);
+  public QProfileOperations(MyBatis myBatis, QualityProfileDao dao, ActiveRuleDao activeRuleDao, PreviewCache dryRunCache, PersistentSettings persistentSettings) {
+    this(myBatis, dao, activeRuleDao, Lists.<ProfileExporter>newArrayList(), Lists.<ProfileImporter>newArrayList(), dryRunCache, persistentSettings);
   }
 
   public QProfileOperations(MyBatis myBatis, QualityProfileDao dao, ActiveRuleDao activeRuleDao, List<ProfileExporter> exporters, List<ProfileImporter> importers,
-                            PreviewCache dryRunCache) {
+                            PreviewCache dryRunCache, PersistentSettings persistentSettings) {
     this.myBatis = myBatis;
     this.dao = dao;
     this.activeRuleDao = activeRuleDao;
     this.exporters = exporters;
     this.importers = importers;
     this.dryRunCache = dryRunCache;
+    this.persistentSettings = persistentSettings;
   }
 
   public NewProfileResult newProfile(String name, String language, Map<String, String> xmlProfilesByPlugin, UserSession userSession) {
@@ -85,21 +90,26 @@ public class QProfileOperations implements ServerComponent {
       }
       result.setProfile(QProfile.from(dto));
       sqlSession.commit();
+      dryRunCache.reportGlobalModification();
     } finally {
       MyBatis.closeQuietly(sqlSession);
-      dryRunCache.reportGlobalModification();
     }
     return result;
   }
 
-  public void renameProfile(String name, String language, String newName, UserSession userSession) {
-    QualityProfileDto qualityProfile = validateRenameProfile(name, language, newName, userSession);
+  public void renameProfile(Integer profileId, String newName, UserSession userSession) {
+    QualityProfileDto qualityProfile = validateRenameProfile(profileId, newName, userSession);
     qualityProfile.setName(newName);
     dao.update(qualityProfile);
   }
 
-  private QualityProfileDto find(String name, String language) {
-    return dao.selectByNameAndLanguage(name, language);
+  public void updateDefaultProfile(Integer id, UserSession userSession) {
+    QualityProfileDto qualityProfile = validateUpdateDefaultProfile(id, userSession);
+    persistentSettings.saveProperty("sonar.profile." + qualityProfile.getLanguage(), qualityProfile.getName());
+  }
+
+  public void updateDefaultProfile(String name, String language, UserSession userSession) {
+    updateDefaultProfile(findNeverNull(name, language).getId(), userSession);
   }
 
   private List<RulesProfile> readProfilesFromXml(NewProfileResult result, Map<String, String> xmlProfilesByPlugin) {
@@ -175,13 +185,30 @@ public class QProfileOperations implements ServerComponent {
     }
   }
 
-  private QualityProfileDto validateRenameProfile(String name, String language, String newName, UserSession userSession) {
+  private QualityProfileDto validateRenameProfile(Integer profileId, String newName, UserSession userSession) {
     checkPermission(userSession);
     validateName(newName);
-    if (find(newName, language) != null) {
+    QualityProfileDto profileDto = findNeverNull(profileId);
+    if (!profileDto.getName().equals(newName) && find(newName, profileDto.getLanguage()) != null) {
       throw BadRequestException.ofL10n("quality_profiles.already_exists");
     }
+    return profileDto;
+  }
+
+  private QualityProfileDto validateUpdateDefaultProfile(Integer id, UserSession userSession) {
+    checkPermission(userSession);
+    return findNeverNull(id);
+  }
 
+  private QualityProfileDto findNeverNull(Integer id) {
+    QualityProfileDto qualityProfile = find(id);
+    if (qualityProfile == null) {
+      throw new NotFoundException("This quality profile does not exists.");
+    }
+    return qualityProfile;
+  }
+
+  private QualityProfileDto findNeverNull(String name, String language) {
     QualityProfileDto qualityProfile = find(name, language);
     if (qualityProfile == null) {
       throw new NotFoundException("This quality profile does not exists.");
@@ -189,6 +216,16 @@ public class QProfileOperations implements ServerComponent {
     return qualityProfile;
   }
 
+  @CheckForNull
+  private QualityProfileDto find(String name, String language) {
+    return dao.selectByNameAndLanguage(name, language);
+  }
+
+  @CheckForNull
+  private QualityProfileDto find(Integer id) {
+    return dao.selectById(id);
+  }
+
   private void validateName(String name) {
     if (Strings.isNullOrEmpty(name)) {
       throw BadRequestException.ofL10n("quality_profiles.please_type_profile_name");
index 69dfc40c08465495a6b7bc6cfa8c22526216c0e1..8cecacbb7ef79823847d277d6c0926143129512b 100644 (file)
@@ -53,12 +53,19 @@ public class QProfiles implements ServerComponent {
     throw new UnsupportedOperationException();
   }
 
-  public void renameProfile(String name, String language, String newName) {
-    operations.renameProfile(name, language, newName, UserSession.get());
+  public void renameProfile(Integer id, String newName) {
+    operations.renameProfile(id, newName, UserSession.get());
   }
 
-  public void updateDefaultProfile() {
-    throw new UnsupportedOperationException();
+  public void updateDefaultProfile(Integer id) {
+    operations.updateDefaultProfile(id, UserSession.get());
+  }
+
+  /**
+   * Used by WS
+   */
+  public void updateDefaultProfile(String name, String language) {
+    operations.updateDefaultProfile(name, language, UserSession.get());
   }
 
   public void copyProfile() {
index 4ce123abfd8cbb7b6d0e998e7c1261725e98d583..fb73adcb2188a41ef465969b1c52f82ef539b6fd 100644 (file)
@@ -107,6 +107,7 @@ class Api::ApiController < ApplicationController
     render_error(message, 200)
   end
 
+  # Override
   def render_server_exception(exception)
     render_response(exception.httpCode, exception.getMessage)
   end
index 8fdf52a9a29cbb7b793c01f34c1b822a9d2c5ab6..4fe95efecabf7e5614b636c520729900df17df78 100644 (file)
@@ -75,12 +75,7 @@ class Api::ProfilesController < Api::ApiController
   # Since v.3.3
   def set_as_default
     verify_post_request
-    access_denied unless has_role?(:profileadmin)
-    require_parameters :language, :name
-
-    profile=Profile.find_by_name_and_language(params[:name], params[:language])
-    not_found('Profile not found') unless profile
-    profile.set_as_default
+    Internal.qprofiles.updateDefaultProfile(params[:name], params[:language])
     render_success
   end
 
index 41c94f6e7d635fcc24ddfe12dae671b1fb2971eb..a38e8cc009818040ef5ffe44d76bd336f872d311 100644 (file)
@@ -181,7 +181,11 @@ class ApplicationController < ActionController::Base
     if exception.java_kind_of?(Java::OrgSonarServerExceptions::BadRequestException) && !exception.errors.empty?
       message += '<br/>' + exception.errors.to_a.map{|error| error.text ? error.text : Api::Utils.message(error.l10nKey, :params => error.l10nParams)}.join('<br/>')
     end
-    render :text => CGI.escapeHTML(message), :status => exception.httpCode
+    if request.xhr?
+      render :text => CGI.escapeHTML(message), :status => exception.httpCode
+    else
+      flash[:error] = message
+    end
   end
 
   def render_native_access_denied(exception)
index 4e3d0b2ce7c8b6997addc65826778fa2f6b22e98..46b86087d143efa604edd7e83d21932ea6c97f0b 100644 (file)
@@ -63,10 +63,7 @@ class ProfilesController < ApplicationController
         flash[:warning] = result.warnings.to_a[0...4].join('<br/>')
       end
     rescue Java::OrgSonarServerExceptions::ServerException => error
-      flash[:error] = (error.getMessage ? error.getMessage : Api::Utils.message(error.l10nKey, :params => error.l10nParams.to_a))
-      if error.java_kind_of?(Java::OrgSonarServerExceptions::BadRequestException) && !error.errors.empty?
-        flash[:error] += '<br/>' + error.errors.to_a.map{|error| error.text ? error.text : Api::Utils.message(error.l10nKey, :params => error.l10nParams)}.join('<br/>')
-      end
+      render_server_exception(error)
     end
     redirect_to :action => 'index'
   end
@@ -88,11 +85,11 @@ class ProfilesController < ApplicationController
   # POST /profiles/set_as_default/<id>
   def set_as_default
     verify_post_request
-    access_denied unless has_role?(:profileadmin)
-    require_parameters 'id'
-
-    profile = Profile.find(params[:id])
-    profile.set_as_default
+    begin
+      Internal.qprofiles.updateDefaultProfile(params[:id].to_i)
+    rescue Java::OrgSonarServerExceptions::ServerException => error
+      render_server_exception(error)
+    end
     redirect_to :action => 'index'
   end
 
@@ -336,7 +333,7 @@ class ProfilesController < ApplicationController
     verify_post_request
     verify_ajax_request
 
-    Internal.qprofiles.renameProfile(params[:name], params[:language], params[:new_name])
+    Internal.qprofiles.renameProfile(params[:id].to_i, params[:new_name])
     render :text => 'ok', :status => 200
   end
 
index 94183e6040cbb9aad69532fea3d4309d9a5232b0..202cc3d3a1f8536a0c8e22e5436452cee673c922 100644 (file)
@@ -61,11 +61,6 @@ class Profile < ActiveRecord::Base
     Property.value("sonar.profile.#{language}")==name
   end
 
-  def set_as_default
-    Property.set("sonar.profile.#{language}", name)
-    self
-  end
-
   def active_by_rule_id(rule_id)
     active_hash_by_rule_id[rule_id]
   end
index b9c935a26a9cf00b8942ed0dc539b2b8e23745d5..cf0f9053583be881574b432ce09a937d8c68be3a 100644 (file)
@@ -1,6 +1,5 @@
 <form id="rename-profile-form" method="post" action="profiles/rename">
-  <input type="hidden" name="name" value="<%= @profile.name -%>"/>
-  <input type="hidden" name="language" value="<%=  @profile.language -%>"/>
+  <input type="hidden" name="id" value="<%= @profile.id -%>"/>
   <fieldset>
 
     <div class="modal-head">
index b04fb400c52e903fd842c8e251ef4397801d669b..a509e9be6000a3bd55f2c2b3b3af653a976f380c 100644 (file)
@@ -44,6 +44,7 @@ import org.sonar.core.qualityprofile.db.*;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.platform.PersistentSettings;
 import org.sonar.server.user.MockUserSession;
 
 import java.io.Reader;
@@ -74,6 +75,9 @@ public class QProfileOperationsTest {
   @Mock
   PreviewCache dryRunCache;
 
+  @Mock
+  PersistentSettings persistentSettings;
+
   List<ProfileExporter> exporters = newArrayList();
 
   List<ProfileImporter> importers = newArrayList();
@@ -83,7 +87,7 @@ public class QProfileOperationsTest {
   @Before
   public void setUp() throws Exception {
     when(myBatis.openSession()).thenReturn(session);
-    operations = new QProfileOperations(myBatis, dao, activeRuleDao, exporters, importers, dryRunCache);
+    operations = new QProfileOperations(myBatis, dao, activeRuleDao, exporters, importers, dryRunCache, persistentSettings);
   }
 
   @Test
@@ -199,9 +203,9 @@ public class QProfileOperationsTest {
 
   @Test
   public void rename_profile() throws Exception {
-    QualityProfileDto dto = new QualityProfileDto().setName("Default").setLanguage("java");
-    when(dao.selectByNameAndLanguage(eq("Default"), anyString())).thenReturn(dto);
-    operations.renameProfile("Default", "java", "Default profile", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
+    QualityProfileDto dto = new QualityProfileDto().setId(1).setName("Default").setLanguage("java");
+    when(dao.selectById(1)).thenReturn(dto);
+    operations.renameProfile(1, "Default profile", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
 
     ArgumentCaptor<QualityProfileDto> profileArgument = ArgumentCaptor.forClass(QualityProfileDto.class);
     verify(dao).update(profileArgument.capture());
@@ -213,7 +217,7 @@ public class QProfileOperationsTest {
   @Test
   public void fail_to_rename_profile_on_unknown_profile() throws Exception {
     try {
-      operations.renameProfile("Default", "java", "Default profile", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
+      operations.renameProfile(1, "Default profile", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(NotFoundException.class);
@@ -224,7 +228,7 @@ public class QProfileOperationsTest {
   @Test
   public void fail_to_rename_profile_when_missing_new_name() throws Exception {
     try {
-      operations.renameProfile("Default", "java", "", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
+      operations.renameProfile(1, "", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(BadRequestException.class);
@@ -235,13 +239,32 @@ public class QProfileOperationsTest {
   @Test
   public void fail_to_rename_profile_if_already_exists() throws Exception {
     try {
-      when(dao.selectByNameAndLanguage(eq("Default"), anyString())).thenReturn(new QualityProfileDto().setName("Default").setLanguage("java"));
+      when(dao.selectById(1)).thenReturn(new QualityProfileDto().setId(1).setName("Default").setLanguage("java"));
       when(dao.selectByNameAndLanguage(eq("New Default"), anyString())).thenReturn(new QualityProfileDto().setName("New Default").setLanguage("java"));
-      operations.renameProfile("Default", "java", "New Default", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
+      operations.renameProfile(1, "New Default", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(BadRequestException.class);
     }
     verify(session, never()).commit();
   }
+
+  @Test
+  public void update_default_profile() throws Exception {
+    when(dao.selectById(1)).thenReturn(new QualityProfileDto().setId(1).setName("My profile").setLanguage("java"));
+
+    operations.updateDefaultProfile(1, MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
+
+    verify(persistentSettings).saveProperty("sonar.profile.java", "My profile");
+  }
+
+  @Test
+  public void update_default_profile_from_name_and_language() throws Exception {
+    when(dao.selectByNameAndLanguage("My profile", "java")).thenReturn(new QualityProfileDto().setId(1).setName("My profile").setLanguage("java"));
+    when(dao.selectById(1)).thenReturn(new QualityProfileDto().setId(1).setName("My profile").setLanguage("java"));
+
+    operations.updateDefaultProfile("My profile", "java", MockUserSession.create().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN));
+
+    verify(persistentSettings).saveProperty("sonar.profile.java", "My profile");
+  }
 }
index 690dce9a723527005a5a8311b181639b636bc4a6..82e352eb7d871328214d02742a70f71d7b3c6f2f 100644 (file)
@@ -74,13 +74,20 @@ public class QProfilesTest {
 
   @Test
   public void rename_profile() throws Exception {
-    qProfiles.renameProfile("Default", "java", "Default profile");
-    verify(operations).renameProfile(eq("Default"), eq("java"), eq("Default profile"), any(UserSession.class));
+    qProfiles.renameProfile(1, "Default profile");
+    verify(operations).renameProfile(eq(1), eq("Default profile"), any(UserSession.class));
   }
 
-  @Test(expected = UnsupportedOperationException.class)
-  public void testSetDefaultProfile() throws Exception {
-    qProfiles.updateDefaultProfile();
+  @Test
+  public void update_default_profile() throws Exception {
+    qProfiles.updateDefaultProfile(1);
+    verify(operations).updateDefaultProfile(eq(1), any(UserSession.class));
+  }
+
+  @Test
+  public void update_default_profile_from_name_and_language() throws Exception {
+    qProfiles.updateDefaultProfile("Default", "java");
+    verify(operations).updateDefaultProfile(eq("Default"), eq("java"), any(UserSession.class));
   }
 
   @Test(expected = UnsupportedOperationException.class)