    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}