2

Is there any way for dynamically changing the fields of a Typesafe config file, using source code to populate placeholders?

For example, assume the following simple configuration statement

{
  values {
    string1: ${name1}
    string2: ${name2}
    string3: ${name3}
    string4: ${name4}
  }
}

As discussed in HOCON documentation and mentioned in an earlier StackOverflow question, one can use environmental variables and system properties to achieve this.

Is it possible to also do the same thing directly from a program? For instance, in Java, having a class Constants like

public class Constants
{
  public static final String name1 = "A";
  public static final String name2 = "B";
  public static final String name3 = "C";
  public static final String name4 = "D";
}

and populating the configuration fields from that class?

HOCON allows integrating Java and executing code in the config file but apparently there is no way to set config placeholders from within the integrated Java code.

Community
  • 1
  • 1
PNS
  • 19,295
  • 32
  • 96
  • 143

1 Answers1

5

You can resolve placeholders by calling resolve(...) with a config of resolved placeholders on an instance of Config.

import com.typesafe.config.ConfigFactory;
import com.typesafe.config.Config;

public class ConfigOverrideFromCode {
    static public void main(String[] args) {
        String config = "system.administrator = ${who-knows}";

        Config original = ConfigFactory
                    .parseString(config)
                    .resolveWith(ConfigFactory.parseString("who-knows = jon"));
        System.out.println(original.getString("system.administrator"));
    }
}
dvim
  • 2,223
  • 1
  • 17
  • 17
  • Thanks and +1. I have read this approach in other questions, but if you have multiple strings in the config file, it means that you have to parse the entire configuration multiple times to substitute the corresponding values. I was hoping for a more "direct" approach but then again, if there is none, your solution can be used. – PNS Jul 09 '14 at 15:54
  • You do not have to parse the entire configuration multiple times. You can pass to `resolveWith` a `Config` which holds all the substituted variables. And there are more ways to create `Config` than parsing a string. Look what `parse...` methods [ConfigFactory](http://typesafehub.github.io/config/latest/api/com/typesafe/config/ConfigFactory.html) has. [Here is another sample](https://gist.github.com/2m/941ed15336d92748cd39) to demonstrate multiple placeholder resolution with values from a map. The key point in my answer is `Config.resloveWith(...)`. Other than that, get creative. :) – dvim Jul 10 '14 at 09:11
  • Merging the configurations will entail multiple parsing, too. I am still not thrilled about this solution. A better approach would perhaps be passing a Java "Environment" object to the configuration, so that one could set placeholders in embedded Java code. Since nothing like that seems to exist however, and since apparently nobody else has a better suggestion, I will follow your advice. Thanks. :-) – PNS Jul 11 '14 at 17:21