From: David Gageot Date: Tue, 25 Sep 2012 13:58:42 +0000 (+0200) Subject: SONAR-3529 prepare for json parsing of property sets X-Git-Tag: 3.3~209 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=dad576683bcc8aa250e4c018375e86c7dc6dbd61;p=sonarqube.git SONAR-3529 prepare for json parsing of property sets --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index f5338025e33..d1647af4994 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -63,7 +63,7 @@ import java.util.List; name = "Toto", global = true, type = PropertyType.PROPERTY_SET, - property_set_name = "myset", + propertySetName = "myset", category = CoreProperties.CATEGORY_GENERAL), @Property( key = CoreProperties.PROJECT_LANGUAGE_PROPERTY, diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/Property.java b/sonar-plugin-api/src/main/java/org/sonar/api/Property.java index 64037142ac2..ca2c7270699 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/Property.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/Property.java @@ -104,5 +104,5 @@ public @interface Property { * * @since 3.3 */ - String property_set_name() default ""; + String propertySetName() default ""; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java index 5464b2f3cdd..5c20b5c56e5 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java @@ -67,7 +67,7 @@ public final class PropertyDefinition { private boolean onModule = false; private boolean isGlobal = true; private boolean multiValues; - private String property_set_name; + private String propertySetName; private PropertyDefinition(Property annotation) { this.key = annotation.key(); @@ -81,7 +81,7 @@ public final class PropertyDefinition { this.type = fixType(annotation.key(), annotation.type()); this.options = annotation.options(); this.multiValues = annotation.multiValues(); - this.property_set_name = annotation.property_set_name(); + this.propertySetName = annotation.propertySetName(); } private static PropertyType fixType(String key, PropertyType type) { @@ -186,7 +186,7 @@ public final class PropertyDefinition { /** * @since 3.3 */ - public String getProperty_set_name() { - return property_set_name; + public String getPropertySetName() { + return propertySetName; } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertySetValue.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertySetValue.java index aadfa06a969..8df3ca267cb 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertySetValue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertySetValue.java @@ -19,8 +19,99 @@ */ package org.sonar.api.config; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import org.apache.commons.lang.ArrayUtils; +import org.sonar.api.utils.DateUtils; + +import java.util.Date; +import java.util.List; +import java.util.Map; + /** * @since 3.3 */ -public class PropertySetValue { +public final class PropertySetValue { + private final Map keyValues; + + private PropertySetValue(Map keyValues) { + this.keyValues = ImmutableMap.copyOf(keyValues); + } + + public static PropertySetValue create(Map keyValues) { + return new PropertySetValue(keyValues); + } + + /** + * @return the field as String. If the field does not exist, then an empty string is returned. + */ + public String getString(String fieldName) { + String value = keyValues.get(fieldName); + return (value == null) ? "" : value; + } + + /** + * @return the field as int. If the field does not exist, then 0 is returned. + */ + public int getInt(String fieldName) { + String value = keyValues.get(fieldName); + return (value == null) ? 0 : Integer.parseInt(value); + } + + /** + * @return the field as boolean. If the field does not exist, then false is returned. + */ + public boolean getBoolean(String fieldName) { + String value = keyValues.get(fieldName); + return (value == null) ? false : Boolean.parseBoolean(value); + } + + /** + * @return the field as float. If the field does not exist, then 0.0 is returned. + */ + public float getFloat(String fieldName) { + String value = keyValues.get(fieldName); + return (value == null) ? 0f : Float.parseFloat(value); + } + + /** + * @return the field as long. If the field does not exist, then 0L is returned. + */ + public long getLong(String fieldName) { + String value = keyValues.get(fieldName); + return (value == null) ? 0L : Long.parseLong(value); + } + + /** + * @return the field as Date. If the field does not exist, then null is returned. + */ + public Date getDate(String fieldName) { + String value = keyValues.get(fieldName); + return (value == null) ? null : DateUtils.parseDate(value); + } + + /** + * @return the field as Date with time. If the field does not exist, then null is returned. + */ + public Date getDateTime(String fieldName) { + String value = keyValues.get(fieldName); + return (value == null) ? null : DateUtils.parseDateTime(value); + } + + /** + * @return the field as an array of String. If the field does not exist, then an empty array is returned. + */ + public String[] getStringArray(String fieldName) { + String value = keyValues.get(fieldName); + if (value == null) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + + List values = Lists.newArrayList(); + for (String v : Splitter.on(",").trimResults().split(value)) { + values.add(v.replace("%2C", ",")); + } + return values.toArray(new String[values.size()]); + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java index d9b55af1109..0735c91073b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java @@ -19,6 +19,8 @@ */ package org.sonar.api.config; +import com.google.common.collect.Iterables; + import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.base.Strings; @@ -33,6 +35,8 @@ import org.sonar.api.utils.DateUtils; import javax.annotation.Nullable; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Project Settings on batch side, Global Settings on server side. This component does not access to database, so @@ -186,14 +190,17 @@ public class Settings implements BatchComponent, ServerComponent { throw new IllegalArgumentException("Property " + key + " is not of type PROPERTY_SET"); } - String propertySetValueName = getString(key); - - // read json for given key - // search value for given propertySetValueName + String propertySetName = property.getPropertySetName(); + String valueName = getString(key); + String propertySetJson = getString("sonar.property_set." + propertySetName); - return null; + return PropertySetValue.create(lowTechJsonParsing(valueName, propertySetJson)); } + private static Map lowTechJsonParsing(String valueName, String json) { + return Maps.newHashMap(); + } + /** * Value is split by carriage returns. * diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java index 061bb99a575..59d3927aa33 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java @@ -47,7 +47,7 @@ public class PropertyDefinitionTest { assertThat(def.isOnProject()).isTrue(); assertThat(def.isOnModule()).isTrue(); assertThat(def.isMultiValues()).isTrue(); - assertThat(def.getProperty_set_name()).isEmpty(); + assertThat(def.getPropertySetName()).isEmpty(); } @Properties(@Property(key = "hello", name = "Hello", defaultValue = "world", description = "desc", @@ -75,7 +75,7 @@ public class PropertyDefinitionTest { assertThat(def.isMultiValues()).isFalse(); } - @Properties(@Property(key = "hello", name = "Hello", type = PropertyType.PROPERTY_SET, property_set_name = "set1")) + @Properties(@Property(key = "hello", name = "Hello", type = PropertyType.PROPERTY_SET, propertySetName = "set1")) static class WithPropertySet { } @@ -87,7 +87,7 @@ public class PropertyDefinitionTest { PropertyDefinition def = PropertyDefinition.create(prop); assertThat(def.getType()).isEqualTo(PropertyType.PROPERTY_SET); - assertThat(def.getProperty_set_name()).isEqualTo("set1"); + assertThat(def.getPropertySetName()).isEqualTo("set1"); } @Properties(@Property(key = "hello", name = "Hello")) diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertySetValueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertySetValueTest.java new file mode 100644 index 00000000000..b59ac26fbe5 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertySetValueTest.java @@ -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.api.config; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class PropertySetValueTest { + @Test + public void should_get_default_values() { + PropertySetValue value = PropertySetValue.create(Maps.newHashMap()); + + assertThat(value.getString("UNKNOWN")).isEmpty(); + assertThat(value.getInt("UNKNOWN")).isZero(); + assertThat(value.getFloat("UNKNOWN")).isZero(); + assertThat(value.getLong("UNKNOWN")).isZero(); + assertThat(value.getDate("UNKNOWN")).isNull(); + assertThat(value.getDateTime("UNKNOWN")).isNull(); + assertThat(value.getStringArray("UNKNOWN")).isEmpty(); + } + + @Test + public void should_get_values() { + PropertySetValue value = PropertySetValue.create(ImmutableMap.builder() + .put("age", "12") + .put("child", "true") + .put("size", "12.4") + .put("distance", "1000000000") + .put("array", "1,2,3,4,5") + .put("birth", "1975-01-29") + .put("now", "2012-09-25T10:08:30+0100") + .build()); + + assertThat(value.getString("age")).isEqualTo("12"); + assertThat(value.getInt("age")).isEqualTo(12); + assertThat(value.getBoolean("child")).isTrue(); + assertThat(value.getFloat("size")).isEqualTo(12.4f); + assertThat(value.getLong("distance")).isEqualTo(1000000000L); + assertThat(value.getStringArray("array")).contains("1", "2", "3", "4", "5"); + assertThat(value.getDate("birth")).isNotNull(); + assertThat(value.getDateTime("now")).isNotNull(); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java index cef3a3fbdfb..137e76a8b4f 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java @@ -19,6 +19,8 @@ */ package org.sonar.api.config; +import org.junit.Ignore; + import com.google.common.collect.ImmutableMap; import org.junit.Before; import org.junit.Rule; @@ -26,6 +28,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.Properties; import org.sonar.api.Property; +import org.sonar.api.PropertyType; import static org.fest.assertions.Assertions.assertThat; @@ -41,7 +44,8 @@ public class SettingsTest { @Property(key = "falseboolean", name = "False Boolean", defaultValue = "false"), @Property(key = "integer", name = "Integer", defaultValue = "12345"), @Property(key = "array", name = "Array", defaultValue = "one,two,three"), - @Property(key = "multi_values", name = "Array", defaultValue = "1,2,3", multiValues = true) + @Property(key = "multi_values", name = "Array", defaultValue = "1,2,3", multiValues = true), + @Property(key = "sonar.jira", name = "Jira Server", type = PropertyType.PROPERTY_SET, propertySetName = "jira") }) static class Init { } @@ -157,47 +161,47 @@ public class SettingsTest { @Test public void setStringArray() { Settings settings = new Settings(definitions); - settings.setProperty("multi_values", new String[] {"A", "B"}); + settings.setProperty("multi_values", new String[]{"A", "B"}); String[] array = settings.getStringArray("multi_values"); - assertThat(array).isEqualTo(new String[] {"A", "B"}); + assertThat(array).isEqualTo(new String[]{"A", "B"}); } @Test public void setStringArrayTrimValues() { Settings settings = new Settings(definitions); - settings.setProperty("multi_values", new String[] {" A ", " B "}); + settings.setProperty("multi_values", new String[]{" A ", " B "}); String[] array = settings.getStringArray("multi_values"); - assertThat(array).isEqualTo(new String[] {"A", "B"}); + assertThat(array).isEqualTo(new String[]{"A", "B"}); } @Test public void setStringArrayEscapeCommas() { Settings settings = new Settings(definitions); - settings.setProperty("multi_values", new String[] {"A,B", "C,D"}); + settings.setProperty("multi_values", new String[]{"A,B", "C,D"}); String[] array = settings.getStringArray("multi_values"); - assertThat(array).isEqualTo(new String[] {"A,B", "C,D"}); + assertThat(array).isEqualTo(new String[]{"A,B", "C,D"}); } @Test public void setStringArrayWithEmptyValues() { Settings settings = new Settings(definitions); - settings.setProperty("multi_values", new String[] {"A,B", "", "C,D"}); + settings.setProperty("multi_values", new String[]{"A,B", "", "C,D"}); String[] array = settings.getStringArray("multi_values"); - assertThat(array).isEqualTo(new String[] {"A,B", "", "C,D"}); + assertThat(array).isEqualTo(new String[]{"A,B", "", "C,D"}); } @Test public void setStringArrayWithNullValues() { Settings settings = new Settings(definitions); - settings.setProperty("multi_values", new String[] {"A,B", null, "C,D"}); + settings.setProperty("multi_values", new String[]{"A,B", null, "C,D"}); String[] array = settings.getStringArray("multi_values"); - assertThat(array).isEqualTo(new String[] {"A,B", "", "C,D"}); + assertThat(array).isEqualTo(new String[]{"A,B", "", "C,D"}); } @Test(expected = IllegalStateException.class) public void shouldFailToSetArrayValueOnSingleValueProperty() { Settings settings = new Settings(definitions); - settings.setProperty("array", new String[] {"A", "B", "C"}); + settings.setProperty("array", new String[]{"A", "B", "C"}); } @Test @@ -319,4 +323,19 @@ public class SettingsTest { assertThat(settings.getKeysStartingWith("sonar.jdbc")).containsOnly("sonar.jdbc.url", "sonar.jdbc.username"); assertThat(settings.getKeysStartingWith("other")).hasSize(0); } + + @Test + @Ignore + public void should_get_property_set_value() { + Settings settings = new Settings(definitions); + settings.setProperty("sonar.property_set.jira", + "[{\"set\": {\"name\": \"codehaus_jira\", \"values\": {\"key1\":\"value1\", \"key2\":\"value2\"}}},{\"set\": {\"name\": \"other\", \"values\": {\"key3\":\"value3\"}}}]"); + + settings.setProperty("sonar.jira", "codehaus_jira"); + assertThat(settings.getPropertySetValue("sonar.jira").getString("key1")).isEqualTo("value1"); + assertThat(settings.getPropertySetValue("sonar.jira").getString("key2")).isEqualTo("value2"); + + settings.setProperty("sonar.jira", "other"); + assertThat(settings.getPropertySetValue("sonar.jira").getString("key3")).isEqualTo("value3"); + } } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/property_sets_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/property_sets_controller.rb index 185a439e758..7d53ee47b7e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/property_sets_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/property_sets_controller.rb @@ -24,6 +24,7 @@ class PropertySetsController < ApplicationController def index @property_sets = java_facade.listPropertySets() + render :partial => 'property_sets/list' end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/settings_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/settings_helper.rb index d64fd1d3744..4ff3b687e35 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/settings_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/settings_helper.rb @@ -51,14 +51,15 @@ module SettingsHelper end def by_name(categories) - categories.sort_by { |category| category_name(category) } + Api::Utils.insensitive_sort(categories) { |category| category_name(category) } end def input_name(property) h(property.key) + (property.multi_values ? '[]' : '') end - def property_set_values(property) - PropertySet.findAll(property.property_set_name); + def property_set_value_names(property) + names = PropertySet.findAll(property.propertySetName).map(&:name); + Api::Utils.insensitive_sort(names) end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb index 1f9841e809e..c6a3dda5149 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb @@ -24,5 +24,4 @@ module WidgetPropertiesHelper property_value definition.key(), definition.type.name(), value.nil? ? definition.defaultValue() : value end - end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb index f9e0e4e9fbf..976fdf7480a 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/property.rb @@ -23,6 +23,7 @@ class Property < ActiveRecord::Base named_scope :with_key, lambda { |value| {:conditions => {:prop_key, value}} } named_scope :with_resource, lambda { |value| {:conditions => {:resource_id => value}} } named_scope :with_user, lambda { |value| {:conditions => {:user_id => value}} } + named_scope :on_resource, :conditions => ['resource_id is not ?', nil] def key prop_key diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/property_set.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/property_set.rb index b7e20fe1a1e..1defe5dece2 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/property_set.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/property_set.rb @@ -42,6 +42,6 @@ class PropertySet < ActiveRecord::Base json = Property.value('sonar.property_set.' + set_name) #json || '[]' - json || '[{"name":"set1"},{"name":"set2"}]' + json || '[{"name":"set2"},{"name":"set1"}]' end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/property_sets/_list.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/property_sets/_list.html.erb new file mode 100644 index 00000000000..a09bcb19b20 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/property_sets/_list.html.erb @@ -0,0 +1,22 @@ +
+
+
+
+ +
+ <% @property_sets.each do |property_set| -%> + <% property_set.fields.each do |field| -%> + <%= field.name %> (<%= field.type %>)
+ <% end -%> + <% end -%> +
+ + +
+
+ + diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/property_sets/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/property_sets/index.html.erb deleted file mode 100644 index 37f9e572498..00000000000 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/property_sets/index.html.erb +++ /dev/null @@ -1,6 +0,0 @@ -<% @property_sets.each do |property_set| -%> - <% property_set.fields.each do |field| -%> - <%= field.name %> - <%= field.type %> - <% end -%> -<% end -%> \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_multi_value.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_multi_value.html.erb index 3bc94037b05..b98f736a8d0 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_multi_value.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_multi_value.html.erb @@ -1,5 +1,7 @@
<%= render "settings/type_#{property_type(property, value)}", :property => property, :value => value -%> - <%= message('delete') -%> + <% if delete_link -%> + <%= message('delete') -%> + <% end -%>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_properties.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_properties.html.erb index f671a1ff32e..458b02c27c2 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_properties.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_properties.html.erb @@ -28,11 +28,11 @@ <% value = property_value(property) -%> <% if property.multi_values -%> - <% value.each do |sub_value| -%> - <%= render "settings/multi_value", :property => property, :value => sub_value -%> + <% value.each_with_index do |sub_value, index| -%> + <%= render "settings/multi_value", :property => property, :value => sub_value, :delete_link => true -%> <% end -%>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_settings.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_settings.html.erb index b4a829782ef..347811ce841 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_settings.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_settings.html.erb @@ -1,5 +1,5 @@
-

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

+

<%= message(@resource ? 'project_settings.page' : 'settings.page' ) -%>

diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_type_PROPERTY_SET.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_type_PROPERTY_SET.html.erb index 613c806d581..aa9a1bbb2a0 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_type_PROPERTY_SET.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_type_PROPERTY_SET.html.erb @@ -1,7 +1,7 @@ +Edit property set...