add more docs about paths vs. keys

This commit is contained in:
Havoc Pennington 2011-11-17 10:36:06 -05:00
parent 2886f73772
commit d8e54099e9
2 changed files with 72 additions and 14 deletions

View File

@ -19,6 +19,16 @@ import com.typesafe.config.impl.Parseable;
* potentially parsing multiple resources and resolving substitutions, while the * potentially parsing multiple resources and resolving substitutions, while the
* ones with "parse" in the name just create a ConfigValue from a resource and * ones with "parse" in the name just create a ConfigValue from a resource and
* nothing else. * nothing else.
*
* Throughout the API, there is a distinction between "keys" and "paths". A key
* is a key in a JSON object; it's just a string that's the key in a map. A
* "path" is a parseable expression with a syntax and it refers to a series of
* keys. A path is used to traverse nested ConfigObject by looking up each key
* in the path. Path expressions are described in the spec for "HOCON", which
* can be found at https://github.com/havocp/config/blob/master/HOCON.md; in
* brief, a path is period-separated so "a.b.c" looks for key c in object b in
* object a in the root object. Sometimes double quotes are needed around
* special characters in path expressions.
*/ */
public final class Config { public final class Config {
@ -108,6 +118,25 @@ public final class Config {
return ConfigImpl.envVariablesAsConfig(); return ConfigImpl.envVariablesAsConfig();
} }
/**
* Converts a Java Properties object to a ConfigObject using the rules
* documented in https://github.com/havocp/config/blob/master/HOCON.md The
* keys in the Properties object are split on the period character '.' and
* treated as paths. The values will all end up as string values. If you
* have both "a=foo" and "a.b=bar" in your properties file, so "a" is both
* the object containing "b" and the string "foo", then the string value is
* dropped.
*
* If you want to get System.getProperties() as a ConfigObject, it's better
* to use the systemProperties() or systemPropertiesRoot() methods. Those
* methods are able to use a cached global singleton ConfigObject for the
* system properties.
*
* @param properties
* a Java Properties object
* @param options
* @return
*/
public static ConfigObject parse(Properties properties, public static ConfigObject parse(Properties properties,
ConfigParseOptions options) { ConfigParseOptions options) {
return Parseable.newProperties(properties, options).parse(); return Parseable.newProperties(properties, options).parse();
@ -153,24 +182,29 @@ public final class Config {
* will become a ConfigObject and an Iterable will become a ConfigList. If * will become a ConfigObject and an Iterable will become a ConfigList. If
* the Iterable is not an ordered collection, results could be strange, * the Iterable is not an ordered collection, results could be strange,
* since ConfigList is ordered. * since ConfigList is ordered.
* *
* In a Map passed to fromAnyRef(), the map's keys are plain keys, not path
* expressions. So if your Map has a key "foo.bar" then you will get one
* object with a key called "foo.bar", rather than an object with a key
* "foo" containing another object with a key "bar".
*
* The originDescription will be used to set the origin() field on the * The originDescription will be used to set the origin() field on the
* ConfigValue. It should normally be the name of the file the values came * ConfigValue. It should normally be the name of the file the values came
* from, or something short describing the value such as "default settings". * from, or something short describing the value such as "default settings".
* The originDescription is prefixed to error messages so users can tell * The originDescription is prefixed to error messages so users can tell
* where problematic values are coming from. * where problematic values are coming from.
* *
* Supplying the result of ConfigValue.unwrapped() to this function is * Supplying the result of ConfigValue.unwrapped() to this function is
* guaranteed to work and should give you back a ConfigValue that matches * guaranteed to work and should give you back a ConfigValue that matches
* the one you unwrapped. The re-wrapped ConfigValue will lose some * the one you unwrapped. The re-wrapped ConfigValue will lose some
* information that was present in the original such as its origin, but it * information that was present in the original such as its origin, but it
* will have matching values. * will have matching values.
* *
* This function throws if you supply a value that cannot be converted to a * This function throws if you supply a value that cannot be converted to a
* ConfigValue, but supplying such a value is a bug in your program, so you * ConfigValue, but supplying such a value is a bug in your program, so you
* should never handle the exception. Just fix your program (or report a bug * should never handle the exception. Just fix your program (or report a bug
* against this library). * against this library).
* *
* @param object * @param object
* object to convert to ConfigValue * object to convert to ConfigValue
* @param originDescription * @param originDescription
@ -186,6 +220,14 @@ public final class Config {
* wrapper that only works on Map and returns ConfigObject rather than * wrapper that only works on Map and returns ConfigObject rather than
* ConfigValue. * ConfigValue.
* *
* If your Map has a key "foo.bar" then you will get one object with a key
* called "foo.bar", rather than an object with a key "foo" containing
* another object with a key "bar". The keys in the map are keys; not path
* expressions. That is, the Map corresponds exactly to a single
* ConfigObject. The keys will not be parsed or modified, and the values are
* wrapped in ConfigValue. To get nested ConfigObject, some of the values in
* the map would have to be more maps.
*
* @param values * @param values
* @param originDescription * @param originDescription
* @return * @return

View File

@ -7,17 +7,33 @@ import java.util.Map;
* A ConfigObject is a read-only configuration object, which may have nested * A ConfigObject is a read-only configuration object, which may have nested
* child objects. Implementations of ConfigObject should be immutable (at least * child objects. Implementations of ConfigObject should be immutable (at least
* from the perspective of anyone using this interface). * from the perspective of anyone using this interface).
*
* Throughout the API, there is a distinction between "keys" and "paths". A key
* is a key in a JSON object; it's just a string that's the key in a map. A
* "path" is a parseable expression with a syntax and it refers to a series of
* keys. A path is used to traverse nested ConfigObject by looking up each key
* in the path. Path expressions are described in the spec for "HOCON", which
* can be found at https://github.com/havocp/config/blob/master/HOCON.md; in
* brief, a path is period-separated so "a.b.c" looks for key c in object b in
* object a in the root object. Sometimes double quotes are needed around
* special characters in path expressions.
* *
* The getters all have the same semantics; they throw ConfigException.Missing * ConfigObject implements java.util.Map<String,ConfigValue>. For all methods
* if the value is entirely unset, and ConfigException.WrongType if you ask for * implementing the Map interface, the keys are just plain keys; not a parseable
* a type that the value can't be converted to. ConfigException.Null is a * path expression. In methods implementing Map, a ConfigValue with
* subclass of ConfigException.WrongType thrown if the value is null. The "path" * ConfigValue.valueType() of ConfigValueType.NULL will be distinct from a
* parameters for all the getters have periods between the key names, so the * missing value. java.util.Map.containsKey() returns true if the map contains a
* path "a.b.c" looks for key c in object b in object a in the root object. (The * value of type ConfigValueType.NULL at that key.
* syntax for paths is the same as in ${} substitution expressions in config
* files, sometimes double quotes are needed around special characters.)
* *
* ConfigObject implements the standard Java Map interface, but the mutator * ConfigObject has another set of "getters", such as getValue() and getAnyRef()
* and getInt(), with more convenient semantics than java.util.Map.get(). These
* "getters" throw ConfigException.Missing if the value is entirely unset, and
* ConfigException.WrongType if you ask for a type that the value can't be
* converted to. ConfigException.Null is a subclass of ConfigException.WrongType
* thrown if the value is null. These getters also use path expressions, rather
* than keys, as described above.
*
* While ConfigObject implements the standard Java Map interface, the mutator
* methods all throw UnsupportedOperationException. This Map is immutable. * methods all throw UnsupportedOperationException. This Map is immutable.
* *
* The Map may contain null values, which will have ConfigValue.valueType() == * The Map may contain null values, which will have ConfigValue.valueType() ==
@ -47,7 +63,7 @@ public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
* not a key; and it returns false for null values, while containsKey() * not a key; and it returns false for null values, while containsKey()
* returns true indicating that the object contains a null value for the * returns true indicating that the object contains a null value for the
* key. * key.
* *
* If a path exists according to hasPath(), then getValue() will never throw * If a path exists according to hasPath(), then getValue() will never throw
* an exception. However, the typed getters, such as getInt(), will still * an exception. However, the typed getters, such as getInt(), will still
* throw if the value is not convertible to the requested type. * throw if the value is not convertible to the requested type.