mirror of
https://github.com/lightbend/config.git
synced 2025-01-29 05:30:08 +08:00
Lots of documentation tweaks.
Fix some since tags, reword/reformat various things. Add some links. Make it nicer.
This commit is contained in:
parent
83cb670051
commit
c36a8b082f
@ -9,46 +9,76 @@ import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* An immutable map from config paths to config values.
|
||||
*
|
||||
* An immutable map from config paths to config values. Paths are dot-separated
|
||||
* expressions such as <code>foo.bar.baz</code>. Values are as in JSON
|
||||
* (booleans, strings, numbers, lists, or objects), represented by
|
||||
* {@link ConfigValue} instances. Values accessed through the
|
||||
* <code>Config</code> interface are never null.
|
||||
*
|
||||
* <p>
|
||||
* Contrast with {@link ConfigObject} which is a map from config <em>keys</em>,
|
||||
* rather than paths, to config values. A {@code Config} contains a tree of
|
||||
* {@code ConfigObject}, and {@link Config#root()} returns the tree's root
|
||||
* object.
|
||||
*
|
||||
* {@code Config} is an immutable object and thus safe to use from multiple
|
||||
* threads. There's never a need for "defensive copies."
|
||||
*
|
||||
* <p>
|
||||
* 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. Path expressions are described in the <a
|
||||
* Fundamental operations on a {@code Config} include getting configuration
|
||||
* values, <em>resolving</em> substitutions with {@link Config#resolve()}, and
|
||||
* merging configs using {@link Config#withFallback(ConfigMergeable)}.
|
||||
*
|
||||
* <p>
|
||||
* All operations return a new immutable {@code Config} rather than modifying
|
||||
* the original instance.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Examples</strong>
|
||||
*
|
||||
* <p>
|
||||
* You can find an example app and library <a
|
||||
* href="https://github.com/typesafehub/config/tree/master/examples">on
|
||||
* GitHub</a>. Also be sure to read the <a
|
||||
* href="package-summary.html#package_description">package overview</a> which
|
||||
* describes the big picture as shown in those examples.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Paths, keys, and Config vs. ConfigObject</strong>
|
||||
*
|
||||
* <p>
|
||||
* <code>Config</code> is a view onto a tree of {@link ConfigObject}; the
|
||||
* corresponding object tree can be found through {@link Config#root()}.
|
||||
* <code>ConfigObject</code> is a map from config <em>keys</em>, rather than
|
||||
* paths, to config values. Think of <code>ConfigObject</code> as a JSON object
|
||||
* and <code>Config</code> as a configuration API.
|
||||
*
|
||||
* <p>
|
||||
* 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 <a
|
||||
* href="https://github.com/typesafehub/config/blob/master/HOCON.md">spec for
|
||||
* Human-Optimized Config Object Notation</a>. 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.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* The API for a {@code Config} is in terms of path expressions, while the API
|
||||
* for a {@code ConfigObject} is in terms of keys. Conceptually, {@code Config}
|
||||
* is a one-level map from <em>paths</em> to values, while a
|
||||
* {@code ConfigObject} is a tree of nested maps from <em>keys</em> to values.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
|
||||
* between path expressions and individual path elements (keys).
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Another difference between {@code Config} and {@code ConfigObject} is that
|
||||
* conceptually, {@code ConfigValue}s with a {@link ConfigValue#valueType()
|
||||
* valueType()} of {@link ConfigValueType#NULL NULL} exist in a
|
||||
* {@code ConfigObject}, while a {@code Config} treats null values as if they
|
||||
* were missing.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* {@code Config} is an immutable object and thus safe to use from multiple
|
||||
* threads. There's never a need for "defensive copies."
|
||||
*
|
||||
* <strong>Getting configuration values</strong>
|
||||
*
|
||||
* <p>
|
||||
* The "getters" on a {@code Config} all work in the same way. They never return
|
||||
* null, nor do they return a {@code ConfigValue} with
|
||||
@ -59,25 +89,49 @@ import java.util.concurrent.TimeUnit;
|
||||
* thrown. {@link 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.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* <strong>Iteration</strong>
|
||||
*
|
||||
* <p>
|
||||
* If you want to iterate over the contents of a {@code Config}, you can get its
|
||||
* {@code ConfigObject} with {@link #root()}, and then iterate over the
|
||||
* {@code ConfigObject} (which implements <code>java.util.Map</code>). Or, you
|
||||
* can use {@link #entrySet()} which recurses the object tree for you and builds
|
||||
* up a <code>Set</code> of all path-value pairs where the value is not null.
|
||||
*
|
||||
* <p>Before using a {@code Config} it's necessary to call {@link Config#resolve()}
|
||||
* to handle substitutions (though {@link ConfigFactory#load()} and similar methods
|
||||
* will do the resolve for you already).
|
||||
*
|
||||
* <p> You can find an example app and library <a
|
||||
* href="https://github.com/typesafehub/config/tree/master/examples">on
|
||||
* GitHub</a>. Also be sure to read the <a
|
||||
* href="package-summary.html#package_description">package
|
||||
* overview</a> which describes the big picture as shown in those
|
||||
* examples.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* <strong>Resolving substitutions</strong>
|
||||
*
|
||||
* <p>
|
||||
* <em>Substitutions</em> are the <code>${foo.bar}</code> syntax in config
|
||||
* files, described in the <a href=
|
||||
* "https://github.com/typesafehub/config/blob/master/HOCON.md#substitutions"
|
||||
* >here</a>. Resolving substitutions replaces these references with real
|
||||
* values.
|
||||
*
|
||||
* <p>
|
||||
* Before using a {@code Config} it's necessary to call {@link Config#resolve()}
|
||||
* to handle substitutions (though {@link ConfigFactory#load()} and similar
|
||||
* methods will do the resolve for you already).
|
||||
*
|
||||
* <p>
|
||||
* <strong>Merging</strong>
|
||||
*
|
||||
* <p>
|
||||
* The full <code>Config</code> for your application can be constructed using
|
||||
* the associative operation {@link Config#withFallback(ConfigMergeable)}. If
|
||||
* you use {@link ConfigFactory#load()} (recommended), it merges system
|
||||
* properties over the top of <code>application.conf</code> over the top of
|
||||
* <code>reference.conf</code>, using <code>withFallback</code>. You can add in
|
||||
* additional sources of configuration in the same way (usually, custom layers
|
||||
* should go either just above or just below <code>application.conf</code>,
|
||||
* keeping <code>reference.conf</code> at the bottom and system properties at
|
||||
* the top).
|
||||
*
|
||||
* <p>
|
||||
* <strong>This is an interface but don't implement it yourself</strong>
|
||||
*
|
||||
* <p>
|
||||
* <em>Do not implement {@code Config}</em>; it should only be implemented by
|
||||
* the config library. Arbitrary implementations will not work because the
|
||||
@ -114,19 +168,20 @@ public interface Config extends ConfigMergeable {
|
||||
* <code>Config</code> as the root object, that is, a substitution
|
||||
* <code>${foo.bar}</code> will be replaced with the result of
|
||||
* <code>getValue("foo.bar")</code>.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* This method uses {@link ConfigResolveOptions#defaults()}, there is
|
||||
* another variant {@link Config#resolve(ConfigResolveOptions)} which lets
|
||||
* you specify non-default options.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* A given {@link Config} must be resolved before using it to retrieve
|
||||
* config values, but ideally should be resolved one time for your entire
|
||||
* stack of fallbacks (see {@link Config#withFallback}). Otherwise, some
|
||||
* substitutions that could have resolved with all fallbacks available may
|
||||
* not resolve, which will be a user-visible oddity.
|
||||
*
|
||||
* not resolve, which will be potentially confusing for your application's
|
||||
* users.
|
||||
*
|
||||
* <p>
|
||||
* <code>resolve()</code> should be invoked on root config objects, rather
|
||||
* than on a subtree (a subtree is the result of something like
|
||||
@ -136,24 +191,24 @@ public interface Config extends ConfigMergeable {
|
||||
* from the root. For example, if you did
|
||||
* <code>config.getConfig("foo").resolve()</code> on the below config file,
|
||||
* it would not work:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* common-value = 10
|
||||
* foo {
|
||||
* whatever = ${common-value}
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Many methods on {@link ConfigFactory} such as {@link
|
||||
* ConfigFactory#load()} automatically resolve the loaded
|
||||
* Many methods on {@link ConfigFactory} such as
|
||||
* {@link ConfigFactory#load()} automatically resolve the loaded
|
||||
* <code>Config</code> on the loaded stack of config files.
|
||||
*
|
||||
* <p> Resolving an already-resolved config is a harmless
|
||||
* no-op, but again, it is best to resolve an entire stack of
|
||||
* fallbacks (such as all your config files combined) rather
|
||||
* than resolving each one individually.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Resolving an already-resolved config is a harmless no-op, but again, it
|
||||
* is best to resolve an entire stack of fallbacks (such as all your config
|
||||
* files combined) rather than resolving each one individually.
|
||||
*
|
||||
* @return an immutable object with substitutions resolved
|
||||
* @throws ConfigException.UnresolvedSubstitution
|
||||
* if any substitutions refer to nonexistent paths
|
||||
@ -173,14 +228,17 @@ public interface Config extends ConfigMergeable {
|
||||
Config resolve(ConfigResolveOptions options);
|
||||
|
||||
/**
|
||||
* Checks whether the config is completely resolved. After a successful call to
|
||||
* {@link Config#resolve()} it will be completely resolved, but after calling
|
||||
* {@link Config#resolve(ConfigResolveOptions)} with <code>allowUnresolved</code> set
|
||||
* in the options, it may or may not be completely resolved. A newly-loaded config
|
||||
* may or may not be completely resolved depending on whether there were substitutions
|
||||
* present in the file.
|
||||
*
|
||||
* @return true if there are no unresolved substitutions remaining in this configuration.
|
||||
* Checks whether the config is completely resolved. After a successful call
|
||||
* to {@link Config#resolve()} it will be completely resolved, but after
|
||||
* calling {@link Config#resolve(ConfigResolveOptions)} with
|
||||
* <code>allowUnresolved</code> set in the options, it may or may not be
|
||||
* completely resolved. A newly-loaded config may or may not be completely
|
||||
* resolved depending on whether there were substitutions present in the
|
||||
* file.
|
||||
*
|
||||
* @return true if there are no unresolved substitutions remaining in this
|
||||
* configuration.
|
||||
* @since 1.2.0
|
||||
*/
|
||||
boolean isResolved();
|
||||
|
||||
@ -208,6 +266,7 @@ public interface Config extends ConfigMergeable {
|
||||
* source
|
||||
* @throws ConfigException
|
||||
* some other config exception if there are other problems
|
||||
* @since 1.2.0
|
||||
*/
|
||||
Config resolveWith(Config source);
|
||||
|
||||
@ -221,6 +280,7 @@ public interface Config extends ConfigMergeable {
|
||||
* resolve options
|
||||
* @return the resolved <code>Config</code> (may be only partially resolved
|
||||
* if options are set to allow unresolved)
|
||||
* @since 1.2.0
|
||||
*/
|
||||
Config resolveWith(Config source, ConfigResolveOptions options);
|
||||
|
||||
@ -536,7 +596,7 @@ public interface Config extends ConfigMergeable {
|
||||
* href="https://github.com/typesafehub/config/blob/master/HOCON.md">the
|
||||
* spec</a>.
|
||||
*
|
||||
* @since 1.1
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param path
|
||||
* path expression
|
||||
@ -600,8 +660,8 @@ public interface Config extends ConfigMergeable {
|
||||
/**
|
||||
* Gets a list, converting each value in the list to a duration, using the
|
||||
* same rules as {@link #getDuration(String, TimeUnit)}.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @param path
|
||||
* a path expression
|
||||
* @param unit
|
||||
|
@ -19,43 +19,52 @@ package com.typesafe.config;
|
||||
public interface ConfigMergeable {
|
||||
/**
|
||||
* Returns a new value computed by merging this value with another, with
|
||||
* keys in this value "winning" over the other one. Only
|
||||
* {@link ConfigObject} and {@link Config} instances do anything in this
|
||||
* method (they need to merge the fallback keys into themselves). All other
|
||||
* values just return the original value, since they automatically override
|
||||
* any fallback.
|
||||
* keys in this value "winning" over the other one.
|
||||
*
|
||||
* <p> The semantics of merging are described in the <a
|
||||
* <p>
|
||||
* This associative operation may be used to combine configurations from
|
||||
* multiple sources (such as multiple configuration files).
|
||||
*
|
||||
* <p>
|
||||
* The semantics of merging are described in the <a
|
||||
* href="https://github.com/typesafehub/config/blob/master/HOCON.md">spec
|
||||
* for HOCON</a>. Merging typically occurs when either the
|
||||
* same object is created twice in the same file, or two
|
||||
* config files are both loaded. For example:
|
||||
* for HOCON</a>. Merging typically occurs when either the same object is
|
||||
* created twice in the same file, or two config files are both loaded. For
|
||||
* example:
|
||||
*
|
||||
* <pre>
|
||||
* foo = { a: 42 }
|
||||
* foo = { b: 43 }
|
||||
* </pre>
|
||||
*
|
||||
* Here, the two objects are merged as if you had written:
|
||||
*
|
||||
* <pre>
|
||||
* foo = { a: 42, b: 43 }
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Note that objects do not merge "across" non-objects; if you write
|
||||
* Only {@link ConfigObject} and {@link Config} instances do anything in
|
||||
* this method (they need to merge the fallback keys into themselves). All
|
||||
* other values just return the original value, since they automatically
|
||||
* override any fallback. This means that objects do not merge "across"
|
||||
* non-objects; if you write
|
||||
* <code>object.withFallback(nonObject).withFallback(otherObject)</code>,
|
||||
* then <code>otherObject</code> will simply be ignored. This is an
|
||||
* intentional part of how merging works, because non-objects such as
|
||||
* strings and integers replace (rather than merging with) any
|
||||
* prior value:
|
||||
* strings and integers replace (rather than merging with) any prior value:
|
||||
*
|
||||
* <pre>
|
||||
* foo = { a: 42 }
|
||||
* foo = 10
|
||||
* </pre>
|
||||
*
|
||||
* Here, the number 10 "wins" and the value of <code>foo</code> would be
|
||||
* simply 10. Again, for details see the spec.
|
||||
*
|
||||
*
|
||||
* @param other
|
||||
* an object whose keys should be used if the keys are not
|
||||
* present in this one
|
||||
* an object whose keys should be used as fallbacks, if the keys
|
||||
* are not present in this one
|
||||
* @return a new object (or the original one, if the fallback doesn't get
|
||||
* used)
|
||||
*/
|
||||
|
@ -6,53 +6,58 @@ package com.typesafe.config;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Subtype of {@link ConfigValue} representing an object (dictionary, map)
|
||||
* value, as in JSON's <code>{ "a" : 42 }</code> syntax.
|
||||
*
|
||||
* Subtype of {@link ConfigValue} representing an object (AKA dictionary or map)
|
||||
* value, as in JSON's curly brace <code>{ "a" : 42 }</code> syntax.
|
||||
*
|
||||
* <p>
|
||||
* An object may also be viewed as a {@link Config} by calling
|
||||
* {@link ConfigObject#toConfig()}.
|
||||
*
|
||||
* <p>
|
||||
* {@code ConfigObject} implements {@code java.util.Map<String, ConfigValue>} so
|
||||
* you can use it like a regular Java map. Or call {@link #unwrapped()} to
|
||||
* unwrap the map to a map with plain Java values rather than
|
||||
* {@code ConfigValue}.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Like all {@link ConfigValue} subtypes, {@code ConfigObject} is immutable.
|
||||
* This makes it threadsafe and you never have to create "defensive copies." The
|
||||
* mutator methods from {@link java.util.Map} all throw
|
||||
* {@link java.lang.UnsupportedOperationException}.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* The {@link ConfigValue#valueType} method on an object returns
|
||||
* {@link ConfigValueType#OBJECT}.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* In most cases you want to use the {@link Config} interface rather than this
|
||||
* one. Call {@link #toConfig()} to convert a {@code ConfigObject} to a
|
||||
* {@code Config}.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* The API for a {@code ConfigObject} is in terms of keys, while the API for a
|
||||
* {@link Config} is in terms of path expressions. Conceptually,
|
||||
* {@code ConfigObject} is a tree of maps from keys to values, while a
|
||||
* {@code Config} is a one-level map from paths to values.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
|
||||
* between path expressions and individual path elements (keys).
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* A {@code ConfigObject} may contain null values, which will have
|
||||
* {@link ConfigValue#valueType()} equal to {@link ConfigValueType#NULL}. If
|
||||
* {@code get()} returns Java's null then the key was not present in the parsed
|
||||
* file (or wherever this value tree came from). If {@code get()} returns a
|
||||
* {@link ConfigValue} with type {@code ConfigValueType#NULL} then the key was
|
||||
* set to null explicitly in the config file.
|
||||
*
|
||||
* {@link ConfigObject#get(Object)} returns Java's null then the key was not
|
||||
* present in the parsed file (or wherever this value tree came from). If
|
||||
* {@code get("key")} returns a {@link ConfigValue} with type
|
||||
* {@code ConfigValueType#NULL} then the key was set to null explicitly in the
|
||||
* config file.
|
||||
*
|
||||
* <p>
|
||||
* <em>Do not implement {@code ConfigObject}</em>; 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
|
||||
* <em>Do not implement interface {@code ConfigObject}</em>; 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.
|
||||
*/
|
||||
public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
|
||||
@ -82,11 +87,11 @@ public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
|
||||
* Gets a {@link ConfigValue} at the given key, or returns null if there is
|
||||
* no value. The returned {@link ConfigValue} may have
|
||||
* {@link ConfigValueType#NULL} or any other type, and the passed-in key
|
||||
* must be a key in this object, rather than a path expression.
|
||||
*
|
||||
* must be a key in this object (rather than a path expression).
|
||||
*
|
||||
* @param key
|
||||
* key to look up
|
||||
*
|
||||
*
|
||||
* @return the value at the key or null if none
|
||||
*/
|
||||
@Override
|
||||
@ -115,7 +120,7 @@ public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
|
||||
* Returns a {@code ConfigObject} based on this one, but with the given key
|
||||
* set to the given value. Does not modify this instance (since it's
|
||||
* immutable). If the key already has a value, that value is replaced. To
|
||||
* remove a value, use withoutKey().
|
||||
* remove a value, use {@link ConfigObject#withoutKey(String)}.
|
||||
*
|
||||
* @param key
|
||||
* key to add
|
||||
|
@ -88,6 +88,7 @@ public final class ConfigResolveOptions {
|
||||
* @param value
|
||||
* true to silently ignore unresolved substitutions.
|
||||
* @return options with requested setting for whether to allow substitutions
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public ConfigResolveOptions setAllowUnresolved(boolean value) {
|
||||
return new ConfigResolveOptions(useSystemEnvironment, value);
|
||||
@ -98,6 +99,7 @@ public final class ConfigResolveOptions {
|
||||
* is mostly used by the config lib internally, not by applications.
|
||||
*
|
||||
* @return true if unresolved substitutions are allowed
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public boolean getAllowUnresolved() {
|
||||
return allowUnresolved;
|
||||
|
@ -4,29 +4,33 @@
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
* The syntax of a character stream, <a href="http://json.org">JSON</a>, <a
|
||||
* The syntax of a character stream (<a href="http://json.org">JSON</a>, <a
|
||||
* href="https://github.com/typesafehub/config/blob/master/HOCON.md">HOCON</a>
|
||||
* aka ".conf", or <a href=
|
||||
* "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
|
||||
* >Java properties</a>.
|
||||
*
|
||||
* >Java properties</a>).
|
||||
*
|
||||
*/
|
||||
public enum ConfigSyntax {
|
||||
/**
|
||||
* Pedantically strict <a href="http://json.org">JSON</a> format; no
|
||||
* comments, no unexpected commas, no duplicate keys in the same object.
|
||||
* Associated with the <code>.json</code> file extension and
|
||||
* <code>application/json</code> Content-Type.
|
||||
*/
|
||||
JSON,
|
||||
/**
|
||||
* The JSON-superset <a
|
||||
* href="https://github.com/typesafehub/config/blob/master/HOCON.md"
|
||||
* >HOCON</a> format.
|
||||
* >HOCON</a> format. Associated with the <code>.conf</code> file extension
|
||||
* and <code>application/hocon</code> Content-Type.
|
||||
*/
|
||||
CONF,
|
||||
/**
|
||||
* Standard <a href=
|
||||
* "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
|
||||
* >Java properties</a> format.
|
||||
* >Java properties</a> format. Associated with the <code>.properties</code>
|
||||
* file extension and <code>text/x-java-properties</code> Content-Type.
|
||||
*/
|
||||
PROPERTIES;
|
||||
}
|
||||
|
@ -6,16 +6,16 @@ package com.typesafe.config;
|
||||
/**
|
||||
* An immutable value, following the <a href="http://json.org">JSON</a> type
|
||||
* schema.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Because this object is immutable, it is safe to use from multiple threads and
|
||||
* there's no need for "defensive copies."
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* <em>Do not implement {@code ConfigValue}</em>; 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
|
||||
* <em>Do not implement interface {@code ConfigValue}</em>; 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.
|
||||
*/
|
||||
public interface ConfigValue extends ConfigMergeable {
|
||||
@ -47,36 +47,36 @@ public interface ConfigValue extends ConfigMergeable {
|
||||
* Renders the config value as a HOCON string. This method is primarily
|
||||
* intended for debugging, so it tries to add helpful comments and
|
||||
* whitespace.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* If the config value has not been resolved (see {@link Config#resolve}),
|
||||
* it's possible that it can't be rendered as valid HOCON. In that case the
|
||||
* rendering should still be useful for debugging but you might not be able
|
||||
* to parse it.
|
||||
*
|
||||
* to parse it. If the value has been resolved, it will always be parseable.
|
||||
*
|
||||
* <p>
|
||||
* This method is equivalent to
|
||||
* {@code render(ConfigRenderOptions.defaults())}.
|
||||
*
|
||||
*
|
||||
* @return the rendered value
|
||||
*/
|
||||
String render();
|
||||
|
||||
/**
|
||||
* Renders the config value to a string, using the provided options.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* If the config value has not been resolved (see {@link Config#resolve}),
|
||||
* it's possible that it can't be rendered as valid HOCON. In that case the
|
||||
* rendering should still be useful for debugging but you might not be able
|
||||
* to parse it.
|
||||
*
|
||||
* to parse it. If the value has been resolved, it will always be parseable.
|
||||
*
|
||||
* <p>
|
||||
* If the config value has been resolved and the options disable all
|
||||
* HOCON-specific features (such as comments), the rendering will be valid
|
||||
* JSON. If you enable HOCON-only features such as comments, the rendering
|
||||
* will not be valid JSON.
|
||||
*
|
||||
*
|
||||
* @param options
|
||||
* the rendering options
|
||||
* @return the rendered value
|
||||
@ -87,9 +87,9 @@ public interface ConfigValue extends ConfigMergeable {
|
||||
ConfigValue withFallback(ConfigMergeable other);
|
||||
|
||||
/**
|
||||
* Places the value inside a {@code Config} at the given path. See also
|
||||
* atKey().
|
||||
*
|
||||
* Places the value inside a {@link Config} at the given path. See also
|
||||
* {@link ConfigValue#atKey(String)}.
|
||||
*
|
||||
* @param path
|
||||
* path to store this value at.
|
||||
* @return a {@code Config} instance containing this value at the given
|
||||
@ -98,9 +98,9 @@ public interface ConfigValue extends ConfigMergeable {
|
||||
Config atPath(String path);
|
||||
|
||||
/**
|
||||
* Places the value inside a {@code Config} at the given key. See also
|
||||
* atPath().
|
||||
*
|
||||
* Places the value inside a {@link Config} at the given key. See also
|
||||
* {@link ConfigValue#atPath(String)}.
|
||||
*
|
||||
* @param key
|
||||
* key to store this value at.
|
||||
* @return a {@code Config} instance containing this value at the given key.
|
||||
|
@ -17,40 +17,45 @@ public final class ConfigValueFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ConfigValue from a plain Java boxed value, which may be a
|
||||
* Boolean, Number, String, Map, Iterable, or null. A Map must be a Map from
|
||||
* String to more values that can be supplied to fromAnyRef(). An Iterable
|
||||
* must iterate over more values that can be supplied to fromAnyRef(). A Map
|
||||
* will become a ConfigObject and an Iterable will become a ConfigList. If
|
||||
* the Iterable is not an ordered collection, results could be strange,
|
||||
* since ConfigList is ordered.
|
||||
*
|
||||
* Creates a {@link ConfigValue} from a plain Java boxed value, which may be
|
||||
* a <code>Boolean</code>, <code>Number</code>, <code>String</code>,
|
||||
* <code>Map</code>, <code>Iterable</code>, or <code>null</code>. A
|
||||
* <code>Map</code> must be a <code>Map</code> from String to more values
|
||||
* that can be supplied to <code>fromAnyRef()</code>. An
|
||||
* <code>Iterable</code> must iterate over more values that can be supplied
|
||||
* to <code>fromAnyRef()</code>. A <code>Map</code> will become a
|
||||
* {@link ConfigObject} and an <code>Iterable</code> will become a
|
||||
* {@link ConfigList}. If the <code>Iterable</code> is not an ordered
|
||||
* collection, results could be strange, since <code>ConfigList</code> is
|
||||
* ordered.
|
||||
*
|
||||
* <p>
|
||||
* 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".
|
||||
*
|
||||
* In a <code>Map</code> passed to <code>fromAnyRef()</code>, the map's keys
|
||||
* are plain keys, not path expressions. So if your <code>Map</code> 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".
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
* from, or something short describing the value such as "default settings".
|
||||
* The originDescription is prefixed to error messages so users can tell
|
||||
* where problematic values are coming from.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Supplying the result of ConfigValue.unwrapped() to this function is
|
||||
* guaranteed to work and should give you back a ConfigValue that matches
|
||||
* the one you unwrapped. The re-wrapped ConfigValue will lose some
|
||||
* information that was present in the original such as its origin, but it
|
||||
* will have matching values.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
* should never handle the exception. Just fix your program (or report a bug
|
||||
* against this library).
|
||||
*
|
||||
*
|
||||
* @param object
|
||||
* object to convert to ConfigValue
|
||||
* @param originDescription
|
||||
@ -62,23 +67,24 @@ public final class ConfigValueFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* See the fromAnyRef() documentation for details. This is a typesafe
|
||||
* wrapper that only works on {@link java.util.Map} and returns
|
||||
* {@link ConfigObject} rather than {@link ConfigValue}.
|
||||
*
|
||||
* See the {@link #fromAnyRef(Object,String)} documentation for details.
|
||||
* This is a typesafe wrapper that only works on {@link java.util.Map} and
|
||||
* returns {@link ConfigObject} rather than {@link ConfigValue}.
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
* {@code ConfigObject}. The keys will not be parsed or modified, and the
|
||||
* values are wrapped in ConfigValue. To get nested {@code ConfigObject},
|
||||
* some of the values in the map would have to be more maps.
|
||||
*
|
||||
* If your <code>Map</code> 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 <code>Map</code> corresponds exactly
|
||||
* to a single {@code ConfigObject}. The keys will not be parsed or
|
||||
* modified, and the values are wrapped in ConfigValue. To get nested
|
||||
* {@code ConfigObject}, some of the values in the map would have to be more
|
||||
* maps.
|
||||
*
|
||||
* <p>
|
||||
* See also {@link ConfigFactory#parseMap(Map,String)} which interprets the
|
||||
* keys in the map as path expressions.
|
||||
*
|
||||
*
|
||||
* @param values
|
||||
* @param originDescription
|
||||
* @return a new {@link ConfigObject} value
|
||||
@ -89,10 +95,10 @@ public final class ConfigValueFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* See the fromAnyRef() documentation for details. This is a typesafe
|
||||
* wrapper that only works on {@link java.lang.Iterable} and returns
|
||||
* {@link ConfigList} rather than {@link ConfigValue}.
|
||||
*
|
||||
* See the {@link #fromAnyRef(Object,String)} documentation for details.
|
||||
* This is a typesafe wrapper that only works on {@link java.lang.Iterable}
|
||||
* and returns {@link ConfigList} rather than {@link ConfigValue}.
|
||||
*
|
||||
* @param values
|
||||
* @param originDescription
|
||||
* @return a new {@link ConfigList} value
|
||||
|
@ -15,7 +15,9 @@ for more information.
|
||||
|
||||
<p>
|
||||
Typically you would load configuration with a static method from {@link com.typesafe.config.ConfigFactory} and then use
|
||||
it with methods in the {@link com.typesafe.config.Config} interface.
|
||||
it with methods in the {@link com.typesafe.config.Config} interface. Configuration may be in the form of JSON files,
|
||||
Java properties, or <a href="https://github.com/typesafehub/config/blob/master/HOCON.md">HOCON files</a>; you may also
|
||||
build your own configuration in code or from your own file formats.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -24,6 +26,8 @@ its configuration in "application.conf" on the classpath.
|
||||
If you use the default configuration from {@link com.typesafe.config.ConfigFactory#load()}
|
||||
there's no need to pass a configuration to your libraries
|
||||
and frameworks, as long as they all default to this same default, which they should.
|
||||
<br/><strong>Example application code:</strong> <a href="https://github.com/typesafehub/config/tree/master/examples/java/simple-app/src/main">Java</a> and <a href="https://github.com/typesafehub/config/tree/master/examples/scala/simple-app/src/main">Scala</a>.
|
||||
<br/>Showing a couple of more special-purpose features, <strong>a more complex example:</strong> <a href="https://github.com/typesafehub/config/tree/master/examples/java/complex-app/src/main">Java</a> and <a href="https://github.com/typesafehub/config/tree/master/examples/scala/complex-app/src/main">Scala</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -32,10 +36,22 @@ A library or framework should ship a file "reference.conf" in its jar, and allow
|
||||
call {@link com.typesafe.config.ConfigFactory#load()}
|
||||
to get the default one. Typically a library might offer two constructors, one with a <code>Config</code> parameter
|
||||
and one which uses {@link com.typesafe.config.ConfigFactory#load()}.
|
||||
<br/><strong>Example library code:</strong> <a href="https://github.com/typesafehub/config/tree/master/examples/java/simple-lib/src/main">Java</a> and <a href="https://github.com/typesafehub/config/tree/master/examples/scala/simple-lib/src/main">Scala</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You can find an example app and library <a href="https://github.com/typesafehub/config/tree/master/examples">on GitHub</a>.
|
||||
Check out the full <a href="https://github.com/typesafehub/config/tree/master/examples">examples directory on GitHub</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
What else to read:
|
||||
<ul>
|
||||
<li>The overview documentation for interface {@link com.typesafe.config.Config}.</li>
|
||||
<li>The <a href="https://github.com/typesafehub/config/blob/master/README.md">README</a> for the library.</li>
|
||||
<li>If you want to use <code>.conf</code> files in addition to <code>.json</code> and <code>.properties</code>,
|
||||
see the <a href="https://github.com/typesafehub/config/blob/master/README.md">README</a> for some short examples
|
||||
and the full <a href="https://github.com/typesafehub/config/blob/master/HOCON.md">HOCON spec</a> for the long version.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user