Class PropertyKeys

java.lang.Object
org.aeonbits.owner.loaders.PropertyKeys

public final class PropertyKeys extends Object
How a tree becomes flat property keys, in one place.

A Loader hands back a Properties, which is a flat map of string to string, and XML, JSON, YAML and the rest are trees. Every one of them therefore has to say the same two things: how a child is named below its parent, and how one element of a list is named. If each loader answered on its own the answers would drift, and a key would mean something slightly different according to the file it came out of. They answer here instead.

     {"server": {"host": "localhost", "ports": [80, 443]}}
 
     server.host=localhost
     server.ports[0]=80
     server.ports[1]=443
 

A dot for nesting, because that is the convention properties files have always used and the one @Key("server.host") already expects. Square brackets for an index, because the dot is taken: a method returning a Map reads everything under server. as a group, so ports.0 would make one layout of keys mean two things according only to the return type, and would leave a map whose keys are numbers indistinguishable from a list.

The two compose in both directions, which is what makes the convention worth having rather than merely having one: servers[0].host is the host of the first server, and grid[0][1] is a cell of a list of lists. Reading the first of those needs nested configuration interfaces and does not work yet, but a loader written today produces the key that will be read then, and nothing has to be flattened twice.

A dot inside a name is ambiguous, and is left so on purpose. A JSON object {"a.b": 1} nested under x flattens to x.a.b=1, which is what {"a": {"b": 1}} flattens to as well. Escaping would remove the ambiguity for whoever wants to reverse the flattening, and cost every reader of a perfectly ordinary key the escape: @Key("x.a.b") works today for either file and would have to become something less obvious. Since nothing in the library reverses a flattened key — a configuration method names the key it wants, and gets it — the ambiguity has no victim, and inventing a quoting scheme to serve a reader that does not exist would be the worse trade. It is written down here so the choice is visible when it stops being true.
Since:
2.0.0
Author:
Matteo Baccan
  • Field Details

  • Method Details

    • child

      public static String child(String parent, String name)
      The key of a child below its parent: server and host give server.host.
      Parameters:
      parent - the key of the parent, or null or empty at the top of the tree.
      name - the name of the child.
      Returns:
      the key of the child.
    • element

      public static String element(String key, int index)
      The key of one element of a list: ports and 0 give ports[0]. Elements are numbered from zero and consecutively; a gap is refused when the list is read back.
      Parameters:
      key - the key of the list.
      index - the position of the element, from zero.
      Returns:
      the key of the element.
      Throws:
      IllegalArgumentException - if the index is negative.