]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3633 improve the management of server-side settings
authorSimon Brandhof <simon.brandhof@gmail.com>
Fri, 13 Jul 2012 18:28:40 +0000 (20:28 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Fri, 13 Jul 2012 18:33:35 +0000 (20:33 +0200)
* do not save default resource permissions in a db migration but in a server-side extension

* new component to save settings from server-side components. It will have to be used by ruby app later.

38 files changed:
sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java
sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml
sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java
sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperties-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperties.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperty-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperty.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/saveGlobalProperties-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/saveGlobalProperties.xml [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
sonar-server/src/main/java/org/sonar/server/configuration/Backup.java
sonar-server/src/main/java/org/sonar/server/configuration/PropertiesBackup.java
sonar-server/src/main/java/org/sonar/server/platform/GlobalSettingsUpdater.java [deleted file]
sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/platform/Platform.java
sonar-server/src/main/java/org/sonar/server/platform/ServerDatabaseSettingsLoader.java [deleted file]
sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java
sonar-server/src/main/java/org/sonar/server/startup/RegisterNewDashboards.java
sonar-server/src/main/java/org/sonar/server/startup/RegisterNewFilters.java
sonar-server/src/main/java/org/sonar/server/startup/ServerMetadataPersister.java
sonar-server/src/main/java/org/sonar/server/startup/SetDefaultProjectPermissions.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
sonar-server/src/main/webapp/WEB-INF/db/migrate/320_move_default_roles.rb
sonar-server/src/test/java/org/sonar/server/configuration/ProfilesBackupTest.java
sonar-server/src/test/java/org/sonar/server/configuration/PropertiesBackupTest.java
sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java
sonar-server/src/test/java/org/sonar/server/startup/ServerMetadataPersisterTest.java
sonar-server/src/test/java/org/sonar/server/startup/SetDefaultProjectPermissionsTest.java [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/conf/sonar.properties
sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/db/shared.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testDeleteProperties-result.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testDeleteProperties.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testSaveProperties-result.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testSaveProperties.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testUpdateExistingProperties-result.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testUpdateExistingProperties.xml [deleted file]

index c21cd08f48ec7aa19ad48c4c2a6a6b270991588a..a496d826fc68e535908417fb4968f1895193d25c 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.api.ServerComponent;
 import org.sonar.core.persistence.MyBatis;
 
 import java.util.List;
+import java.util.Map;
 
 public class PropertiesDao implements BatchComponent, ServerComponent {
 
@@ -89,4 +90,45 @@ public class PropertiesDao implements BatchComponent, ServerComponent {
       MyBatis.closeQuietly(session);
     }
   }
+
+  public void deleteGlobalProperties() {
+    SqlSession session = mybatis.openSession();
+    PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
+    try {
+      mapper.deleteGlobalProperties();
+      session.commit();
+
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  public void deleteGlobalProperty(String key) {
+    SqlSession session = mybatis.openSession();
+    PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
+    try {
+      mapper.deleteGlobalProperty(key);
+      session.commit();
+
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  public void saveGlobalProperties(Map<String, String> properties) {
+    SqlSession session = mybatis.openBatchSession();
+    PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
+    try {
+      for (Map.Entry<String, String> entry : properties.entrySet()) {
+        mapper.deleteGlobalProperty(entry.getKey());
+      }
+      for (Map.Entry<String, String> entry : properties.entrySet()) {
+        mapper.insert(new PropertyDto().setKey(entry.getKey()).setValue(entry.getValue()));
+      }
+      session.commit();
+
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
 }
index 1f75ed36dfbd64b07e8e818b265a2ebea6e770e9..cb63e4bb2271d4ff723442fa86c8adb47ff12be6 100644 (file)
@@ -32,5 +32,6 @@ public interface PropertiesMapper {
   PropertyDto selectByKey(PropertyDto key);
   void update(PropertyDto property);
   void insert(PropertyDto property);
-
+  void deleteGlobalProperty(String key);
+  void deleteGlobalProperties();
 }
index 768c4f4dfe65d7173ce6120f988a8c08177f6920..913e1ff6d9ce1f6b0271b2e45e84a117302044bf 100644 (file)
@@ -10,28 +10,6 @@ ALTER TABLE GROUP_ROLES ALTER COLUMN ID RESTART WITH 2;
 INSERT INTO GROUPS_USERS(USER_ID, GROUP_ID) VALUES (1, 1);
 INSERT INTO GROUPS_USERS(USER_ID, GROUP_ID) VALUES (1, 2);
 
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (1, 'sonar.role.admin.TRK.defaultGroups', 'sonar-administrators');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (2, 'sonar.role.admin.TRK.defaultUsers', '');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (3, 'sonar.role.user.TRK.defaultGroups', 'Anyone,sonar-users');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (4, 'sonar.role.user.TRK.defaultUsers', '');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (5, 'sonar.role.codeviewer.TRK.defaultGroups', 'Anyone,sonar-users');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (6, 'sonar.role.codeviewer.TRK.defaultUsers', '');
-
--- COMPATIBILITY WITH OLD VERSIONS OF VIEWS PLUGIN -> see migration 320
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (7, 'sonar.role.admin.VW.defaultGroups', 'sonar-administrators');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (8, 'sonar.role.admin.VW.defaultUsers', '');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (9, 'sonar.role.user.VW.defaultGroups', 'Anyone,sonar-users');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (10, 'sonar.role.user.VW.defaultUsers', '');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (11, 'sonar.role.codeviewer.VW.defaultGroups', 'Anyone,sonar-users');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (12, 'sonar.role.codeviewer.VW.defaultUsers', '');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (13, 'sonar.role.admin.SVW.defaultGroups', 'sonar-administrators');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (14, 'sonar.role.admin.SVW.defaultUsers', '');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (15, 'sonar.role.user.SVW.defaultGroups', 'Anyone,sonar-users');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (16, 'sonar.role.user.SVW.defaultUsers', '');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (17, 'sonar.role.codeviewer.SVW.defaultGroups', 'Anyone,sonar-users');
-INSERT INTO PROPERTIES(ID, PROP_KEY, TEXT_VALUE) VALUES (18, 'sonar.role.codeviewer.SVW.defaultUsers', '');
-ALTER TABLE PROPERTIES ALTER COLUMN ID RESTART WITH 19;
-
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('2');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('10');
index 768ee357f24a06154aa5c8c1c72778652e37c4b8..d3d55c0008f0f8c04688d4d00e41a67483b67743 100644 (file)
     update properties set text_value = #{value} where id = #{id}
   </update>
 
-  <insert id="insert" parameterType="Property" useGeneratedKeys="true" keyProperty="id">
+  <insert id="insert" parameterType="Property" useGeneratedKeys="false">
     INSERT INTO properties (prop_key, resource_id, user_id, text_value)
     VALUES (#{key}, #{resourceId}, #{userId}, #{value})
   </insert>
 
   <!-- Oracle -->
-  <insert id="insert" databaseId="oracle" parameterType="Property" useGeneratedKeys="true" keyProperty="id">
+  <insert id="insert" databaseId="oracle" parameterType="Property" useGeneratedKeys="false">
     <selectKey order="BEFORE" resultType="Long" keyProperty="id">
       select properties_seq.NEXTVAL from DUAL
     </selectKey>
     VALUES (#{id}, #{key}, #{resourceId}, #{userId}, #{value})
   </insert>
 
+  <delete id="deleteGlobalProperty" parameterType="string">
+    delete from properties where prop_key=#{id} and resource_id is null and user_id is null
+  </delete>
+
+  <delete id="deleteGlobalProperties">
+    delete from properties where resource_id is null and user_id is null
+  </delete>
+
 </mapper>
index 20c39047808960ca7be7ad74682e3666e14888da..6fef82d9fd76188b33b70d56a09e0ee20d98c5e8 100644 (file)
  */
 package org.sonar.core.properties;
 
+import com.google.common.collect.Maps;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.core.persistence.AbstractDaoTestCase;
 
 import java.util.List;
+import java.util.TreeMap;
 
 import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.is;
@@ -34,12 +36,12 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
   private PropertiesDao dao;
 
   @Before
-  public void createDao() throws Exception {
+  public void createDao() {
     dao = new PropertiesDao(getMyBatis());
   }
 
   @Test
-  public void shouldFindUserIdsForFavouriteResource() throws Exception {
+  public void shouldFindUserIdsForFavouriteResource() {
     setupData("shouldFindUserIdsForFavouriteResource");
     List<String> userIds = dao.findUserIdsForFavouriteResource(2L);
     assertThat(userIds.size(), is(2));
@@ -47,7 +49,7 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void selectGlobalProperties() throws Exception {
+  public void selectGlobalProperties() {
     setupData("selectGlobalProperties");
     List<PropertyDto> properties = dao.selectGlobalProperties();
     assertThat(properties.size(), is(2));
@@ -62,7 +64,7 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void selectProjectProperties() throws Exception {
+  public void selectProjectProperties() {
     setupData("selectProjectProperties");
     List<PropertyDto> properties = dao.selectProjectProperties("org.struts:struts");
     assertThat(properties.size(), is(1));
@@ -73,7 +75,7 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void setProperty_update() throws Exception {
+  public void setProperty_update() {
     setupData("update");
 
     dao.setProperty(new PropertyDto().setKey("global.key").setValue("new_global"));
@@ -85,7 +87,7 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void setProperty_insert() throws Exception {
+  public void setProperty_insert() {
     setupData("insert");
 
     dao.setProperty(new PropertyDto().setKey("global.key").setValue("new_global"));
@@ -95,6 +97,36 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
     checkTables("insert", "properties");
   }
 
+  @Test
+  public void deleteGlobalProperties() {
+    setupData("deleteGlobalProperties");
+
+    dao.deleteGlobalProperties();
+
+    checkTables("deleteGlobalProperties", "properties");
+  }
+
+  @Test
+  public void deleteGlobalProperty() {
+    setupData("deleteGlobalProperty");
+
+    dao.deleteGlobalProperty("to_be_deleted");
+
+    checkTables("deleteGlobalProperty", "properties");
+  }
+
+  @Test
+  public void saveGlobalProperties() {
+    setupData("saveGlobalProperties");
+
+    TreeMap<String, String> props = Maps.newTreeMap();
+    props.put("to_be_inserted", "inserted");
+    props.put("to_be_updated", "updated");
+    dao.saveGlobalProperties(props);
+
+    checkTable("saveGlobalProperties", "properties", "prop_key", "text_value", "resource_id", "user_id");
+  }
+
   private PropertyDto findById(List<PropertyDto> properties, int id) {
     for (PropertyDto property : properties) {
       if (property.getId() == id) {
diff --git a/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperties-result.xml b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperties-result.xml
new file mode 100644 (file)
index 0000000..a5cfed3
--- /dev/null
@@ -0,0 +1,12 @@
+<dataset>
+
+  <!-- global -->
+  <!--<properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/>-->
+
+  <!-- project -->
+  <properties id="2" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+  <!-- user -->
+  <properties id="3" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperties.xml b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperties.xml
new file mode 100644 (file)
index 0000000..3e5eb87
--- /dev/null
@@ -0,0 +1,12 @@
+<dataset>
+
+  <!-- global -->
+  <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/>
+
+  <!-- project -->
+  <properties id="2" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+  <!-- user -->
+  <properties id="3" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperty-result.xml b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperty-result.xml
new file mode 100644 (file)
index 0000000..0428139
--- /dev/null
@@ -0,0 +1,13 @@
+<dataset>
+
+  <!-- global -->
+  <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/>
+  <!--<properties id="2" prop_key="to_be_deleted" text_value="xxx" resource_id="[null]" user_id="[null]"/>-->
+
+  <!-- project -->
+  <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+  <!-- user -->
+  <properties id="4" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperty.xml b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/deleteGlobalProperty.xml
new file mode 100644 (file)
index 0000000..aaf0fd6
--- /dev/null
@@ -0,0 +1,13 @@
+<dataset>
+
+  <!-- global -->
+  <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/>
+  <properties id="2" prop_key="to_be_deleted" text_value="xxx" resource_id="[null]" user_id="[null]"/>
+
+  <!-- project - do not delete this project property that has the same key -->
+  <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+  <!-- user -->
+  <properties id="4" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/saveGlobalProperties-result.xml b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/saveGlobalProperties-result.xml
new file mode 100644 (file)
index 0000000..f12984a
--- /dev/null
@@ -0,0 +1,18 @@
+<dataset>
+
+  <!-- global -->
+  <!--<properties id="1" prop_key="to_be_updated" text_value="old value" resource_id="[null]" user_id="[null]"/>-->
+  <properties id="2" prop_key="to_not_change" text_value="xxx" resource_id="[null]" user_id="[null]"/>
+
+  <!-- project - do not update this project property that has the same key -->
+  <properties id="3" prop_key="to_be_updated" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+  <!-- user -->
+  <properties id="4" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+
+  <properties id="5" prop_key="to_be_inserted" text_value="inserted" resource_id="[null]" user_id="[null]"/>
+  <properties id="6" prop_key="to_be_updated" text_value="updated" resource_id="[null]" user_id="[null]"/>
+
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/saveGlobalProperties.xml b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/saveGlobalProperties.xml
new file mode 100644 (file)
index 0000000..b0fa0be
--- /dev/null
@@ -0,0 +1,13 @@
+<dataset>
+
+  <!-- global -->
+  <properties id="1" prop_key="to_be_updated" text_value="old value" resource_id="[null]" user_id="[null]"/>
+  <properties id="2" prop_key="to_not_change" text_value="xxx" resource_id="[null]" user_id="[null]"/>
+
+  <!-- project - do not update this project property that has the same key -->
+  <properties id="3" prop_key="to_be_updated" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+  <!-- user -->
+  <properties id="4" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+</dataset>
index 2b8423a67d7f436a6679888fcad95279e6791b3a..5b118ecd4fccdbdcc77dfc0ebb6078edbd2cd42e 100644 (file)
@@ -210,43 +210,34 @@ public class Settings implements BatchComponent, ServerComponent {
     } else {
       newValue += "," + StringUtils.trim(value);
     }
-    properties.put(key, newValue);
-    return this;
+    return setProperty(key, newValue);
   }
 
   public final Settings setProperty(String key, @Nullable String value) {
-    if (!clearIfNullValue(key, value)) {
+    if (value == null) {
+      properties.remove(key);
+      doOnRemoveProperty(key);
+    } else {
       properties.put(key, StringUtils.trim(value));
+      doOnSetProperty(key, value);
     }
     return this;
   }
 
   public final Settings setProperty(String key, @Nullable Boolean value) {
-    if (!clearIfNullValue(key, value)) {
-      properties.put(key, String.valueOf(value));
-    }
-    return this;
+    return setProperty(key, String.valueOf(value));
   }
 
   public final Settings setProperty(String key, @Nullable Integer value) {
-    if (!clearIfNullValue(key, value)) {
-      properties.put(key, String.valueOf(value));
-    }
-    return this;
+    return setProperty(key, String.valueOf(value));
   }
 
   public final Settings setProperty(String key, @Nullable Long value) {
-    if (!clearIfNullValue(key, value)) {
-      properties.put(key, String.valueOf(value));
-    }
-    return this;
+    return setProperty(key, String.valueOf(value));
   }
 
   public final Settings setProperty(String key, @Nullable Double value) {
-    if (!clearIfNullValue(key, value)) {
-      properties.put(key, String.valueOf(value));
-    }
-    return this;
+    return setProperty(key, String.valueOf(value));
   }
 
   public final Settings setProperty(String key, @Nullable Date date) {
@@ -276,24 +267,21 @@ public class Settings implements BatchComponent, ServerComponent {
   }
 
   public final Settings setProperties(Map<String, String> props) {
-    properties.clear();
+    clear();
     return addProperties(props);
   }
 
   public final Settings setProperty(String key, @Nullable Date date, boolean includeTime) {
-    if (!clearIfNullValue(key, date)) {
-      properties.put(key, includeTime ? DateUtils.formatDateTime(date) : DateUtils.formatDate(date));
-    }
-    return this;
+    return setProperty(key, includeTime ? DateUtils.formatDateTime(date) : DateUtils.formatDate(date));
   }
 
   public final Settings removeProperty(String key) {
-    properties.remove(key);
-    return this;
+    return setProperty(key, (String) null);
   }
 
   public final Settings clear() {
     properties.clear();
+    doOnClearProperties();
     return this;
   }
 
@@ -308,14 +296,6 @@ public class Settings implements BatchComponent, ServerComponent {
     return definitions;
   }
 
-  private boolean clearIfNullValue(String key, @Nullable Object value) {
-    if (value == null) {
-      properties.remove(key);
-      return true;
-    }
-    return false;
-  }
-
   /**
    * Create empty settings. Definition of available properties is loaded from the given annotated class.
    * This method is usually used by unit tests.
@@ -323,4 +303,13 @@ public class Settings implements BatchComponent, ServerComponent {
   public static Settings createForComponent(Object component) {
     return new Settings(new PropertyDefinitions(component));
   }
+
+  protected void doOnSetProperty(String key, @Nullable String value) {
+  }
+
+  protected void doOnRemoveProperty(String key) {
+  }
+
+  protected void doOnClearProperties() {
+  }
 }
index 8b6583a959fc36573e4de6878f7fc8778378ed66..7e495cf8746672ec87663b47e9a40a0c58696902 100644 (file)
@@ -31,6 +31,7 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.database.DatabaseSession;
 import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.server.platform.PersistentSettings;
 
 import javax.annotation.Nullable;
 import java.io.IOException;
@@ -52,12 +53,12 @@ public class Backup {
     backupables = new ArrayList<Backupable>();
   }
 
-  public Backup(DatabaseSession session) {
+  public Backup(DatabaseSession session, PersistentSettings persistentSettings) {
     this();
     this.session = session;
 
     backupables.add(new MetricsBackup(session));
-    backupables.add(new PropertiesBackup(session));
+    backupables.add(new PropertiesBackup(persistentSettings));
     // Note that order is important, because profile can have reference to rule
     backupables.add(new RulesBackup(session));
     backupables.add(new ProfilesBackup(session));
@@ -153,27 +154,27 @@ public class Backup {
 
   private XStream getConfiguredXstream() {
     XStream xStream = new XStream(
-        new XppDriver() {
-          @Override
-          public HierarchicalStreamWriter createWriter(Writer out) {
-            return new PrettyPrintWriter(out) {
-              @Override
-              protected void writeText(QuickWriter writer, @Nullable String text) {
-                if (text != null) {
-                  writer.write("<![CDATA[");
-                  /*
-                  * See http://jira.codehaus.org/browse/SONAR-1605 According to XML specification (
-                  * http://www.w3.org/TR/REC-xml/#sec-cdata-sect ) CData section may contain everything except of sequence ']]>' so we will
-                  * split all occurrences of this sequence into two CDATA first one would contain ']]' and second '>'
-                  */
-                  text = StringUtils.replace(text, "]]>", "]]]]><![CDATA[>");
-                  writer.write(text);
-                  writer.write("]]>");
-                }
+      new XppDriver() {
+        @Override
+        public HierarchicalStreamWriter createWriter(Writer out) {
+          return new PrettyPrintWriter(out) {
+            @Override
+            protected void writeText(QuickWriter writer, @Nullable String text) {
+              if (text != null) {
+                writer.write("<![CDATA[");
+                /*
+                * See http://jira.codehaus.org/browse/SONAR-1605 According to XML specification (
+                * http://www.w3.org/TR/REC-xml/#sec-cdata-sect ) CData section may contain everything except of sequence ']]>' so we will
+                * split all occurrences of this sequence into two CDATA first one would contain ']]' and second '>'
+                */
+                text = StringUtils.replace(text, "]]>", "]]]]><![CDATA[>");
+                writer.write(text);
+                writer.write("]]>");
               }
-            };
-          }
-        });
+            }
+          };
+        }
+      });
 
     xStream.processAnnotations(SonarConfig.class);
     xStream.addDefaultImplementation(ArrayList.class, Collection.class);
index d0fb42a07777024b92f6d02503b319ea5ec75418..359db78cbaf04d061b91bda0613345e6894aa9c2 100644 (file)
  */
 package org.sonar.server.configuration;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.thoughtworks.xstream.XStream;
 import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.database.DatabaseSession;
 import org.sonar.api.database.configuration.Property;
+import org.sonar.server.platform.PersistentSettings;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 public class PropertiesBackup implements Backupable {
 
-  private DatabaseSession databaseSession;
-  private static final String FROM_GLOBAL_PROPERTIES = "from " + Property.class.getSimpleName() + " p WHERE p.resourceId IS NULL and user_id is null";
+  private final PersistentSettings persistentSettings;
 
-  public PropertiesBackup(DatabaseSession databaseSession) {
-    this.databaseSession = databaseSession;
+  public PropertiesBackup(PersistentSettings persistentSettings) {
+    this.persistentSettings = persistentSettings;
   }
 
   public void exportXml(SonarConfig sonarConfig) {
-    List<Property> xmlProperties = new ArrayList<Property>();
+    List<Property> xmlProperties = Lists.newArrayList();
 
-    List<Property> dbProperties = databaseSession.createQuery(FROM_GLOBAL_PROPERTIES).getResultList();
-    if (dbProperties != null) {
-      for (Property dbProperty : dbProperties) {
-        String propKey = dbProperty.getKey();
-        if (!CoreProperties.SERVER_ID.equals(propKey)) {
-          // "sonar.core.id" must never be restored, it is unique for a server and it created once at the 1rst server startup
-          xmlProperties.add(new Property(dbProperty.getKey(), dbProperty.getValue()));
-        }
+    for (Map.Entry<String, String> entry : persistentSettings.getProperties().entrySet()) {
+      // "sonar.core.id" must never be restored, it is unique for a server and it created once at the 1rst server startup
+      if (!CoreProperties.SERVER_ID.equals(entry.getKey())) {
+        xmlProperties.add(new Property(entry.getKey(), entry.getValue()));
       }
-      sonarConfig.setProperties(xmlProperties);
     }
+    sonarConfig.setProperties(xmlProperties);
   }
 
   public void importXml(SonarConfig sonarConfig) {
     LoggerFactory.getLogger(getClass()).info("Restore properties");
-    clearProperties();
 
+    // "sonar.core.id" property should not be cleared, because it is the unique key used to identify the server
+    // and it is used by the batch to verify that it connects to the same DB as the remote server (see SONAR-3126).
+    String serverId = persistentSettings.getString(CoreProperties.SERVER_ID);
+    String serverStartTime = persistentSettings.getString(CoreProperties.SERVER_STARTTIME);
+
+    Map<String, String> properties = Maps.newHashMap();
     if (CollectionUtils.isNotEmpty(sonarConfig.getProperties())) {
       for (Property xmlProperty : sonarConfig.getProperties()) {
-        String propKey = xmlProperty.getKey();
-        if (!CoreProperties.SERVER_ID.equals(propKey)) {
-          // "sonar.core.id" must never be restored, it is unique for a server and it created once at the 1rst server startup
-          databaseSession.save(new Property(propKey, xmlProperty.getValue()));
-        }
+        properties.put(xmlProperty.getKey(), xmlProperty.getValue());
       }
     }
-    databaseSession.commit();
-  }
-
-  private void clearProperties() {
-    // "sonar.core.id" property should not be cleared, because it is the unique key used to identify the server
-    // and it is used by the batch to verify that it connects to the same DB as the remote server (see SONAR-3126).
-    databaseSession.createQuery("delete " + FROM_GLOBAL_PROPERTIES + " and prop_key != '" + CoreProperties.SERVER_ID + "'").executeUpdate();
+    properties.put(CoreProperties.SERVER_ID, serverId);
+    properties.put(CoreProperties.SERVER_STARTTIME, serverStartTime);
+    persistentSettings.deleteProperties();
+    persistentSettings.saveProperties(properties);
   }
 
   public void configure(XStream xStream) {
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/GlobalSettingsUpdater.java b/sonar-server/src/main/java/org/sonar/server/platform/GlobalSettingsUpdater.java
deleted file mode 100644 (file)
index d2d6507..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.server.platform;
-
-import org.apache.commons.configuration.Configuration;
-import org.sonar.api.config.GlobalPropertyChangeHandler;
-
-import javax.annotation.Nullable;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Update cache of global settings (see org.sonar.api.config.Settings) and notify org.sonar.api.config.GlobalPropertyChangeHandler extensions
- *
- * @since 3.0
- */
-public class GlobalSettingsUpdater {
-  private ServerSettings settings;
-  private Configuration deprecatedConf;
-  private List<GlobalPropertyChangeHandler> changeHandlers;
-
-  public GlobalSettingsUpdater(ServerSettings settings, Configuration config, List<GlobalPropertyChangeHandler> changeHandlers) {
-    this.settings = settings;
-    this.deprecatedConf = config;
-    this.changeHandlers = changeHandlers;
-  }
-
-  public GlobalSettingsUpdater(ServerSettings settings, Configuration config) {
-    this(settings, config, Collections.<GlobalPropertyChangeHandler>emptyList());
-  }
-
-  public void setProperty(String key, @Nullable String value) {
-    settings.setProperty(key, value);
-    deprecatedConf.setProperty(key, value);
-
-    GlobalPropertyChangeHandler.PropertyChange change = GlobalPropertyChangeHandler.PropertyChange.create(key, value);
-    for (GlobalPropertyChangeHandler changeHandler : changeHandlers) {
-      changeHandler.onChange(change);
-    }
-  }
-}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java b/sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java
new file mode 100644 (file)
index 0000000..0b922d9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.platform;
+
+import com.google.common.collect.Maps;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.config.Settings;
+import org.sonar.core.properties.PropertiesDao;
+import org.sonar.core.properties.PropertyDto;
+
+import javax.annotation.Nullable;
+import java.util.Map;
+
+/**
+ * @since 3.2
+ */
+public class PersistentSettings implements ServerComponent {
+  private final PropertiesDao propertiesDao;
+  private final ServerSettings settings;
+
+  public PersistentSettings(PropertiesDao propertiesDao, ServerSettings settings) {
+    this.propertiesDao = propertiesDao;
+    this.settings = settings;
+  }
+
+  public void start() {
+    Map<String, String> databaseProperties = Maps.newHashMap();
+    for (PropertyDto property : propertiesDao.selectGlobalProperties()) {
+      databaseProperties.put(property.getKey(), property.getValue());
+    }
+    settings.activateDatabaseSettings(SonarHome.getHome(), databaseProperties);
+  }
+
+  public PersistentSettings saveProperty(String key, @Nullable String value) {
+    settings.setProperty(key, value);
+    propertiesDao.setProperty(new PropertyDto().setKey(key).setValue(value));
+    return this;
+  }
+
+  public PersistentSettings removeProperty(String key) {
+    settings.removeProperty(key);
+    propertiesDao.deleteGlobalProperty(key);
+    return this;
+  }
+
+  public PersistentSettings deleteProperties() {
+    settings.clear();
+    propertiesDao.deleteGlobalProperties();
+    return this;
+  }
+
+  public PersistentSettings saveProperties(Map<String, String> properties) {
+    settings.addProperties(properties);
+    propertiesDao.saveGlobalProperties(properties);
+    return this;
+  }
+
+  public String getString(String key) {
+    return settings.getString(key);
+  }
+
+  public Map<String, String> getProperties() {
+    return settings.getProperties();
+  }
+
+  public Settings getSettings() {
+    return settings;
+  }
+}
index e20fed0c4c0dc415d6f0e07bb0f9e0bdc27acadb..287f8e2f541bf4bb72d26c95ac097989cbcf5da9 100644 (file)
@@ -78,19 +78,7 @@ import org.sonar.server.plugins.UpdateCenterMatrixFactory;
 import org.sonar.server.qualitymodel.DefaultModelManager;
 import org.sonar.server.rules.ProfilesConsole;
 import org.sonar.server.rules.RulesConsole;
-import org.sonar.server.startup.ActivateDefaultProfiles;
-import org.sonar.server.startup.DeleteDeprecatedMeasures;
-import org.sonar.server.startup.EnableProfiles;
-import org.sonar.server.startup.GeneratePluginIndex;
-import org.sonar.server.startup.GwtPublisher;
-import org.sonar.server.startup.JdbcDriverDeployer;
-import org.sonar.server.startup.RegisterMetrics;
-import org.sonar.server.startup.RegisterNewDashboards;
-import org.sonar.server.startup.RegisterNewFilters;
-import org.sonar.server.startup.RegisterProvidedProfiles;
-import org.sonar.server.startup.RegisterQualityModels;
-import org.sonar.server.startup.RegisterRules;
-import org.sonar.server.startup.ServerMetadataPersister;
+import org.sonar.server.startup.*;
 import org.sonar.server.ui.CodeColorizers;
 import org.sonar.server.ui.JRubyI18n;
 import org.sonar.server.ui.SecurityRealmFactory;
@@ -184,7 +172,7 @@ public final class Platform {
 
   private void startCoreComponents() {
     coreContainer = rootContainer.createChild();
-    coreContainer.addSingleton(ServerDatabaseSettingsLoader.class);
+    coreContainer.addSingleton(PersistentSettings.class);
     coreContainer.addSingleton(DefaultDatabaseConnector.class);
     coreContainer.addSingleton(ServerExtensionInstaller.class);
     coreContainer.addSingleton(ThreadLocalDatabaseSessionFactory.class);
@@ -204,7 +192,6 @@ public final class Platform {
     servicesContainer.addSingleton(ReviewDatabaseStore.class);
     servicesContainer.addSingleton(WorkflowEngine.class);
 
-    servicesContainer.addSingleton(GlobalSettingsUpdater.class);
     servicesContainer.addSingleton(HttpDownloader.class);
     servicesContainer.addSingleton(UpdateCenterClient.class);
     servicesContainer.addSingleton(UpdateCenterMatrixFactory.class);
@@ -267,6 +254,7 @@ public final class Platform {
     startupContainer.addSingleton(GeneratePluginIndex.class);
     startupContainer.addSingleton(RegisterNewFilters.class);
     startupContainer.addSingleton(RegisterNewDashboards.class);
+    startupContainer.addSingleton(SetDefaultProjectPermissions.class);
     startupContainer.startComponents();
 
     startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart();
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerDatabaseSettingsLoader.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerDatabaseSettingsLoader.java
deleted file mode 100644 (file)
index 0596e81..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.server.platform;
-
-import org.sonar.core.properties.PropertiesDao;
-
-/**
- * @since 3.0
- */
-public final class ServerDatabaseSettingsLoader {
-
-  private PropertiesDao propertiesDao;
-  private ServerSettings settings;
-
-  public ServerDatabaseSettingsLoader(PropertiesDao propertiesDao, ServerSettings settings) {
-    this.propertiesDao = propertiesDao;
-    this.settings = settings;
-  }
-
-  public void start() {
-    settings.activateDatabaseSettings(propertiesDao);
-  }
-}
index fbcaaaa576e8ae714ca6d913c0171eed9280264f..07f0f4e65b433f62fa39e8a7959591417175b1cd 100644 (file)
@@ -22,15 +22,17 @@ package org.sonar.server.platform;
 import com.google.common.annotations.VisibleForTesting;
 import org.apache.commons.configuration.Configuration;
 import org.sonar.api.CoreProperties;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.config.GlobalPropertyChangeHandler;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
 import org.sonar.core.config.ConfigurationUtils;
-import org.sonar.core.properties.PropertiesDao;
-import org.sonar.core.properties.PropertyDto;
 
+import javax.annotation.Nullable;
 import javax.servlet.ServletContext;
 import java.io.File;
-import java.util.List;
+import java.util.Collections;
+import java.util.Map;
 import java.util.Properties;
 
 /**
@@ -44,50 +46,42 @@ import java.util.Properties;
  *
  * @since 2.12
  */
-public class ServerSettings extends Settings {
+public class ServerSettings extends Settings implements ServerComponent {
 
   public static final String DEPLOY_DIR = "sonar.web.deployDir";
 
-  private PropertiesDao propertiesDao;
   private Configuration deprecatedConfiguration;
   private File deployDir;
+  private GlobalPropertyChangeHandler[] changeHandlers;
+
+  public ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, ServletContext servletContext, GlobalPropertyChangeHandler[] changeHandlers) {
+    this(definitions, deprecatedConfiguration, getDeployDir(servletContext), SonarHome.getHome(), changeHandlers);
+  }
 
   public ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, ServletContext servletContext) {
-    super(definitions);
-    this.deprecatedConfiguration = deprecatedConfiguration;
-    this.deployDir = getDeployDir(servletContext);
-    load();
+    this(definitions, deprecatedConfiguration, servletContext, new GlobalPropertyChangeHandler[0]);
   }
 
-  ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, File deployDir, File sonarHome) {
+  @VisibleForTesting
+  ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, File deployDir, File sonarHome, GlobalPropertyChangeHandler[] changeHandlers) {
     super(definitions);
     this.deprecatedConfiguration = deprecatedConfiguration;
     this.deployDir = deployDir;
-    load(sonarHome);
-  }
-
-  public ServerSettings activateDatabaseSettings(PropertiesDao dao) {
-    return activateDatabaseSettings(dao, SonarHome.getHome());
-  }
-
-  @VisibleForTesting
-  ServerSettings activateDatabaseSettings(PropertiesDao dao, File sonarHome) {
-    this.propertiesDao = dao;
-    load(sonarHome);
-    return this;
+    this.changeHandlers = changeHandlers;
+    load(sonarHome, Collections.<String, String>emptyMap());
   }
 
-  private ServerSettings load() {
-    return load(SonarHome.getHome());
+  public ServerSettings activateDatabaseSettings(File sonarHome, Map<String, String> databaseProperties) {
+    return load(sonarHome, databaseProperties);
   }
 
-  private ServerSettings load(File sonarHome) {
-    clear();
-    setProperty(CoreProperties.SONAR_HOME, sonarHome.getAbsolutePath());
-    setProperty(DEPLOY_DIR, deployDir.getAbsolutePath());
+  private ServerSettings load(File sonarHome, Map<String, String> databaseSettings) {
+    properties.clear();
+    properties.put(CoreProperties.SONAR_HOME, sonarHome.getAbsolutePath());
+    properties.put(DEPLOY_DIR, deployDir.getAbsolutePath());
 
     // order is important : the last override the first
-    loadDatabaseSettings();
+    properties.putAll(databaseSettings);
     loadPropertiesFile(sonarHome);
     addEnvironmentVariables();
     addSystemProperties();
@@ -98,15 +92,6 @@ public class ServerSettings extends Settings {
     return this;
   }
 
-  private void loadDatabaseSettings() {
-    if (propertiesDao != null) {
-      List<PropertyDto> dpProps = propertiesDao.selectGlobalProperties();
-      for (PropertyDto dbProp : dpProps) {
-        setProperty(dbProp.getKey(), dbProp.getValue());
-      }
-    }
-  }
-
   private void loadPropertiesFile(File sonarHome) {
     File propertiesFile = new File(sonarHome, "conf/sonar.properties");
     if (!propertiesFile.isFile() || !propertiesFile.exists()) {
@@ -116,7 +101,9 @@ public class ServerSettings extends Settings {
     try {
       Properties p = ConfigurationUtils.openProperties(propertiesFile);
       p = ConfigurationUtils.interpolateEnvVariables(p);
-      addProperties(p);
+      for (Map.Entry<Object, Object> entry : p.entrySet()) {
+        properties.put(entry.getKey().toString(), entry.getValue().toString());
+      }
     } catch (Exception e) {
       throw new IllegalStateException("Fail to load configuration file: " + propertiesFile, e);
     }
@@ -133,4 +120,24 @@ public class ServerSettings extends Settings {
     }
     return dir;
   }
+
+  @Override
+  protected void doOnSetProperty(String key, @Nullable String value) {
+    deprecatedConfiguration.setProperty(key, value);
+
+    GlobalPropertyChangeHandler.PropertyChange change = GlobalPropertyChangeHandler.PropertyChange.create(key, value);
+    for (GlobalPropertyChangeHandler changeHandler : changeHandlers) {
+      changeHandler.onChange(change);
+    }
+  }
+
+  @Override
+  protected void doOnRemoveProperty(String key) {
+    deprecatedConfiguration.clearProperty(key);
+  }
+
+  @Override
+  protected void doOnClearProperties() {
+    deprecatedConfiguration.clear();
+  }
 }
index 5f11a57d6703c311d36c1b4cacedb12da176a112..82943acaa0dde329ddbb1c9f578d08b7a7d8053f 100644 (file)
@@ -93,7 +93,7 @@ public final class RegisterNewDashboards {
         .setOrderIndex(index);
     activeDashboardDao.insert(activeDashboardDto);
 
-    LOG.info("New dashboard '" + dashboardDto.getName() + "' registered");
+    LoggerFactory.getLogger(getClass()).info("New dashboard '" + dashboardDto.getName() + "' registered");
   }
 
   protected DashboardDto register(String name, Dashboard dashboard) {
index 470a2eeaad51538768911e6393308d2828d8b4ef..1a9c7b1d2338338df45e1e2fbbd6ab895da0aeab 100644 (file)
@@ -53,7 +53,7 @@ public final class RegisterNewFilters {
   }
 
   public void start() {
-    TimeProfiler profiler = new TimeProfiler().start("Register filters");
+    TimeProfiler profiler = new TimeProfiler(LoggerFactory.getLogger(getClass())).start("Register filters");
 
     for (FilterTemplate template : filterTemplates) {
       if (shouldRegister(template.getName())) {
index 93c3a92e8770a7a367e0e286cd44b2ec89c0dba5..52592b355273f96d9427874cac995cc0563322bd 100644 (file)
  */
 package org.sonar.server.startup;
 
+import com.google.common.collect.ImmutableMap;
+import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.configuration.Property;
 import org.sonar.api.platform.Server;
+import org.sonar.server.platform.PersistentSettings;
 
 import java.text.SimpleDateFormat;
 
-public class ServerMetadataPersister {
+public final class ServerMetadataPersister {
 
   private final Server server;
-  private final DatabaseSession session;
+  private final PersistentSettings persistentSettings;
 
-  public ServerMetadataPersister(Server server, DatabaseSession session) {
+  public ServerMetadataPersister(Server server, PersistentSettings persistentSettings) {
     this.server = server;
-    this.session = session;
+    this.persistentSettings = persistentSettings;
   }
 
   public void start() {
-    setProperty(CoreProperties.SERVER_ID, server.getId());
-    setProperty(CoreProperties.SERVER_VERSION, server.getVersion());
-    setProperty(CoreProperties.SERVER_STARTTIME, new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(server.getStartedAt()));
-    session.commit();
-  }
-
-  private void setProperty(String key, String value) {
-    Property prop = session.getSingleResult(Property.class, "key", key);
-
-    if (value == null && prop != null) {
-      session.removeWithoutFlush(prop);
-
-    } else if (value != null) {
-      if (prop == null) {
-        prop = new Property(key, value);
-      } else {
-        prop.setValue(value);
-      }
-      session.saveWithoutFlush(prop);
-    }
+    LoggerFactory.getLogger(getClass()).debug("Persisting server metadata");
+    persistentSettings.saveProperties(ImmutableMap.of(
+      CoreProperties.SERVER_ID, server.getId(),
+      CoreProperties.SERVER_VERSION, server.getVersion(),
+      CoreProperties.SERVER_STARTTIME, new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(server.getStartedAt())));
   }
 }
\ No newline at end of file
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/SetDefaultProjectPermissions.java b/sonar-server/src/main/java/org/sonar/server/startup/SetDefaultProjectPermissions.java
new file mode 100644 (file)
index 0000000..318a8ff
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.startup;
+
+import com.google.common.collect.Maps;
+import org.slf4j.LoggerFactory;
+import org.sonar.server.platform.PersistentSettings;
+
+import java.util.Map;
+
+/**
+ * @since 3.2
+ */
+public class SetDefaultProjectPermissions {
+  private final PersistentSettings persistentSettings;
+
+  public SetDefaultProjectPermissions(PersistentSettings persistentSettings) {
+    this.persistentSettings = persistentSettings;
+  }
+
+  public void start() {
+    if (persistentSettings.getSettings().getKeysStartingWith("sonar.role.").isEmpty()) {
+      LoggerFactory.getLogger(SetDefaultProjectPermissions.class).info("Setting default project permissions");
+      Map<String, String> props = Maps.newHashMap();
+      props.put("sonar.role.admin.TRK.defaultGroups", "sonar-administrators");
+      props.put("sonar.role.user.TRK.defaultGroups", "Anyone,sonar-users");
+      props.put("sonar.role.codeviewer.TRK.defaultGroups", "Anyone,sonar-users");
+
+      // Support old versions of Views plugin
+      props.put("sonar.role.admin.VW.defaultGroups", "sonar-administrators");
+      props.put("sonar.role.user.VW.defaultGroups", "Anyone,sonar-users");
+      props.put("sonar.role.codeviewer.VW.defaultGroups", "Anyone,sonar-users");
+      props.put("sonar.role.admin.SVW.defaultGroups", "sonar-administrators");
+      props.put("sonar.role.user.SVW.defaultGroups", "Anyone,sonar-users");
+      props.put("sonar.role.codeviewer.SVW.defaultGroups", "Anyone,sonar-users");
+
+      persistentSettings.saveProperties(props);
+    }
+  }
+}
index a5eb9095852a515b562448dabe1d4576f3f0e2eb..cad1ff6d9a7bd1f560d3c3b999f32339d88b439d 100644 (file)
@@ -57,10 +57,7 @@ import org.sonar.server.filters.Filter;
 import org.sonar.server.filters.FilterExecutor;
 import org.sonar.server.filters.FilterResult;
 import org.sonar.server.notifications.reviews.ReviewsNotificationManager;
-import org.sonar.server.platform.GlobalSettingsUpdater;
-import org.sonar.server.platform.NewUserNotifier;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.ServerIdGenerator;
+import org.sonar.server.platform.*;
 import org.sonar.server.plugins.*;
 import org.sonar.server.rules.ProfilesConsole;
 import org.sonar.server.rules.RulesConsole;
@@ -335,7 +332,7 @@ public final class JRubyFacade {
   }
 
   public void setGlobalProperty(String key, @Nullable String value) {
-    get(GlobalSettingsUpdater.class).setProperty(key, value);
+    get(ServerSettings.class).setProperty(key, value);
   }
 
   public Settings getSettings() {
index 75ee2d5165848797538632b5ab50771a1866eff8..8635e4d3890347419b4ff0265025732cde9b07ed 100644 (file)
@@ -31,6 +31,7 @@ class MoveDefaultRoles < ActiveRecord::Migration
 
   class User < ActiveRecord::Base
   end
+
   class UserRole < ActiveRecord::Base
   end
 
@@ -49,28 +50,11 @@ class MoveDefaultRoles < ActiveRecord::Migration
       # upgrade from version < 3.2.
       move_groups
       move_users
-    else
-      create_default_groups('admin', 'TRK', 'sonar-administrators')
-      create_default_groups('user', 'TRK', 'Anyone,sonar-users')
-      create_default_groups('codeviewer', 'TRK', 'Anyone,sonar-users')
-
-      # Support old versions of Views plugin
-      create_default_groups('admin', 'VW', 'sonar-administrators')
-      create_default_groups('user', 'VW', 'Anyone,sonar-users')
-      create_default_groups('codeviewer', 'VW', 'Anyone,sonar-users')
-      create_default_groups('admin', 'SVW', 'sonar-administrators')
-      create_default_groups('user', 'SVW', 'Anyone,sonar-users')
-      create_default_groups('codeviewer', 'SVW', 'Anyone,sonar-users')
     end
   end
 
   private
 
-  def self.create_default_groups(role, qualifier, groups)
-    Property.create(:prop_key => "sonar.role.#{role}.#{qualifier}.defaultGroups", :text_value => groups)
-    Property.create(:prop_key => "sonar.role.#{role}.#{qualifier}.defaultUsers", :text_value => '')
-  end
-
   def self.move_groups
     groups_per_role={}
     group_roles = GroupRole.find(:all, :conditions => ['resource_id is null and role like ?', 'default-%'])
index 5cd0cb6b63df21930bcd760ca1999e779883d34a..a762d9bcc14935fbdef4b6aef8367bddbff7cfa5 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleParam;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
+import org.sonar.server.platform.PersistentSettings;
 import org.sonar.test.TestUtils;
 
 import java.io.IOException;
@@ -44,6 +45,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
 
 public class ProfilesBackupTest extends AbstractDbUnitTestCase {
 
@@ -157,7 +159,7 @@ public class ProfilesBackupTest extends AbstractDbUnitTestCase {
    */
   @Test
   public void shouldSupportMissingEnabledField() throws IOException {
-    Backup backup = new Backup(getSession());
+    Backup backup = new Backup(getSession(), mock(PersistentSettings.class));
     backup.doImportXml(FileUtils.readFileToString(TestUtils.getResource(getClass(), "shouldSupportMissingEnabledField.xml")));
 
     RulesProfile profile = getSession().getSingleResult(RulesProfile.class, "name", "Missing enabled field");
@@ -166,7 +168,7 @@ public class ProfilesBackupTest extends AbstractDbUnitTestCase {
 
   @Test
   public void shouldSupportEnabledField() throws IOException {
-    Backup backup = new Backup(getSession());
+    Backup backup = new Backup(getSession(), mock(PersistentSettings.class));
     backup.doImportXml(FileUtils.readFileToString(TestUtils.getResource(getClass(), "shouldSupportEnabledField.xml")));
 
     RulesProfile enabledProfile = getSession().getSingleResult(RulesProfile.class, "name", "Enabled");
index 078a39dc41a91822feef9bd3ad8220fbcf3f2587..5e91f5fe5b7db2faa5cd42bf66f3bf35e953d9bd 100644 (file)
  */
 package org.sonar.server.configuration;
 
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.CharEncoding;
+import com.google.common.collect.ImmutableMap;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.CoreProperties;
 import org.sonar.api.database.configuration.Property;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
-import org.sonar.test.TestUtils;
+import org.sonar.server.platform.PersistentSettings;
 
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Map;
 
-import static org.hamcrest.Matchers.endsWith;
-import static org.hamcrest.Matchers.startsWith;
-import static org.hamcrest.collection.IsCollectionContaining.hasItem;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
 
 public class PropertiesBackupTest extends AbstractDbUnitTestCase {
 
-  private SonarConfig sonarConfig;
+  private PersistentSettings persistentSettings;
+  private PropertiesBackup backup;
 
   @Before
   public void setup() {
-    sonarConfig = new SonarConfig();
+    persistentSettings = mock(PersistentSettings.class);
+    backup = new PropertiesBackup(persistentSettings);
   }
 
   @Test
-  public void shouldExportProperties() {
-    setupData("shouldExportProperties");
+  public void export_properties() {
+    when(persistentSettings.getProperties()).thenReturn(ImmutableMap.of("key1", "value1", "key2", "value2"));
 
-    new PropertiesBackup(getSession()).exportXml(sonarConfig);
+    SonarConfig config = new SonarConfig();
+    backup.exportXml(config);
 
-    Property prop1 = new Property("key1", "value1");
-    Property prop2 = new Property("key2", "value2");
-    Property prop3 = new Property("sonar.core.version", "3.1");
-
-    assertTrue(CollectionUtils.isEqualCollection(sonarConfig.getProperties(), Arrays.asList(prop1, prop2, prop3)));
+    assertThat(config.getProperties()).containsOnly(new Property("key1", "value1"), new Property("key2", "value2"));
   }
 
   @Test
-  public void shouldNotExportPropertiesLinkedToResources() {
-    setupData("shouldNotExportPropertiesLinkedToResources");
-
-    new PropertiesBackup(getSession()).exportXml(sonarConfig);
+  public void do_not_export_server_id() {
+    when(persistentSettings.getProperties()).thenReturn(ImmutableMap.of(CoreProperties.SERVER_ID, "111"));
 
-    Property prop1 = new Property("key1", "value1");
-    Property prop2 = new Property("key2", "value2");
+    SonarConfig config = new SonarConfig();
+    backup.exportXml(config);
 
-    assertTrue(CollectionUtils.isEqualCollection(sonarConfig.getProperties(), Arrays.asList(prop1, prop2)));
+    assertThat(config.getProperties()).isEmpty();
   }
 
-  @Test
-  public void shouldExportAnArrayProperty() {
-    setupData("shouldExportAnArrayProperty");
-
-    new PropertiesBackup(getSession()).exportXml(sonarConfig);
-
-    assertThat(sonarConfig.getProperties(), hasItem(new Property("key1", "value1,value2,value3")));
-  }
-
-  @Test
-  public void shouldImportProperties() {
-    setupData("shouldImportProperties");
-
-    Collection<Property> newProperties = Arrays.asList(new Property("key1", "value1"), new Property("key2", "value2"), new Property("key3", "value3"));
-    sonarConfig.setProperties(newProperties);
-
-    new PropertiesBackup(getSession()).importXml(sonarConfig);
-
-    checkTables("shouldImportProperties", "properties");
-  }
 
   @Test
-  public void shouldNotImportSonarCoreIdProperty() {
-    setupData("shouldNotImportSonarCoreIdProperty");
-
-    Collection<Property> newProperties = Arrays.asList(new Property("sonar.core.id", "11111111"));
-    sonarConfig.setProperties(newProperties);
-
-    new PropertiesBackup(getSession()).importXml(sonarConfig);
-
-    checkTables("shouldNotImportSonarCoreIdProperty", "properties");
+  public void import_backup_of_properties() {
+    Collection<Property> newProperties = Arrays.asList(new Property("key1", "value1"), new Property("key2", "value2"));
+    SonarConfig config = new SonarConfig();
+    config.setProperties(newProperties);
+
+    backup.importXml(config);
+
+    verify(persistentSettings).saveProperties(argThat(new BaseMatcher<Map<String, String>>() {
+      public boolean matches(Object o) {
+        Map<String, String> map = (Map<String, String>) o;
+        return map.get("key1").equals("value1") && map.get("key2").equals("value2");
+      }
+
+      public void describeTo(Description description) {
+      }
+    }));
   }
 
   @Test
-  public void shouldImportMultilineProperties() throws Exception {
-    setupData("shouldImportMultilineProperties");
-
-    new Backup(getSession()).doImportXml(
-        FileUtils.readFileToString(
-            TestUtils.getResource(getClass(), "backup-with-multiline-property.xml"), CharEncoding.UTF_8));
-
-    Property property = getSession().getSingleResult(Property.class, "key", "sonar.multiline.secured");
-    assertThat(property.getValue(), startsWith("ONQwdcwcwwdadalkdmaiQGMqMVnhtAbhxwjjoVkHbWgx"));
-    assertThat(property.getValue(), endsWith("mmmm"));
-
+  public void do_not_import_server_id() {
+    // initial server id
+    when(persistentSettings.getString(CoreProperties.SERVER_ID)).thenReturn("111");
+
+    Collection<Property> newProperties = Arrays.asList(new Property(CoreProperties.SERVER_ID, "999"));
+    SonarConfig config = new SonarConfig();
+    config.setProperties(newProperties);
+    backup.importXml(config);
+
+    verify(persistentSettings).saveProperties(argThat(new BaseMatcher<Map<String, String>>() {
+      public boolean matches(Object o) {
+        Map<String, String> map = (Map<String, String>) o;
+        return map.get(CoreProperties.SERVER_ID).equals("111");
+      }
+
+      public void describeTo(Description description) {
+      }
+    }));
   }
 }
index 9d79811cb5361fb47ec3d78e0a64dcf2a28d7fe0..2ffff06b75dcf20095e91207cf7e3812632469a7 100644 (file)
  */
 package org.sonar.server.platform;
 
+import com.google.common.collect.ImmutableMap;
 import org.apache.commons.configuration.BaseConfiguration;
 import org.junit.Test;
+import org.sonar.api.config.GlobalPropertyChangeHandler;
 import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.core.persistence.AbstractDaoTestCase;
-import org.sonar.core.properties.PropertiesDao;
 
 import java.io.File;
 import java.net.URISyntaxException;
+import java.util.Map;
 
-import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
 
-public class ServerSettingsTest extends AbstractDaoTestCase {
+public class ServerSettingsTest {
 
   private static File home = getHome();
 
   @Test
   public void shouldLoadPropertiesFile() {
-    ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home);
+    ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home, new GlobalPropertyChangeHandler[0]);
 
-    assertThat(settings.getString("hello"), is("world"));
+    assertThat(settings.getString("hello")).isEqualTo("world");
   }
 
   @Test
   public void systemPropertiesShouldOverridePropertiesFile() {
     System.setProperty("ServerSettingsTestEnv", "in_env");
-    ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home);
+    ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home, new GlobalPropertyChangeHandler[0]);
 
-    assertThat(settings.getString("ServerSettingsTestEnv"), is("in_env"));
+    assertThat(settings.getString("ServerSettingsTestEnv")).isEqualTo("in_env");
   }
 
   @Test(expected = IllegalStateException.class)
   public void shouldFailIfPropertiesFileNotFound() {
     File sonarHome = new File("unknown/path");
-    new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), sonarHome);
+    new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), sonarHome, new GlobalPropertyChangeHandler[0]);
   }
 
   @Test
-  public void shouldActivateDatabaseSettings() {
-    setupData("db/shared");
+  public void activateDatabaseSettings() {
+    ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home, new GlobalPropertyChangeHandler[0]);
 
-    ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home);
-    settings.activateDatabaseSettings(new PropertiesDao(getMyBatis()), home);
+    Map<String, String> databaseProperties = ImmutableMap.of("in_db", "true");
+    settings.activateDatabaseSettings(home, databaseProperties);
 
-    assertThat(settings.getString("global_only"), is("is_global"));
-    assertThat(settings.getString("global_and_project"), is("is_global"));
-    assertThat(settings.getString("project_only"), nullValue());
+    assertThat(settings.getString("in_db")).isEqualTo("true");
+  }
+
+  @Test
+  public void file_settings_override_db_settings() {
+    ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home, new GlobalPropertyChangeHandler[0]);
+    assertThat(settings.getString("in_file")).isEqualTo("true");
+
+    Map<String, String> databaseProperties = ImmutableMap.of("in_file", "false");
+    settings.activateDatabaseSettings(home, databaseProperties);
+
+    assertThat(settings.getString("in_file")).isEqualTo("true");
   }
 
   private static File getHome() {
index 7fe0f5fbf7b93172563cbd4c64c81aeaac5b09aa..ba00c5c61cd32fbbfff44c28fd2abeb832939997 100644 (file)
  */
 package org.sonar.server.startup;
 
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.CoreProperties;
 import org.sonar.api.platform.Server;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
+import org.sonar.server.platform.PersistentSettings;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.Map;
 import java.util.TimeZone;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
 
-public class ServerMetadataPersisterTest extends AbstractDbUnitTestCase {
+public class ServerMetadataPersisterTest {
 
   private TimeZone initialTimeZone;
+  private PersistentSettings persistentSettings;
 
   @Before
   public void fixTimeZone() {
     initialTimeZone = TimeZone.getDefault();
     TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+    persistentSettings = mock(PersistentSettings.class);
   }
 
   @After
@@ -50,41 +56,28 @@ public class ServerMetadataPersisterTest extends AbstractDbUnitTestCase {
 
   @Test
   public void testSaveProperties() throws ParseException {
-    setupData("testSaveProperties");
-    persist(newServer());
-    checkTables("testSaveProperties", "properties");
-  }
-
-  @Test
-  public void testUpdateExistingProperties() throws ParseException {
-    setupData("testUpdateExistingProperties");
-    persist(newServer());
-    checkTables("testUpdateExistingProperties", "properties");
-  }
-
-  @Test
-  public void testDeleteProperties() throws ParseException {
-    setupData("testDeleteProperties");
-    Server server = mock(Server.class);
-    when(server.getStartedAt()).thenReturn(new SimpleDateFormat("yyyy-MM-dd HH:mm").parse("2010-05-18 17:59"));//this is a mandatory not-null property
-    persist(server);
-    checkTables("testDeleteProperties", "properties");
-  }
-
-  private void persist(Server server) {
-    ServerMetadataPersister persister = new ServerMetadataPersister(server, getSession());
-    persister.start();
-  }
-
-  private Server newServer() throws ParseException {
     Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse("2010-05-18 17:59");
     Server server = mock(Server.class);
     when(server.getPermanentServerId()).thenReturn("1abcdef");
     when(server.getId()).thenReturn("123");
-    when(server.getVersion()).thenReturn("2.2");
+    when(server.getVersion()).thenReturn("3.2");
     when(server.getStartedAt()).thenReturn(date);
+    ServerMetadataPersister persister = new ServerMetadataPersister(server, persistentSettings);
+    persister.start();
 
-    return server;
+    verify(persistentSettings).saveProperties(argThat(new BaseMatcher<Map<String, String>>() {
+      public boolean matches(Object o) {
+        Map<String, String> map = (Map<String, String>) o;
+        return map.get(CoreProperties.SERVER_ID).equals("123")
+          && map.get(CoreProperties.SERVER_VERSION).equals("3.2")
+          && map.get(CoreProperties.SERVER_STARTTIME).equals("2010-05-18T17:59:00+0000")
+          && map.size() == 3;
+      }
 
+      public void describeTo(Description description) {
+      }
+    }));
   }
+
+
 }
diff --git a/sonar-server/src/test/java/org/sonar/server/startup/SetDefaultProjectPermissionsTest.java b/sonar-server/src/test/java/org/sonar/server/startup/SetDefaultProjectPermissionsTest.java
new file mode 100644 (file)
index 0000000..0f7ef23
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.startup;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.server.platform.PersistentSettings;
+
+import java.util.Map;
+
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
+
+public class SetDefaultProjectPermissionsTest {
+  @Test
+  public void set_default_permissions_if_none() {
+    PersistentSettings persistentSettings = mock(PersistentSettings.class);
+    Settings settings = new Settings();
+    when(persistentSettings.getSettings()).thenReturn(settings);
+
+    new SetDefaultProjectPermissions(persistentSettings).start();
+
+    verify(persistentSettings).saveProperties(argThat(new BaseMatcher<Map<String, String>>() {
+      public boolean matches(Object o) {
+        Map<String, String> map = (Map<String, String>) o;
+        return map.size() == 9 && map.get("sonar.role.admin.TRK.defaultGroups").equals("sonar-administrators");
+      }
+
+      public void describeTo(Description description) {
+      }
+    }));
+  }
+
+  @Test
+  public void do_not_set_default_permissions_if_exist() {
+    PersistentSettings persistentSettings = mock(PersistentSettings.class);
+    Settings settings = new Settings().setProperty("sonar.role.admin.TRK.defaultGroups", "custom-group");
+    when(persistentSettings.getSettings()).thenReturn(settings);
+
+    new SetDefaultProjectPermissions(persistentSettings).start();
+
+    verify(persistentSettings, never()).saveProperties(any(Map.class));
+  }
+}
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/db/shared.xml b/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/db/shared.xml
deleted file mode 100644 (file)
index 55b972c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<dataset>
-
-  <!-- project -->
-  <projects long_name="[null]" id="3333" scope="PRJ" qualifier="TRK" kee="mygroup:anotherproject" name="[null]"
-            root_id="[null]"
-            description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>
-
-  <!-- global properties -->
-  <properties prop_key="global_only" resource_id="[null]" user_id="[null]" text_value="is_global"/>
-  <properties prop_key="global_and_project" resource_id="[null]" user_id="[null]" text_value="is_global"/>
-
-  <!-- project properties: do not load  -->
-  <properties prop_key="global_and_project" resource_id="3333" user_id="[null]" text_value="is_project"/>
-  <properties prop_key="project_only" resource_id="3333" user_id="[null]" text_value="is_project"/>
-
-  <!-- user properties : do not load -->
-  <properties prop_key="user" resource_id="[null]" user_id="110" text_value="is_user"/>
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testDeleteProperties-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testDeleteProperties-result.xml
deleted file mode 100644 (file)
index f7ada56..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<dataset>
-
-  <properties id="1" prop_key="other" resource_id="[null]" text_value="some text" user_id="[null]"/>
-
-  <!-- not null property -->
-  <properties id="4" prop_key="sonar.core.startTime" resource_id="[null]" text_value="2010-05-18T17:59:00+0000" user_id="[null]"/>
-</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testDeleteProperties.xml b/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testDeleteProperties.xml
deleted file mode 100644 (file)
index ec292a1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<dataset>
-
-  <properties id="1" prop_key="other" resource_id="[null]" text_value="some text" user_id="[null]" />
-
-  <properties id="2" prop_key="sonar.core.id" resource_id="[null]" text_value="123" user_id="[null]"/>
-  <properties id="3" prop_key="sonar.core.version" resource_id="[null]" text_value="2.2" user_id="[null]"/>
-  <properties id="4" prop_key="sonar.core.startTime" resource_id="[null]" text_value="2010-05-18T17:59:00+0000" user_id="[null]"/>
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testSaveProperties-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testSaveProperties-result.xml
deleted file mode 100644 (file)
index ec292a1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<dataset>
-
-  <properties id="1" prop_key="other" resource_id="[null]" text_value="some text" user_id="[null]" />
-
-  <properties id="2" prop_key="sonar.core.id" resource_id="[null]" text_value="123" user_id="[null]"/>
-  <properties id="3" prop_key="sonar.core.version" resource_id="[null]" text_value="2.2" user_id="[null]"/>
-  <properties id="4" prop_key="sonar.core.startTime" resource_id="[null]" text_value="2010-05-18T17:59:00+0000" user_id="[null]"/>
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testSaveProperties.xml b/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testSaveProperties.xml
deleted file mode 100644 (file)
index a9e2365..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<dataset>
-
-  <properties id="1" prop_key="other" resource_id="[null]" text_value="some text" user_id="[null]"/>
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testUpdateExistingProperties-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testUpdateExistingProperties-result.xml
deleted file mode 100644 (file)
index 365acc0..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<dataset>
-
-  <properties id="1" prop_key="other" resource_id="[null]" text_value="some text" user_id="[null]"/>
-
-  <properties id="2" prop_key="sonar.core.id" resource_id="[null]" text_value="123" user_id="[null]"/>
-  <properties id="3" prop_key="sonar.core.version" resource_id="[null]" text_value="2.2" user_id="[null]"/>
-  <properties id="4" prop_key="sonar.core.startTime" resource_id="[null]" text_value="2010-05-18T17:59:00+0000" user_id="[null]"/>
-
-</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testUpdateExistingProperties.xml b/sonar-server/src/test/resources/org/sonar/server/startup/ServerMetadataPersisterTest/testUpdateExistingProperties.xml
deleted file mode 100644 (file)
index 824615a..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<dataset>
-
-  <properties id="1" prop_key="other" resource_id="[null]" text_value="some text" user_id="[null]"/>
-
-  <properties id="2" prop_key="sonar.core.id" resource_id="[null]" text_value="65" user_id="[null]"/>
-  <properties id="3" prop_key="sonar.core.version" resource_id="[null]" text_value="1.9" user_id="[null]"/>
-  <properties id="4" prop_key="sonar.core.startTime" resource_id="[null]" text_value="2008-04-18T17:59:00+0000" user_id="[null]"/>
-
-</dataset>
\ No newline at end of file