How to get a deployed key in Configes Config?

Test case:

import org.specs2.mutable._ class HelloWorldSpec extends Specification { "Typesafe Config" should "allow me to see my escaped key" in { val entries = ConfigFactory.parseString(""" "quoted.key.1" = 5 "quoted.key.2" = 6""").entrySet entries.head.getKey === "quoted.key.1" } } 

This test fails because the key is actually "quoted.key.1" , not quoted.key.1 . Is there a way to expand this, or do I need to manually search for the surrounding quotes and delete them each time?

+8
scala typesafe typesafe-config
source share
1 answer

Read about "Paths, Keys, and Config vs. ConfigObject" in the API docs here: http://typesafehub.imtqy.com/config/latest/api/com/typesafe/config/Config.html and in README here: https: / /github.com/typesafehub/config#understanding-config-and-configobject

(Suggestions for improving these documents are welcome.)

The keys in the recordset (and Config) are path expressions. These are lines that need to be parsed. ConfigUtil has a parsing method, see http://typesafehub.imtqy.com/config/latest/api/com/typesafe/config/ConfigUtil.html#splitPath%28java.lang.String%29

You cannot just remove the quotation marks; parsing is a bit more complicated. Fortunately, you can simply use the ConfigUtil.splitPath method.

So the two ways to iterate the keys at the root level are something like: first with Config:

 Config config = ... ; for (Map.Entry<String, ConfigValue> entry: config.entrySet()) { String[] keys = ConfigUtil.splitPath(entry.getKey()); System.out.println("Root key = " + keys[0]); } 

Then using ConfigObject:

 Config config = ... ; for (Map.Entry<String, ConfigValue> entry: config.root().entrySet()) { System.out.println("Root key = " + entry.getKey()); } 

I did not try to compile the examples above, so goodbye to any stupid syntax errors.

If your configuration contains only one level (without nested objects), the above two methods of iteration are the same; but if you have nested values, they do not match, because the Config iteration will give you all the sheet values, while the ConfigObject iteration ( config.root() ) will give you all the immediate children of the root, even if these immediate children themselves are objects .

Say what you have:

 foo { bar { baz = 10 } } 

If you repeat this as Config , you will get one entry that will have the path foo.bar.baz as the key and a value of 10 . If you repeat it as ConfigObject , then you will have one record that will have the key foo , and the value will be an object, which, in turn, will contain the key bar . If you repeat this as Config you could splitPath foo.bar.baz , and you would get an array of three lines, foo , bar and baz .

To convert a Config to ConfigObject use the root() method and to convert ConfigObject to Config use the toConfig() method. So config.root().toConfig() == config .

In addition, the above configuration file may be equivalently written as:

 foo.bar.baz = 10 

But it would be different if it were written as:

 "foo.bar.baz" = 10 

Because in the first case, you have nested objects, and in the second case, you have one object with periods in the key name. This is due to quotation marks.

If you write "foo.bar.baz" with quotes, then when you repeat Config path you return will be returned, and splitPath() will return an array from one foo.bar.baz element. When you repeat ConfigObject , you will have one object that will contain the entry with foo.bar.baz as the key and 10 as the value. Keys containing . or other special characters must be quoted, so they are interpreted as separate keys, not paths.

To pass the test, you can do this with splitPath:

 import org.specs2.mutable._ class HelloWorldSpec extends Specification { "Typesafe Config" should "allow me to see my escaped key" in { val entries = ConfigFactory.parseString(""" "quoted.key.1" = 5 "quoted.key.2" = 6""").entrySet // the ordering of entrySet is not guaranteed so this may // still fail because it gets quoted.key.2 instead ConfigUtil.splitPath(entries.head.getKey).head === "quoted.key.1" } } 

You can also do this using ConfigObject :

 import org.specs2.mutable._ class HelloWorldSpec extends Specification { "Typesafe Config" should "allow me to see my escaped key" in { val entries = ConfigFactory.parseString(""" "quoted.key.1" = 5 "quoted.key.2" = 6""").root.entrySet // note ".root." here // the ordering of entrySet is not guaranteed so this may // still fail because it gets quoted.key.2 instead // no need to splitPath because ConfigObject has keys not paths entries.head.getKey === "quoted.key.1" } } 
+7
source share

All Articles