org.ekrich.config
Type members
Classlikes
An immutable map from config paths to config values. Paths are dot-separated
expressions such as foo.bar.baz
. Values are as in JSON
(booleans, strings, numbers, lists, or objects), represented by
[[ConfigValue]]
instances. Values accessed through the
Config
interface are never null.
An immutable map from config paths to config values. Paths are dot-separated
expressions such as foo.bar.baz
. Values are as in JSON
(booleans, strings, numbers, lists, or objects), represented by
[[ConfigValue]]
instances. Values accessed through the
Config
interface are never null.
Config
is an immutable object and thus safe to use from multiple
threads. There's never a need for "defensive copies."
Fundamental operations on a Config
include getting configuration
values, resolving substitutions with resolve(), and
merging configs using
withFallback(ConfigMergeable).
All operations return a new immutable Config
rather than modifying
the original instance.
Examples
You can find an example app and library
on GitHub.
Also be sure to read the package-summary.html#package_description
package overview]]
which describes the big picture as shown in those examples.
Paths, keys, and Config vs. ConfigObject
Config
is a view onto a tree of [[ConfigObject]]
; the
corresponding object tree can be found through [[Config#root]]
.
ConfigObject
is a map from config keys, rather than
paths, to config values. Think of ConfigObject
as a JSON object
and Config
as a configuration API.
The API tries to consistently use the terms "key" and "path." 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. Path expressions are described in the spec for Human-Optimized Config Object Notation. 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 API for a Config
is in terms of path expressions, while the API
for a ConfigObject
is in terms of keys. Conceptually, Config
is a one-level map from paths to values, while a
ConfigObject
is a tree of nested maps from keys to values.
Use ConfigUtil.joinPath(String*) and ConfigUtil.splitPath(String) to convert between path expressions and individual path elements (keys).
Another difference between Config
and ConfigObject
is that
conceptually, ConfigValue
s with a [[ConfigValue#valueType valueType]]
of [[ConfigValueType#NULL NULL]]
exist in a
ConfigObject
, while a Config
treats null values as if they
were missing. (With the exception of two methods: [[Config#hasPathOrNull]]
and [[Config#getIsNull]]
let you detect null
values.)
Getting configuration values
The "getters" on a Config
all work in the same way. They never return
null, nor do they return a ConfigValue
with
[[ConfigValue#valueType valueType]]
of [[ConfigValueType#NULL NULL]]
. Instead, they throw [[ConfigException.Missing]]
if the value is
completely absent or set to null. If the value is set to null, a subtype of
ConfigException.Missing
called [[ConfigException.Null]]
will be
thrown. [[ConfigException.WrongType]]
will be thrown anytime you ask for
a type and the value has an incompatible type. Reasonable type conversions
are performed for you though.
Iteration
If you want to iterate over the contents of a Config
, you can get its
ConfigObject
with [[#root]]
, and then iterate over the
ConfigObject
(which implements java.util.Map
). Or, you
can use [[#entrySet]]
which recurses the object tree for you and builds
up a Set
of all path-value pairs where the value is not null.
'''Resolving substitutions'''
''Substitutions'' are the ${foo.bar}
syntax in config
files, described in the <a href=
"https://github.com/lightbend/config/blob/master/HOCON.md#substitutions"
specification. Resolving substitutions replaces these references with real values.
Before using a Config
it's necessary to call resolve()
to handle substitutions (though ConfigFactory.load() and similar
methods will do the resolve for you already).
Merging
The full Config
for your application can be constructed using
the associative operation
withFallback(ConfigMergeable).
If you use ConfigFactory.load() (recommended), it
merges system properties over the top of application.conf
over
the top of reference.conf
, using withFallback
. You
can add in additional sources of configuration in the same way (usually,
custom layers should go either just above or just below
application.conf
, keeping reference.conf
at the
bottom and system properties at the top).
Serialization
Convert a Config
to a JSON or HOCON string by calling
root to get the ConfigObject and then call
render
on the root object, myConfig.root.render
. There's also a variant
render(ConfigRenderOptions)
inherited from ConfigValue which allows you to control
the format of the rendered string. (See [[ConfigRenderOptions]]
.) Note
that Config
does not remember the formatting of the original
file, so if you load, modify, and re-save a config file, it will be
substantially reformatted.
As an alternative to render, the
toString
method produces a debug-output-oriented
representation (which is not valid JSON).
Java serialization is supported as well for Config
and all
subtypes of ConfigValue
.
This is an interface but don't implement it yourself
Do not implement Config
; it should only be implemented by
the config library. Arbitrary implementations will not work because the
library internals assume a specific concrete implementation. Also, this
interface is likely to grow new methods over time, so third-party
implementations will break.
All exceptions thrown by the library are subclasses of
ConfigException
.
All exceptions thrown by the library are subclasses of
ConfigException
.
- Companion
- object
Contains static methods for creating Config instances.
Contains static methods for creating Config instances.
See also ConfigValueFactory which contains static methods for converting Java values into a ConfigObject. You can then convert a ConfigObject into a Config with ConfigObject.toConfig().
The static methods with "load" in the name do some sort of higher-level operation potentially parsing multiple resources and resolving substitutions, while the ones with "parse" in the name just create a ConfigValue from a resource and nothing else.
You can find an example app and library <a on GitHub. Also be sure to read the package overview which describes the big picture as shown in those examples.
- Companion
- class
Context provided to a [[ConfigIncluder]]
; this interface is only useful
inside a ConfigIncluder
implementation, and is not intended for apps
to implement.
Context provided to a [[ConfigIncluder]]
; this interface is only useful
inside a ConfigIncluder
implementation, and is not intended for apps
to implement.
Do not implement this interface; it should only be implemented by the config library. Arbitrary implementations will not work because the library internals assume a specific concrete implementation. Also, this interface is likely to grow new methods over time, so third-party implementations will break.
Implement this interface and provide an instance to
[[ConfigParseOptions#setIncluder ConfigParseOptions.setIncluder()]]
to
customize handling of include
statements in config files. You may
also want to implement [[ConfigIncluderClasspath]]
,
[[ConfigIncluderFile]]
, and [[ConfigIncluderURL]]
, or not.
Implement this interface and provide an instance to
[[ConfigParseOptions#setIncluder ConfigParseOptions.setIncluder()]]
to
customize handling of include
statements in config files. You may
also want to implement [[ConfigIncluderClasspath]]
,
[[ConfigIncluderFile]]
, and [[ConfigIncluderURL]]
, or not.
Implement this in addition to [[ConfigIncluder]]
if you want to
support inclusion of files with the include classpath("resource")
syntax. If you do not implement this but do implement [[ConfigIncluder]]
,
attempts to load classpath resources will use the default includer.
Implement this in addition to [[ConfigIncluder]]
if you want to
support inclusion of files with the include classpath("resource")
syntax. If you do not implement this but do implement [[ConfigIncluder]]
,
attempts to load classpath resources will use the default includer.
Implement this in addition to [[ConfigIncluder]]
if you want to
support inclusion of files with the include file("filename")
syntax.
If you do not implement this but do implement [[ConfigIncluder]]
,
attempts to load files will use the default includer.
Implement this in addition to [[ConfigIncluder]]
if you want to
support inclusion of files with the include file("filename")
syntax.
If you do not implement this but do implement [[ConfigIncluder]]
,
attempts to load files will use the default includer.
Implement this in addition to [[ConfigIncluder]]
if you want to
support inclusion of files with the include url("http://example.com")
syntax. If you do not implement this but do implement [[ConfigIncluder]]
,
attempts to load URLs will use the default includer.
Implement this in addition to [[ConfigIncluder]]
if you want to
support inclusion of files with the include url("http://example.com")
syntax. If you do not implement this but do implement [[ConfigIncluder]]
,
attempts to load URLs will use the default includer.
Subtype of [[ConfigValue]]
representing a list value, as in JSON's
[1,2,3]
syntax.
Subtype of [[ConfigValue]]
representing a list value, as in JSON's
[1,2,3]
syntax.
ConfigList
implements java.util.List
so you can
use it like a regular Java list. Or call [[#unwrapped]]
to unwrap the
list elements into plain Java values.
Like all [[ConfigValue]]
subtypes, ConfigList
is immutable. This
makes it threadsafe and you never have to create "defensive copies." The
mutator methods from java.util.List
all throw
java.lang.UnsupportedOperationException
.
The [[ConfigValue#valueType]]
method on a list returns
[[ConfigValueType#LIST]]
.
Do not implement ConfigList
; it should only be implemented
by the config library. Arbitrary implementations will not work because the
library internals assume a specific concrete implementation. Also, this
interface is likely to grow new methods over time, so third-party
implementations will break.
This method allows you to alter default config loading strategy for all the code which calls one of the methods, e.g. ConfigFactory.load(String)
This method allows you to alter default config loading strategy for all the code which calls one of the methods, e.g. ConfigFactory.load(String)
Usually you don't have to implement this interface but it may be required when you fixing a improperly implemented library with unavailable source code.
You have to define VM property config.strategy
to replace default strategy with your own.
An immutable class representing an amount of memory. Use
static factory methods such as
[[ConfigMemorySize#ofBytes]]
to create instances.
An immutable class representing an amount of memory. Use
static factory methods such as
[[ConfigMemorySize#ofBytes]]
to create instances.
- Since
1.3.0
- Companion
- class
Marker for types whose instances can be merged, that is Config and
ConfigValue. Instances of Config
and ConfigValue
can
be combined into a single new instance using the
withFallback() method.
Marker for types whose instances can be merged, that is Config and
ConfigValue. Instances of Config
and ConfigValue
can
be combined into a single new instance using the
withFallback() method.
''Do not implement this interface''; it should only be implemented by the config library. Arbitrary implementations will not work because the library internals assume a specific concrete implementation. Also, this interface is likely to grow new methods over time, so third-party implementations will break.
Subtype of [[ConfigValue]]
representing an object (AKA dictionary or map)
value, as in JSON's curly brace { "a" : 42 }
syntax.
Subtype of [[ConfigValue]]
representing an object (AKA dictionary or map)
value, as in JSON's curly brace { "a" : 42 }
syntax.
An object may also be viewed as a [[Config]]
by calling
[[ConfigObject#toConfig]]
.
ConfigObject
implements java.util.Map<String, ConfigValue>
so
you can use it like a regular Java map. Or call [[#unwrapped]]
to
unwrap the map to a map with plain Java values rather than
ConfigValue
.
Like all [[ConfigValue]]
subtypes, ConfigObject
is immutable.
This makes it threadsafe and you never have to create "defensive copies." The
mutator methods from java.util.Map
all throw
java.lang.UnsupportedOperationException
.
The [[ConfigValue#valueType]]
method on an object returns
[[ConfigValueType#OBJECT]]
.
In most cases you want to use the [[Config]]
interface rather than this
one. Call [[#toConfig]]
to convert a ConfigObject
to a
Config
.
The API for a ConfigObject
is in terms of keys, while the API for a
[[Config]]
is in terms of path expressions. Conceptually,
ConfigObject
is a tree of maps from keys to values, while a
Config
is a one-level map from paths to values.
Use ConfigUtil.joinPath(String*) and ConfigUtil.splitPath(String) to convert between path expressions and individual path elements (keys).
A ConfigObject
may contain null values, which will have
[[ConfigValue#valueType]]
equal to [[ConfigValueType#NULL]]
. If
[[ConfigObject#get]]
returns Java's null then the key was not
present in the parsed file (or wherever this value tree came from). If
get("key")
returns a [[ConfigValue]]
with type
ConfigValueType#NULL
then the key was set to null explicitly in the
config file.
Do not implement interface ConfigObject
; it should only be
implemented by the config library. Arbitrary implementations will not work
because the library internals assume a specific concrete implementation.
Also, this interface is likely to grow new methods over time, so third-party
implementations will break.
Represents the origin (such as filename and line number) of a
[[ConfigValue]]
for use in error messages. Obtain the origin of a value
with [[ConfigValue#origin]]
. Exceptions may have an origin, see
[[ConfigException#origin]]
, but be careful because
ConfigException.origin()
may return null.
Represents the origin (such as filename and line number) of a
[[ConfigValue]]
for use in error messages. Obtain the origin of a value
with [[ConfigValue#origin]]
. Exceptions may have an origin, see
[[ConfigException#origin]]
, but be careful because
ConfigException.origin()
may return null.
It's best to use this interface only for debugging; its accuracy is "best effort" rather than guaranteed, and a potentially-noticeable amount of memory could probably be saved if origins were not kept around, so in the future there might be some option to discard origins.
Do not implement this interface; it should only be implemented by the config library. Arbitrary implementations will not work because the library internals assume a specific concrete implementation. Also, this interface is likely to grow new methods over time, so third-party implementations will break.
This class contains some static factory methods for building a ConfigOrigin. ConfigOrigins are automatically created when you call other API methods to get a ConfigValue or Config. But you can also set the origin of an existing ConfigValue, using ConfigValue.withOrigin(ConfigOrigin).
This class contains some static factory methods for building a ConfigOrigin. ConfigOrigins are automatically created when you call other API methods to get a ConfigValue or Config. But you can also set the origin of an existing ConfigValue, using ConfigValue.withOrigin(ConfigOrigin).
- Since
1.3.0
- Companion
- class
A set of options related to parsing.
A set of options related to parsing.
This object is immutable, so the "setters" return a new object.
Here is an example of creating a custom ConfigParseOptions
:
ConfigParseOptions options = ConfigParseOptions.defaults() .setSyntax(ConfigSyntax.JSON) .setAllowMissing(false)
- Companion
- class
An opaque handle to something that can be parsed, obtained from
[[ConfigIncludeContext]]
.
An opaque handle to something that can be parsed, obtained from
[[ConfigIncludeContext]]
.
Do not implement this interface; it should only be implemented by the config library. Arbitrary implementations will not work because the library internals assume a specific concrete implementation. Also, this interface is likely to grow new methods over time, so third-party implementations will break.
A set of options related to rendering a [[ConfigValue]]
. Passed to
ConfigValue.render(ConfigRenderOptions).
A set of options related to rendering a [[ConfigValue]]
. Passed to
ConfigValue.render(ConfigRenderOptions).
Here is an example of creating a ConfigRenderOptions
:
ConfigRenderOptions options = ConfigRenderOptions.defaults().setComments(false)
- Companion
- class
A set of options related to resolving substitutions. Substitutions use the
${foo.bar
syntax and are documented in the
HOCON">spec.
A set of options related to resolving substitutions. Substitutions use the
${foo.bar
syntax and are documented in the
HOCON">spec.
Typically this class would be used with the method Config.resolve(ConfigResolveOptions).
This object is immutable, so the "setters" return a new object.
Here is an example of creating a custom ConfigResolveOptions
:
ConfigResolveOptions options = ConfigResolveOptions.defaults() .setUseSystemEnvironment(false)
In addition to [[ConfigResolveOptions#defaults]]
, there's a prebuilt
[[ConfigResolveOptions#noSystem]]
which avoids looking at any system
environment variables or other external system information. (Right now,
environment variables are the only example.)
- Companion
- class
Implement this interface and provide an instance to
[[ConfigResolveOptions#appendResolver ConfigResolveOptions.appendResolver()]]
to provide custom behavior when unresolved substitutions are encountered
during resolution.
Implement this interface and provide an instance to
[[ConfigResolveOptions#appendResolver ConfigResolveOptions.appendResolver()]]
to provide custom behavior when unresolved substitutions are encountered
during resolution.
- Since
1.3.2
The syntax of a character stream (JSON, HOCON aka ".conf", or <a href= "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
The syntax of a character stream (JSON, HOCON aka ".conf", or <a href= "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
Java properties).
An immutable value, following the JSON type schema.
An immutable value, following the JSON type schema.
Because this object is immutable, it is safe to use from multiple threads and there's no need for "defensive copies."
Do not implement interface ConfigValue
; it should only be
implemented by the config library. Arbitrary implementations will not work
because the library internals assume a specific concrete implementation.
Also, this interface is likely to grow new methods over time, so third-party
implementations will break.
This class holds some static factory methods for building [[ConfigValue]]
instances. See also [[ConfigFactory]]
which has methods for parsing files
and certain in-memory data structures.
This class holds some static factory methods for building [[ConfigValue]]
instances. See also [[ConfigFactory]]
which has methods for parsing files
and certain in-memory data structures.
- Companion
- class
Default config loading strategy. Able to load resource, file or URL.
Behavior may be altered by defining one of VM properties
config.resource
, config.file
or config.url
Default config loading strategy. Able to load resource, file or URL.
Behavior may be altered by defining one of VM properties
config.resource
, config.file
or config.url