diff --git a/core/commons/che-core-commons-inject/src/main/java/org/eclipse/che/inject/CheBootstrap.java b/core/commons/che-core-commons-inject/src/main/java/org/eclipse/che/inject/CheBootstrap.java index 739f923689..064e773017 100644 --- a/core/commons/che-core-commons-inject/src/main/java/org/eclipse/che/inject/CheBootstrap.java +++ b/core/commons/che-core-commons-inject/src/main/java/org/eclipse/che/inject/CheBootstrap.java @@ -32,8 +32,10 @@ import java.nio.charset.Charset; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.function.Function; @@ -98,9 +100,24 @@ import org.slf4j.LoggerFactory; * ${root_data}/input/  ${root_data}/input/ * * + * During code evolution might be the case when someone will want to rename some property. This + * brings a couple of problems like support of old property name in external plugins and support old + * configuration values in code with the new property name. To cover these cases there is a file + * che_aliases.properties that contains old names of all existed properties. It has such format + * current_name =old_name, very_old_name. In this case will be such binding. + * + *

Always current_name = current_value if old_name property exist it will be binded to old_value + * and current_name = old_value and very_old_name = old_value if very_old_name property exist it + * will be binded to very_old_value, and current_name = very_old_value and old_name = very_old_value + * + *

NOTE: it's prohibited to use a different name for same property on the same level. From the + * example above - you can use environment property CHE_CURRENT_NAME and CHE_OLD_NAME. But you can + * use it on a different level, for instance, environment property and system property. + * * @author gazarenkov * @author andrew00x * @author Florent Benoit + * @author Sergii Kabashniuk */ public class CheBootstrap extends EverrestGuiceContextListener { private static final Logger LOG = LoggerFactory.getLogger(CheBootstrap.class); @@ -319,10 +336,18 @@ public class CheBootstrap extends EverrestGuiceContextListener { Pattern.compile("\\$\\{[^\\}^\\$\\{]+\\}"); abstract static class AbstractConfigurationModule extends AbstractModule { - final Map> aliases; + final Map> bindMap; AbstractConfigurationModule(Map> aliases) { - this.aliases = aliases; + this.bindMap = new HashMap<>(aliases); + for (Entry> entry : aliases.entrySet()) { + for (String alias : entry.getValue()) { + Set newAliases = new HashSet<>(entry.getValue()); + newAliases.remove(alias); + newAliases.add(entry.getKey()); + bindMap.put(alias, newAliases); + } + } } protected void bindConf(File confDir) { @@ -410,7 +435,7 @@ public class CheBootstrap extends EverrestGuiceContextListener { private void bindProperty(String prefix, String name, String value) { String key = prefix == null ? name : (prefix + name); - Set aliasesForName = aliases.get(name); + Set aliasesForName = bindMap.get(name); if (value == null) { bind(String.class).annotatedWith(Names.named(key)).toProvider(Providers.of(null)); if (aliasesForName != null) { diff --git a/core/commons/che-core-commons-inject/src/test/java/org/eclipse/che/inject/CheBootstrapTest.java b/core/commons/che-core-commons-inject/src/test/java/org/eclipse/che/inject/CheBootstrapTest.java index 272a4c3a2c..94b31424de 100644 --- a/core/commons/che-core-commons-inject/src/test/java/org/eclipse/che/inject/CheBootstrapTest.java +++ b/core/commons/che-core-commons-inject/src/test/java/org/eclipse/che/inject/CheBootstrapTest.java @@ -297,6 +297,28 @@ public class CheBootstrapTest { assertEquals(testComponent.otherOtherString, "some_value"); } + @Test + public void processesOld2NewPropertyAliases() throws Exception { + Properties cheProperties = new Properties(); + cheProperties.put("che.some.name", "some_value"); + writePropertiesFile(che, "che.properties", cheProperties); + + Properties aliases = new Properties(); + aliases.put("very.new.some.name", "new.some.name, che.some.name"); + writePropertiesFile(che.getParentFile(), PROPERTIES_ALIASES_CONFIG_FILE, aliases); + + ModuleScanner.modules.add(binder -> binder.bind(TestConfAliasComponent.class)); + + cheBootstrap.contextInitialized(new ServletContextEvent(servletContext)); + + Injector injector = retrieveComponentFromServletContext(Injector.class); + + TestConfAliasComponent testComponent = injector.getInstance(TestConfAliasComponent.class); + assertEquals(testComponent.string, "some_value"); + assertEquals(testComponent.otherString, "some_value"); + assertEquals(testComponent.otherOtherString, "some_value"); + } + static class TestChePropertiesComponent { @Named("test_int") @Inject