001/**
002 *   Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
003 */
004package com.typesafe.config;
005
006import java.util.Map;
007
008/**
009 * Subtype of {@link ConfigValue} representing an object (AKA dictionary or map)
010 * value, as in JSON's curly brace <code>{ "a" : 42 }</code> syntax.
011 * 
012 * <p>
013 * An object may also be viewed as a {@link Config} by calling
014 * {@link ConfigObject#toConfig()}.
015 * 
016 * <p>
017 * {@code ConfigObject} implements {@code java.util.Map<String, ConfigValue>} so
018 * you can use it like a regular Java map. Or call {@link #unwrapped()} to
019 * unwrap the map to a map with plain Java values rather than
020 * {@code ConfigValue}.
021 * 
022 * <p>
023 * Like all {@link ConfigValue} subtypes, {@code ConfigObject} is immutable.
024 * This makes it threadsafe and you never have to create "defensive copies." The
025 * mutator methods from {@link java.util.Map} all throw
026 * {@link java.lang.UnsupportedOperationException}.
027 * 
028 * <p>
029 * The {@link ConfigValue#valueType} method on an object returns
030 * {@link ConfigValueType#OBJECT}.
031 * 
032 * <p>
033 * In most cases you want to use the {@link Config} interface rather than this
034 * one. Call {@link #toConfig()} to convert a {@code ConfigObject} to a
035 * {@code Config}.
036 * 
037 * <p>
038 * The API for a {@code ConfigObject} is in terms of keys, while the API for a
039 * {@link Config} is in terms of path expressions. Conceptually,
040 * {@code ConfigObject} is a tree of maps from keys to values, while a
041 * {@code Config} is a one-level map from paths to values.
042 * 
043 * <p>
044 * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
045 * between path expressions and individual path elements (keys).
046 * 
047 * <p>
048 * A {@code ConfigObject} may contain null values, which will have
049 * {@link ConfigValue#valueType()} equal to {@link ConfigValueType#NULL}. If
050 * {@link ConfigObject#get(Object)} returns Java's null then the key was not
051 * present in the parsed file (or wherever this value tree came from). If
052 * {@code get("key")} returns a {@link ConfigValue} with type
053 * {@code ConfigValueType#NULL} then the key was set to null explicitly in the
054 * config file.
055 * 
056 * <p>
057 * <em>Do not implement interface {@code ConfigObject}</em>; it should only be
058 * implemented by the config library. Arbitrary implementations will not work
059 * because the library internals assume a specific concrete implementation.
060 * Also, this interface is likely to grow new methods over time, so third-party
061 * implementations will break.
062 */
063public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
064
065    /**
066     * Converts this object to a {@link Config} instance, enabling you to use
067     * path expressions to find values in the object. This is a constant-time
068     * operation (it is not proportional to the size of the object).
069     *
070     * @return a {@link Config} with this object as its root
071     */
072    Config toConfig();
073
074    /**
075     * Recursively unwraps the object, returning a map from String to whatever
076     * plain Java values are unwrapped from the object's values.
077     *
078     * @return a {@link java.util.Map} containing plain Java objects
079     */
080    @Override
081    Map<String, Object> unwrapped();
082
083    @Override
084    ConfigObject withFallback(ConfigMergeable other);
085
086    /**
087     * Gets a {@link ConfigValue} at the given key, or returns null if there is
088     * no value. The returned {@link ConfigValue} may have
089     * {@link ConfigValueType#NULL} or any other type, and the passed-in key
090     * must be a key in this object (rather than a path expression).
091     * 
092     * @param key
093     *            key to look up
094     * 
095     * @return the value at the key or null if none
096     */
097    @Override
098    ConfigValue get(Object key);
099
100    /**
101     * Clone the object with only the given key (and its children) retained; all
102     * sibling keys are removed.
103     *
104     * @param key
105     *            key to keep
106     * @return a copy of the object minus all keys except the one specified
107     */
108    ConfigObject withOnlyKey(String key);
109
110    /**
111     * Clone the object with the given key removed.
112     *
113     * @param key
114     *            key to remove
115     * @return a copy of the object minus the specified key
116     */
117    ConfigObject withoutKey(String key);
118
119    /**
120     * Returns a {@code ConfigObject} based on this one, but with the given key
121     * set to the given value. Does not modify this instance (since it's
122     * immutable). If the key already has a value, that value is replaced. To
123     * remove a value, use {@link ConfigObject#withoutKey(String)}.
124     * 
125     * @param key
126     *            key to add
127     * @param value
128     *            value at the new key
129     * @return the new instance with the new map entry
130     */
131    ConfigObject withValue(String key, ConfigValue value);
132
133    @Override
134    ConfigObject withOrigin(ConfigOrigin origin);
135}