From: Simon Brandhof Date: Wed, 7 Nov 2012 16:30:33 +0000 (+0100) Subject: SONAR-3940 property relocation X-Git-Tag: 3.4~357 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=95718a509257f37bbb498f36185adceb65537068;p=sonarqube.git SONAR-3940 property relocation --- 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 b0179ceedf3..4802b6fe251 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 @@ -121,4 +121,10 @@ public @interface Property { * @since 3.3 */ PropertyField[] fields() default {}; + + /** + * Relocation of key. + * @since 3.4 + */ + String deprecatedKey() 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 c829cd4ac17..083b598d4da 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 @@ -71,6 +71,7 @@ public final class PropertyDefinition { private final boolean isGlobal; private final boolean multiValues; private final String propertySetKey; + private final String deprecatedKey; private final List fields; private PropertyDefinition(Property annotation) { @@ -87,6 +88,7 @@ public final class PropertyDefinition { this.multiValues = annotation.multiValues(); this.propertySetKey = annotation.propertySetKey(); this.fields = ImmutableList.copyOf(PropertyFieldDefinition.create(annotation.fields())); + this.deprecatedKey = annotation.deprecatedKey(); } private PropertyDefinition(String key, PropertyType type, String[] options) { @@ -103,6 +105,7 @@ public final class PropertyDefinition { this.multiValues = false; this.propertySetKey = null; this.fields = null; + this.deprecatedKey = null; } private static PropertyType fixType(String key, PropertyType type) { @@ -215,4 +218,11 @@ public final class PropertyDefinition { public List getFields() { return fields; } + + /** + * @since 3.4 + */ + public String getDeprecatedKey() { + return deprecatedKey; + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java index dfd1dfe5b55..8aae3ed9289 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java @@ -19,6 +19,7 @@ */ package org.sonar.api.config; +import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; @@ -43,6 +44,9 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen private final Map definitions = Maps.newHashMap(); private final Map categories = Maps.newHashMap(); + // deprecated key -> new key + private final Map deprecatedKeys = Maps.newHashMap(); + public PropertyDefinitions(Object... components) { if (components != null) { addComponents(Arrays.asList(components)); @@ -87,6 +91,10 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen if (!definitions.containsKey(definition.getKey())) { definitions.put(definition.getKey(), definition); categories.put(definition.getKey(), StringUtils.defaultIfBlank(definition.getCategory(), defaultCategory)); + if (!Strings.isNullOrEmpty(definition.getDeprecatedKey()) && !definition.getDeprecatedKey().equals(definition.getKey())) { + deprecatedKeys.put(definition.getDeprecatedKey(), definition.getKey()); + definitions.put(definition.getDeprecatedKey(), definition); + } } return this; } @@ -170,4 +178,16 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen public String getCategory(Property prop) { return getCategory(prop.key()); } + + public String getNewKey(String deprecatedKey) { + return deprecatedKeys.get(deprecatedKey); + } + + public String getDeprecatedKey(String key) { + PropertyDefinition def = get(key); + if (def == null) { + return null; + } + return StringUtils.defaultIfEmpty(def.getDeprecatedKey(), null); + } } 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 8043a7e9e35..a3a087b4175 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 @@ -92,10 +92,8 @@ public class Settings implements BatchComponent, ServerComponent { } public final String getString(String key) { - String value = properties.get(key); - if (value == null) { - value = getDefaultValue(key); - } else if (encryption.isEncrypted(value)) { + String value = getClearString(key); + if (value != null && encryption.isEncrypted(value)) { try { value = encryption.decrypt(value); } catch (Exception e) { @@ -264,10 +262,8 @@ public class Settings implements BatchComponent, ServerComponent { throw new IllegalStateException("Fail to set multiple values on a single value property " + key); } - if (values == null) { - properties.remove(key); - doOnRemoveProperty(key); - } else { + String text = null; + if (values != null) { List escaped = Lists.newArrayList(); for (String value : values) { if (null != value) { @@ -278,13 +274,16 @@ public class Settings implements BatchComponent, ServerComponent { } String escapedValue = Joiner.on(',').join(escaped); - properties.put(key, StringUtils.trim(escapedValue)); - doOnSetProperty(key, escapedValue); + text = StringUtils.trim(escapedValue); } - return this; + return setProperty(key, text); } public final Settings setProperty(String key, @Nullable String value) { + return setProperty(key, value, true); + } + + private Settings setProperty(String key, @Nullable String value, boolean recursive) { if (value == null) { properties.remove(key); doOnRemoveProperty(key); @@ -292,6 +291,17 @@ public class Settings implements BatchComponent, ServerComponent { properties.put(key, StringUtils.trim(value)); doOnSetProperty(key, value); } + if (recursive) { + String newKey = definitions.getNewKey(key); + if (newKey != null) { + setProperty(newKey, value, false); + } else { + String deprecatedKey = definitions.getDeprecatedKey(key); + if (deprecatedKey != null) { + setProperty(deprecatedKey, value, false); + } + } + } return this; } @@ -347,7 +357,7 @@ public class Settings implements BatchComponent, ServerComponent { } public final Settings setProperties(Settings s) { - if (s.properties==null) { + if (s.properties == null) { return clear(); } return setProperties(Maps.newHashMap(s.properties)); 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 8be0edeca61..0993b09063f 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 @@ -44,7 +44,10 @@ public class SettingsTest { @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 = "sonar.jira", name = "Jira Server", type = PropertyType.PROPERTY_SET, propertySetKey = "jira") + @Property(key = "sonar.jira", name = "Jira Server", type = PropertyType.PROPERTY_SET, propertySetKey = "jira"), + @Property(key = "newKey", name = "New key", deprecatedKey = "oldKey"), + @Property(key = "newKeyWithDefaultValue", name = "New key with default value", deprecatedKey = "oldKeyWithDefaultValue", defaultValue = "default_value"), + @Property(key = "new_multi_values", name = "New multi values", defaultValue = "1,2,3", multiValues = true, deprecatedKey = "old_multi_values") }) static class Init { } @@ -376,4 +379,39 @@ public class SettingsTest { assertThat(settings.getKeysStartingWith("sonar.jdbc")).containsOnly("sonar.jdbc.url", "sonar.jdbc.username"); assertThat(settings.getKeysStartingWith("other")).hasSize(0); } + + @Test + public void should_fallback_deprecated_key_to_default_value_of_new_key() { + Settings settings = new Settings(definitions); + + assertThat(settings.getString("newKeyWithDefaultValue")).isEqualTo("default_value"); + assertThat(settings.getString("oldKeyWithDefaultValue")).isEqualTo("default_value"); + } + + @Test + public void should_fallback_deprecated_key_to_new_key() { + Settings settings = new Settings(definitions); + settings.setProperty("newKey", "value of newKey"); + + assertThat(settings.getString("newKey")).isEqualTo("value of newKey"); + assertThat(settings.getString("oldKey")).isEqualTo("value of newKey"); + } + + @Test + public void should_load_value_set_on_deprecated_key() { + // it's used for example when deprecated settings are set through command-line + Settings settings = new Settings(definitions); + settings.setProperty("oldKey", "value of oldKey"); + + assertThat(settings.getString("newKey")).isEqualTo("value of oldKey"); + assertThat(settings.getString("oldKey")).isEqualTo("value of oldKey"); + } + + @Test + public void should_support_deprecated_props_with_multi_values() { + Settings settings = new Settings(definitions); + settings.setProperty("new_multi_values", new String[]{" A ", " B "}); + assertThat(settings.getStringArray("new_multi_values")).isEqualTo(new String[]{"A", "B"}); + assertThat(settings.getStringArray("old_multi_values")).isEqualTo(new String[]{"A", "B"}); + } } diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index b47b65ba5e3..5c5d8f46955 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -89,6 +89,7 @@ import org.sonar.server.startup.RegisterNewFilters; import org.sonar.server.startup.RegisterNewProfiles; import org.sonar.server.startup.RegisterQualityModels; import org.sonar.server.startup.RegisterRules; +import org.sonar.server.startup.RenameDeprecatedPropertyKeys; import org.sonar.server.startup.ServerMetadataPersister; import org.sonar.server.ui.CodeColorizers; import org.sonar.server.ui.JRubyI18n; @@ -269,6 +270,7 @@ public final class Platform { startupContainer.addSingleton(GeneratePluginIndex.class); startupContainer.addSingleton(RegisterNewFilters.class); startupContainer.addSingleton(RegisterNewDashboards.class); + startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class); startupContainer.startComponents(); startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart(); diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RenameDeprecatedPropertyKeys.java b/sonar-server/src/main/java/org/sonar/server/startup/RenameDeprecatedPropertyKeys.java index 6e154c7144e..79c70a8f0f0 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/RenameDeprecatedPropertyKeys.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/RenameDeprecatedPropertyKeys.java @@ -20,6 +20,7 @@ package org.sonar.server.startup; import com.google.common.base.Strings; +import org.slf4j.LoggerFactory; import org.sonar.api.config.PropertyDefinition; import org.sonar.api.config.PropertyDefinitions; import org.sonar.core.properties.PropertiesDao; @@ -38,6 +39,7 @@ public class RenameDeprecatedPropertyKeys { } public void start() { + LoggerFactory.getLogger(RenameDeprecatedPropertyKeys.class).info("Rename deprecated property keys"); for (PropertyDefinition definition : definitions.getAll()) { if (!Strings.isNullOrEmpty(definition.getDeprecatedKey())) { dao.renamePropertyKey(definition.getDeprecatedKey(), definition.getKey()); diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/measures_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/measures_controller.rb new file mode 100644 index 00000000000..0b6662b207f --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/measures_controller.rb @@ -0,0 +1,27 @@ +# +# 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 +# +class MeasuresController < ApplicationController + + def index + + end + + +end