Clean up the javadocs.

This commit is contained in:
Havoc Pennington 2011-11-21 11:36:58 -05:00
parent 554461eabb
commit d9cac206e1
17 changed files with 515 additions and 188 deletions

View File

@ -6,51 +6,82 @@ package com.typesafe.config;
import java.util.List;
/**
* This class represents an immutable map from config paths to config values. It
* also contains some static methods for creating configs.
* An immutable map from config paths to config values.
*
* <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#toObject()} returns the tree's root
* object.
*
* <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 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.
* keys. Path expressions are described in the <a
* href="https://github.com/havocp/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.
*
* 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 maps from keys to
* values.
* <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.
*
* Another difference between Config and ConfigObject is that conceptually,
* ConfigValue with valueType() of ConfigValueType.NULL exist in a ConfigObject,
* while a Config treats null values as if they were missing.
* <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.
*
* Config is an immutable object and thus safe to use from multiple threads.
* <p>
* {@code Config} is an immutable object and thus safe to use from multiple
* threads. There's never a need for "defensive copies."
*
* The "getters" on a Config all work in the same way. They never return null,
* nor do they return a ConfigValue with valueType() of ConfigValueType.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.
* <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
* {@link ConfigValue#valueType() valueType()} of {@link ConfigValueType#NULL
* NULL}. Instead, they throw {@link ConfigException.Missing} if the value is
* completely absent or set to null. If the value is set to null, a subtype of
* {@code ConfigException.Missing} called {@link ConfigException.Null} will be
* 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.
*
* If you want to iterate over the contents of a Config, you have to get its
* ConfigObject with toObject, and then iterate over the ConfigObject.
* <p>
* If you want to iterate over the contents of a {@code Config}, you have to get
* its {@code ConfigObject} with {@link #toObject()}, and then iterate over the
* {@code ConfigObject}.
*
*
* <p>
* <em>Do not implement {@code Config}</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 Config extends ConfigMergeable {
/**
* Gets the config as a tree of ConfigObject. This is a constant-time
* operation (it is not proportional to the number of values in the Config).
* Gets the {@code Config} as a tree of {@link ConfigObject}. This is a
* constant-time operation (it is not proportional to the number of values
* in the {@code Config}).
*
* @return
* @return the root object in the configuration
*/
ConfigObject toObject();
/**
* Gets the origin of the {@code Config}, which may be a file, or a file
* with a line number, or just a descriptive phrase.
*
* @return the origin of the {@code Config} for use in error messages
*/
ConfigOrigin origin();
@Override
@ -61,14 +92,16 @@ public interface Config extends ConfigMergeable {
/**
* Checks whether a value is present and non-null at the given path. This
* differs in two ways from ConfigObject.containsKey(): it looks for a path
* expression, not a key; and it returns false for null values, while
* containsKey() returns true indicating that the object contains a null
* value for the key.
* differs in two ways from {@code Map.containsKey()} as implemented by
* {@link ConfigObject}: it looks for a path expression, not a key; and it
* returns false for null values, while {@code containsKey()} returns true
* indicating that the object contains a null value for the key.
*
* If a path exists according to hasPath(), then getValue() will never throw
* an exception. However, the typed getters, such as getInt(), will still
* throw if the value is not convertible to the requested type.
* <p>
* If a path exists according to {@link #hasPath(String)}, then
* {@link #getValue(String)} will never throw an exception. However, the
* typed getters, such as {@link #getInt(String)}, will still throw if the
* value is not convertible to the requested type.
*
* @param path
* the path expression
@ -78,12 +111,19 @@ public interface Config extends ConfigMergeable {
*/
boolean hasPath(String path);
/**
* Returns true if the {@code Config}'s root object contains no key-value
* pairs.
*
* @return true if the configuration is empty
*/
boolean isEmpty();
/**
*
* @param path
* @return
* path expression
* @return the boolean value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -93,7 +133,8 @@ public interface Config extends ConfigMergeable {
/**
* @param path
* @return
* path expression
* @return the numeric value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -103,17 +144,20 @@ public interface Config extends ConfigMergeable {
/**
* @param path
* @return
* path expression
* @return the 32-bit integer value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to an int
* if value is not convertible to an int (for example it is out
* of range, or it's a boolean value)
*/
int getInt(String path);
/**
* @param path
* @return
* path expression
* @return the 64-bit long value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -123,7 +167,8 @@ public interface Config extends ConfigMergeable {
/**
* @param path
* @return
* path expression
* @return the floating-point value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -133,7 +178,8 @@ public interface Config extends ConfigMergeable {
/**
* @param path
* @return
* path expression
* @return the string value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -143,7 +189,8 @@ public interface Config extends ConfigMergeable {
/**
* @param path
* @return
* path expression
* @return the {@link ConfigObject} value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -153,7 +200,8 @@ public interface Config extends ConfigMergeable {
/**
* @param path
* @return
* path expression
* @return the nested {@code Config} value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -162,9 +210,13 @@ public interface Config extends ConfigMergeable {
Config getConfig(String path);
/**
* Gets the value at the path as an unwrapped Java boxed value (Boolean,
* Integer, Long, etc.)
*
* Gets the value at the path as an unwrapped Java boxed value (
* {@link java.lang.Boolean Boolean}, {@link java.lang.Integer Integer}, and
* so on - see {@link ConfigValue#unwrapped()}).
*
* @param path
* path expression
* @return the unwrapped value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
*/
@ -172,21 +224,30 @@ public interface Config extends ConfigMergeable {
/**
* Gets the value at the given path, unless the value is a null value or
* missing, in which case it throws just like the other getters. Use get()
* from the Map interface if you want an unprocessed value.
* missing, in which case it throws just like the other getters. Use
* {@code get()} from the {@link java.util.Map Map} interface if you want an
* unprocessed value.
*
* @param path
* @return
* path expression
* @return the value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
*/
ConfigValue getValue(String path);
/**
* Get value as a size in bytes (parses special strings like "128M"). The
* Gets a value as a size in bytes (parses special strings like "128M"). The
* size units are interpreted as for memory, not as for disk space, so they
* are in powers of two.
* are in powers of two. If the value is already a number, then it's left
* alone; if it's a string, it's parsed understanding unit suffixes such as
* "128K", as documented in the <a
* href="https://github.com/havocp/config/blob/master/HOCON.md">the
* spec</a>.
*
* @param path
* path expression
* @return the memory size value at the requested path, in bytes
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -199,8 +260,13 @@ public interface Config extends ConfigMergeable {
/**
* Get value as a duration in milliseconds. If the value is already a
* number, then it's left alone; if it's a string, it's parsed understanding
* units suffixes like "10m" or "5ns"
* units suffixes like "10m" or "5ns" as documented in the <a
* href="https://github.com/havocp/config/blob/master/HOCON.md">the
* spec</a>.
*
* @param path
* path expression
* @return the duration value at the requested path, in milliseconds
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -213,8 +279,12 @@ public interface Config extends ConfigMergeable {
/**
* Get value as a duration in nanoseconds. If the value is already a number
* it's taken as milliseconds and converted to nanoseconds. If it's a
* string, it's parsed understanding unit suffixes.
* string, it's parsed understanding unit suffixes, as for
* {@link #getMilliseconds(String)}.
*
* @param path
* path expression
* @return the duration value at the requested path, in nanoseconds
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
@ -225,13 +295,13 @@ public interface Config extends ConfigMergeable {
Long getNanoseconds(String path);
/**
* Gets a list value (with any element type) as a ConfigList, which
* implements java.util.List<ConfigValue>. Throws if the path is unset or
* null.
* Gets a list value (with any element type) as a {@link ConfigList}, which
* implements {@code java.util.List<ConfigValue>}. Throws if the path is
* unset or null.
*
* @param path
* the path to the list value.
* @return the ConfigList at the path
* @return the {@link ConfigList} at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType

View File

@ -13,12 +13,18 @@ import com.typesafe.config.impl.ConfigImpl;
import com.typesafe.config.impl.Parseable;
/**
* This class contains static methods for creating Config objects.
* Contains static methods for creating {@link Config} instances.
*
* <p>
* See also {@link ConfigValueFactory} which contains static methods for
* converting Java values into a {@link ConfigObject}. You can then convert a
* {@code ConfigObject} into a {@code Config} with {@link ConfigObject#toConfig}.
*
* <p>
* 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.
* while the ones with "parse" in the name just create a {@link ConfigValue}
* from a resource and nothing else.
*/
public final class ConfigFactory {
/**
@ -45,7 +51,7 @@ public final class ConfigFactory {
*
* @param rootPath
* the configuration "domain"
* @return configuration object for the requested root path
* @return configuration for the requested root path
*/
public static ConfigRoot load(String rootPath) {
return loadWithoutResolving(rootPath).resolve();
@ -60,10 +66,10 @@ public final class ConfigFactory {
/**
* Like load() but does not resolve the object, so you can go ahead and add
* more fallbacks and stuff and have them seen by substitutions when you do
* call {@link ConfigRoot.resolve()}.
* call {@link ConfigRoot#resolve}.
*
* @param rootPath
* @return
* @return configuration for the requested root path
*/
public static ConfigRoot loadWithoutResolving(String rootPath) {
return loadWithoutResolving(rootPath, ConfigParseOptions.defaults());
@ -125,7 +131,7 @@ public final class ConfigFactory {
* @param properties
* a Java Properties object
* @param options
* @return
* @return the parsed configuration
*/
public static Config parseProperties(Properties properties,
ConfigParseOptions options) {
@ -155,7 +161,7 @@ public final class ConfigFactory {
*
* @param fileBasename
* @param options
* @return
* @return the parsed configuration
*/
public static Config parseFileAnySyntax(File fileBasename,
ConfigParseOptions options) {
@ -175,7 +181,7 @@ public final class ConfigFactory {
* @param klass
* @param resourceBasename
* @param options
* @return
* @return the parsed configuration
*/
public static Config parseResourceAnySyntax(Class<?> klass, String resourceBasename,
ConfigParseOptions options) {
@ -192,10 +198,10 @@ public final class ConfigFactory {
* Essentially if the path is "foo.bar" then the resources are
* "/foo-bar.conf", "/foo-bar.json", and "/foo-bar.properties". If more than
* one of those exists, they are merged.
*
* @param path
*
* @param rootPath
* @param options
* @return
* @return the parsed configuration
*/
public static Config parseResourcesForPath(String rootPath,
ConfigParseOptions options) {
@ -204,12 +210,15 @@ public final class ConfigFactory {
}
/**
* Similar to ConfigValueFactory.fromMap(), but the keys in the map are path
* expressions, rather than keys; and correspondingly it returns a Config
* instead of a ConfigObject. This is more convenient if you are writing
* literal maps in code, and less convenient if you are getting your maps
* from some data source such as a parser.
* Creates a {@code Config} based on a {@link java.util.Map} from paths to
* plain Java values. Similar to
* {@link ConfigValueFactory#fromMap(Map,String)}, except the keys in the
* map are path expressions, rather than keys; and correspondingly it
* returns a {@code Config} instead of a {@code ConfigObject}. This is more
* convenient if you are writing literal maps in code, and less convenient
* if you are getting your maps from some data source such as a parser.
*
* <p>
* An exception will be thrown (and it is a bug in the caller of the method)
* if a path is both an object and a value, for example if you had both
* "a=foo" and "a.b=bar", then "a" is both the string "foo" and the parent
@ -221,7 +230,7 @@ public final class ConfigFactory {
* description of what this map represents, like a filename, or
* "default settings" (origin description is used in error
* messages)
* @return
* @return the map converted to a {@code Config}
*/
public static Config parseMap(Map<String, ? extends Object> values,
String originDescription) {
@ -229,11 +238,11 @@ public final class ConfigFactory {
}
/**
* See the other overload of parseMap() for details, this one just uses a
* default origin description.
* See the other overload of {@link #parseMap(Map, String)} for details,
* this one just uses a default origin description.
*
* @param values
* @return
* @return the map converted to a {@code Config}
*/
public static Config parseMap(Map<String, ? extends Object> values) {
return parseMap(values, null);

View File

@ -5,8 +5,9 @@ package com.typesafe.config;
/**
* A ConfigIncludeContext is passed to a ConfigIncluder. This interface is not
* intended for apps to implement.
* Context provided to a {@link ConfigIncluder}; this interface is only useful
* inside a {@code ConfigIncluder} implementation, and is not intended for apps
* to implement.
*/
public interface ConfigIncludeContext {
/**
@ -15,7 +16,7 @@ public interface ConfigIncludeContext {
* null if it can't meaningfully create a relative name. The returned
* parseable may not exist; this function is not required to do any IO, just
* compute what the name would be.
*
*
* The passed-in filename has to be a complete name (with extension), not
* just a basename. (Include statements in config files are allowed to give
* just a basename.)

View File

@ -4,8 +4,9 @@
package com.typesafe.config;
/**
* Interface you have to implement to customize "include" statements in config
* files.
* Implement this interface and provide an instance to
* {@link ConfigParseOptions#setIncluder ConfigParseOptions.setIncluder()} to
* customize handling of {@code include} statements in config files.
*/
public interface ConfigIncluder {
/**
@ -29,7 +30,7 @@ public interface ConfigIncluder {
* Parses another item to be included. The returned object typically would
* not have substitutions resolved. You can throw a ConfigException here to
* abort parsing, or return an empty object, but may not return null.
*
*
* @param context
* some info about the include context
* @param what

View File

@ -6,9 +6,30 @@ package com.typesafe.config;
import java.util.List;
/**
* A list (aka array) value corresponding to ConfigValueType.LIST or JSON's
* "[1,2,3]" value. Implements java.util.List<ConfigValue> so you can use it
* like a regular Java list.
* Subtype of {@link ConfigValue} representing a list value, as in JSON's
* {@code [1,2,3]} syntax.
*
* <p>
* {@code ConfigList} implements {@code java.util.List<ConfigValue>} so you can
* use it like a regular Java list. Or call {@link #unwrapped()} to unwrap the
* list elements into plain Java values.
*
* <p>
* Like all {@link ConfigValue} subtypes, {@code ConfigList} is immutable. This
* makes it threadsafe and you never have to create "defensive copies." The
* mutator methods from {@link java.util.List} all throw
* {@link java.lang.UnsupportedOperationException}.
*
* <p>
* The {@link ConfigValue#valueType} method on a list returns
* {@link ConfigValueType#LIST}.
*
* <p>
* <em>Do not implement {@code ConfigList}</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 ConfigList extends List<ConfigValue>, ConfigValue {

View File

@ -4,33 +4,48 @@
package com.typesafe.config;
/**
* This is a marker for types that can be merged as a fallback into a Config or
* a ConfigValue. Both Config and ConfigValue are mergeable.
* Marker for types whose instances can be merged, that is {@link Config} and
* {@link ConfigValue}. Instances of {@code Config} and {@code ConfigValue} can
* be combined into a single new instance using the
* {@link ConfigMergeable#withFallback withFallback()} method.
*
* <p>
* <em>Do not implement this interface</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 ConfigMergeable {
/**
* Converts the mergeable to a ConfigValue to be merged.
*
* @return
* Converts this instance to a {@link ConfigValue}. If called on a
* {@code ConfigValue} it returns {@code this}, if called on a
* {@link Config} it's equivalent to {@link Config#toObject}.
*
* @return this instance as a {@code ConfigValue}
*/
ConfigValue toValue();
/**
* Returns a new value computed by merging this value with another, with
* keys in this value "winning" over the other one. Only ConfigObject and
* 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.
*
* The semantics of merging are described in
* https://github.com/havocp/config/blob/master/HOCON.md
*
* Note that objects do not merge "across" non-objects; if you do
* 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.
*
* <p>
* The semantics of merging are described in the <a
* href="https://github.com/havocp/config/blob/master/HOCON.md">spec for
* HOCON</a>.
*
* <p>
* Note 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. Both non-objects, and any object
* which has fallen back to a non-object, block subsequent fallbacks.
*
*
* @param other
* an object whose keys should be used if the keys are not
* present in this one

View File

@ -6,54 +6,67 @@ package com.typesafe.config;
import java.util.Map;
/**
* A ConfigObject is a read-only configuration object, which may have nested
* child objects. Implementations of ConfigObject should be immutable (at least
* from the perspective of anyone using this interface) and thus thread-safe.
* Subtype of {@link ConfigValue} representing an object (dictionary, map)
* value, as in JSON's <code>{ "a" : 42 }</code> syntax.
*
* In most cases you want to use the Config interface rather than this one. Call
* toConfig() to convert a ConfigObject to a config.
* <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}.
*
* 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 ConfigObject is a one-level map from paths to
* values.
* <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}.
*
* 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.
* <p>
* The {@link ConfigValue#valueType} method on an object returns
* {@link ConfigValueType#OBJECT}.
*
* ConfigObject implements java.util.Map<String,ConfigValue> and all methods
* work with keys, not path expressions.
* <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}.
*
* While ConfigObject implements the standard Java Map interface, the mutator
* methods all throw UnsupportedOperationException. This Map is immutable.
* <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 ConfigObject} is a one-level map from paths to values.
*
* The Map may contain null values, which will have ConfigValue.valueType() ==
* ConfigValueType.NULL. If get() returns Java's null then the key was not
* present in the parsed file (or wherever this value tree came from). If get()
* returns a ConfigValue with type ConfigValueType.NULL then the key was set to
* null explicitly.
* <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.
*
* <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
* implementations will break.
*/
public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
/**
* Converts this object to a Config instance, enabling you to use path
* expressions to find values in the object. This is a constant-time
* Converts this object to a {@link Config} instance, enabling you to use
* path expressions to find values in the object. This is a constant-time
* operation (it is not proportional to the size of the object).
*
* @return
* @return a {@link Config} with this object as its root
*/
Config toConfig();
/**
* Recursively unwraps the object, returning a map from String to whatever
* plain Java values are unwrapped from the object's values.
*
* @return a {@link java.util.Map} containing plain Java objects
*/
@Override
Map<String, Object> unwrapped();
@ -62,10 +75,15 @@ public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
ConfigObject withFallback(ConfigMergeable other);
/**
* Gets a ConfigValue at the given key, or returns null if there is no
* value. The returned ConfigValue may have ConfigValueType.NULL or any
* other type, and the passed-in key must be a key in this object, rather
* than a path expression.
* 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.
*
* @param key
* key to look up
*
* @return the value at the key or null if none
*/
@Override
ConfigValue get(Object key);

View File

@ -4,8 +4,16 @@
package com.typesafe.config;
/**
* ConfigOrigin is used to track the origin (such as filename and line number)
* of a ConfigValue or other object. The origin is used in error messages.
* Represents the origin (such as filename and line number) of a
* {@link ConfigValue} for use in error messages. Obtain the origin of a value
* with {@link ConfigValue#origin}.
*
* <p>
* <em>Do not implement this interface</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 ConfigOrigin {
public String description();

View File

@ -4,6 +4,22 @@
package com.typesafe.config;
/**
* A set of options related to parsing.
*
* <p>
* This object is immutable, so the "setters" return a new object.
*
* <p>
* Here is an example of creating a custom {@code ConfigParseOptions}:
*
* <pre>
* ConfigParseOptions options = ConfigParseOptions.defaults()
* .setSyntax(ConfigSyntax.JSON)
* .setAllowMissing(false)
* </pre>
*
*/
public final class ConfigParseOptions {
final ConfigSyntax syntax;
final String originDescription;
@ -24,10 +40,11 @@ public final class ConfigParseOptions {
/**
* Set the file format. If set to null, try to guess from any available
* filename extension; if guessing fails, assume ConfigSyntax.CONF.
*
* filename extension; if guessing fails, assume {@link ConfigSyntax#CONF}.
*
* @param syntax
* @return
* a syntax or {@code null} for best guess
* @return options with the syntax set
*/
public ConfigParseOptions setSyntax(ConfigSyntax syntax) {
if (this.syntax == syntax)
@ -45,10 +62,11 @@ public final class ConfigParseOptions {
* Set a description for the thing being parsed. In most cases this will be
* set up for you to something like the filename, but if you provide just an
* input stream you might want to improve on it. Set to null to allow the
* library to come up with something automatically.
* library to come up with something automatically. This description is the
* basis for the {@link ConfigOrigin} of the parsed values.
*
* @param originDescription
* @return
* @return options with the origin description set
*/
public ConfigParseOptions setOriginDescription(String originDescription) {
if (this.originDescription == originDescription)
@ -79,7 +97,7 @@ public final class ConfigParseOptions {
* case.
*
* @param allowMissing
* @return
* @return options with the "allow missing" flag set
*/
public ConfigParseOptions setAllowMissing(boolean allowMissing) {
if (this.allowMissing == allowMissing)

View File

@ -5,19 +5,39 @@ package com.typesafe.config;
import java.net.URL;
/** An opaque handle to something that can be parsed. */
/**
* An opaque handle to something that can be parsed, obtained from
* {@link ConfigIncludeContext}.
*
* <p>
* <em>Do not implement this interface</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 ConfigParseable {
/**
* Parse whatever it is.
* Parse whatever it is. The options should come from
* {@link ConfigParseable#options options()} but you could tweak them if you
* like.
*
* @param options
* parse options, should be based on the ones from options()
* parse options, should be based on the ones from
* {@link ConfigParseable#options options()}
*/
ConfigObject parse(ConfigParseOptions options);
/** Possibly return a URL representing the resource; this may return null. */
/**
* Possibly return a URL representing the resource; this may return null if
* the resource has no meaningful URL representation.
*/
URL url();
/** Get the initial options, which can be modified then passed to parse(). */
/**
* Get the initial options, which can be modified then passed to parse().
* These options will have the right description, includer, and other
* parameters already set up.
*/
ConfigParseOptions options();
}

View File

@ -3,6 +3,28 @@
*/
package com.typesafe.config;
/**
* A set of options related to resolving substitutions. Substitutions use the
* <code>${foo.bar}</code> syntax and are documented in the <a
* href="https://github.com/havocp/config/blob/master/HOCON.md">HOCON</a> spec.
*
* <p>
* This object is immutable, so the "setters" return a new object.
*
* <p>
* Here is an example of creating a custom {@code ConfigResolveOptions}:
*
* <pre>
* ConfigResolveOptions options = ConfigResolveOptions.defaults()
* .setUseSystemProperties(false)
* .setUseSystemEnvironment(false)
* </pre>
*
* <p>
* In addition to {@link ConfigResolveOptions#defaults}, there's a prebuilt
* {@link ConfigResolveOptions#noSystem} which avoids looking at any system
* properties or environment variables.
*/
public final class ConfigResolveOptions {
private final boolean useSystemProperties;
private final boolean useSystemEnvironment;
@ -13,26 +35,68 @@ public final class ConfigResolveOptions {
this.useSystemEnvironment = useSystemEnvironment;
}
/**
* Returns the default resolve options.
*
* @return the default resolve options
*/
public static ConfigResolveOptions defaults() {
return new ConfigResolveOptions(true, true);
}
/**
* Returns resolve options that disable any reference to "system" data
* (system properties or environment variables).
*
* @return the resolve options with system properties and env variables
* disabled
*/
public static ConfigResolveOptions noSystem() {
return new ConfigResolveOptions(false, false);
}
/**
* Returns options with use of Java system properties set to the given
* value.
*
* @param value
* true to resolve substitutions falling back to Java system
* properties.
* @return options with requested setting for use of system properties
*/
public ConfigResolveOptions setUseSystemProperties(boolean value) {
return new ConfigResolveOptions(value, useSystemEnvironment);
}
/**
* Returns options with use of environment variables set to the given value.
*
* @param value
* true to resolve substitutions falling back to environment
* variables.
* @return options with requested setting for use of environment variables
*/
public ConfigResolveOptions setUseSystemEnvironment(boolean value) {
return new ConfigResolveOptions(useSystemProperties, value);
}
/**
* Returns whether the options enable use of system properties. This method
* is mostly used by the config lib internally, not by applications.
*
* @return true if system properties should be used
*/
public boolean getUseSystemProperties() {
return useSystemProperties;
}
/**
* Returns whether the options enable use of system environment variables.
* This method is mostly used by the config lib internally, not by
* applications.
*
* @return true if environment variables should be used
*/
public boolean getUseSystemEnvironment() {
return useSystemEnvironment;
}

View File

@ -4,21 +4,36 @@
package com.typesafe.config;
/**
* A root object. The only special thing about a root object is that you can
* resolve substitutions against it. So it can have a resolve() method that
* doesn't require you to pass in an object to resolve against.
* Subtype of {@link Config} which is a root rather than nested object and
* supports {@link ConfigRoot#resolve resolving substitutions}.
*
* <p>
* <em>Do not implement this interface</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 ConfigRoot extends Config {
/**
* Returns a replacement root object with all substitutions (the
* "${foo.bar}" syntax) resolved. Substitutions are looked up in this root
* object. A configuration value tree must be resolved before you can use
* it. This method uses ConfigResolveOptions.defaults().
* <code>${foo.bar}</code> syntax, see <a
* href="https://github.com/havocp/config/blob/master/HOCON.md">the
* spec</a>) resolved. Substitutions are looked up in this root object. A
* {@link Config} must be resolved before you can use it. This method uses
* {@link ConfigResolveOptions#defaults()}.
*
* @return an immutable object with substitutions resolved
*/
ConfigRoot resolve();
/**
* Like {@link ConfigRoot#resolve()} but allows you to specify options.
*
* @param options
* resolve options
* @return the resolved root config
*/
ConfigRoot resolve(ConfigResolveOptions options);
@Override

View File

@ -3,6 +3,30 @@
*/
package com.typesafe.config;
/**
* The syntax of a character stream, <a href="http://json.org">JSON</a>, <a
* href="https://github.com/havocp/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>.
*
*/
public enum ConfigSyntax {
JSON, CONF, PROPERTIES;
/**
* Pedantically strict <a href="http://json.org">JSON</a> format; no
* comments, no unexpected commas, no duplicate keys in the same object.
*/
JSON,
/**
* The JSON-superset <a
* href="https://github.com/havocp/config/blob/master/HOCON.md">HOCON</a>
* format.
*/
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.
*/
PROPERTIES;
}

View File

@ -4,29 +4,42 @@
package com.typesafe.config;
/**
* Interface implemented by any configuration value. From the perspective of
* users of this interface, the object is immutable. It is therefore safe to use
* from multiple threads.
* 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
* implementations will break.
*/
public interface ConfigValue extends ConfigMergeable {
/**
* The origin of the value, for debugging and error messages.
* The origin of the value (file, line number, etc.), for debugging and
* error messages.
*
* @return where the value came from
*/
ConfigOrigin origin();
/**
* The type of the value; matches the JSON type schema.
* The {@link ConfigValueType} of the value; matches the JSON type schema.
*
* @return value's type
*/
ConfigValueType valueType();
/**
* Returns the config value as a plain Java boxed value, should be a String,
* Number, etc. matching the valueType() of the ConfigValue. If the value is
* a ConfigObject or ConfigList, it is recursively unwrapped.
* Returns the value as a plain Java boxed value, that is, a {@code String},
* {@code Number}, {@code Boolean}, {@code Map<String,Object>},
* {@code List<Object>}, or {@code null}, matching the {@link #valueType()}
* of this {@code ConfigValue}. If the value is a {@link ConfigObject} or
* {@link ConfigList}, it is recursively unwrapped.
*/
Object unwrapped();

View File

@ -3,7 +3,6 @@
*/
package com.typesafe.config;
import java.util.Collection;
import java.util.Map;
import com.typesafe.config.impl.ConfigImpl;
@ -23,23 +22,27 @@ public final class ConfigValueFactory {
* the Iterable is not an ordered collection, results could be strange,
* since ConfigList 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".
*
* <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
@ -57,23 +60,25 @@ public final class ConfigValueFactory {
/**
* See the fromAnyRef() documentation for details. This is a typesafe
* wrapper that only works on Map and returns ConfigObject rather than
* ConfigValue.
* 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
* 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.
* {@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.
*
* There is a separate fromPathMap() that interprets the keys in the map as
* path expressions.
* <p>
* See also {@link ConfigFactory#parseMap(Map,String)} which interprets the
* keys in the map as path expressions.
*
* @param values
* @param originDescription
* @return
* @return a new {@link ConfigObject} value
*/
public static ConfigObject fromMap(Map<String, ? extends Object> values,
String originDescription) {
@ -82,12 +87,12 @@ public final class ConfigValueFactory {
/**
* See the fromAnyRef() documentation for details. This is a typesafe
* wrapper that only works on Iterable and returns ConfigList rather than
* ConfigValue.
* wrapper that only works on {@link java.util.Iterable} and returns
* {@link ConfigList} rather than {@link ConfigValue}.
*
* @param values
* @param originDescription
* @return
* @return a new {@link ConfigList} value
*/
public static ConfigList fromIterable(Iterable<? extends Object> values,
String originDescription) {
@ -95,35 +100,39 @@ public final class ConfigValueFactory {
}
/**
* See the other overload of fromAnyRef() for details, this one just uses a
* default origin description.
* See the other overload {@link #fromAnyRef(Object,String)} for details,
* this one just uses a default origin description.
*
* @param object
* @return
* @return a new {@link ConfigValue}
*/
public static ConfigValue fromAnyRef(Object object) {
return fromAnyRef(object, null);
}
/**
* See the other overload of fromMap() for details, this one just uses a
* default origin description.
* See the other overload {@link #fromMap(Map,String)} for details, this one
* just uses a default origin description.
*
* <p>
* See also {@link ConfigFactory#parseMap(Map)} which interprets the keys in
* the map as path expressions.
*
* @param values
* @return
* @return a new {@link ConfigObject}
*/
public static ConfigObject fromMap(Map<String, ? extends Object> values) {
return fromMap(values, null);
}
/**
* See the other overload of fromIterable() for details, this one just uses
* a default origin description.
* See the other overload of {@link #fromIterable(Iterable, String)} for
* details, this one just uses a default origin description.
*
* @param values
* @return
* @return a new {@link ConfigList}
*/
public static ConfigList fromIterable(Collection<? extends Object> values) {
public static ConfigList fromIterable(Iterable<? extends Object> values) {
return fromIterable(values, null);
}
}

View File

@ -4,7 +4,8 @@
package com.typesafe.config;
/**
* The type of a configuration value. Value types follow the JSON type schema.
* The type of a configuration value (following the <a
* href="http://json.org">JSON</a> type schema).
*/
public enum ConfigValueType {
OBJECT, LIST, NUMBER, BOOLEAN, NULL, STRING

View File

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<!--
Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
-->
</head>
<body bgcolor="white">
An API for loading and using configuration files, see <a href="https://github.com/havocp/config/">the project site</a>
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.
</p>
</body>
</html>