001/**
002 *   Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
003 */
004package com.typesafe.config;
005
006import java.util.Map;
007
008import com.typesafe.config.impl.ConfigImpl;
009
010/**
011 * This class holds some static factory methods for building {@link ConfigValue}
012 * instances. See also {@link ConfigFactory} which has methods for parsing files
013 * and certain in-memory data structures.
014 */
015public final class ConfigValueFactory {
016    private ConfigValueFactory() {
017    }
018
019    /**
020     * Creates a {@link ConfigValue} from a plain Java boxed value, which may be
021     * a <code>Boolean</code>, <code>Number</code>, <code>String</code>,
022     * <code>Map</code>, <code>Iterable</code>, or <code>null</code>. A
023     * <code>Map</code> must be a <code>Map</code> from String to more values
024     * that can be supplied to <code>fromAnyRef()</code>. An
025     * <code>Iterable</code> must iterate over more values that can be supplied
026     * to <code>fromAnyRef()</code>. A <code>Map</code> will become a
027     * {@link ConfigObject} and an <code>Iterable</code> will become a
028     * {@link ConfigList}. If the <code>Iterable</code> is not an ordered
029     * collection, results could be strange, since <code>ConfigList</code> is
030     * ordered.
031     * 
032     * <p>
033     * In a <code>Map</code> passed to <code>fromAnyRef()</code>, the map's keys
034     * are plain keys, not path expressions. So if your <code>Map</code> has a
035     * key "foo.bar" then you will get one object with a key called "foo.bar",
036     * rather than an object with a key "foo" containing another object with a
037     * key "bar".
038     * 
039     * <p>
040     * The originDescription will be used to set the origin() field on the
041     * ConfigValue. It should normally be the name of the file the values came
042     * from, or something short describing the value such as "default settings".
043     * The originDescription is prefixed to error messages so users can tell
044     * where problematic values are coming from.
045     * 
046     * <p>
047     * Supplying the result of ConfigValue.unwrapped() to this function is
048     * guaranteed to work and should give you back a ConfigValue that matches
049     * the one you unwrapped. The re-wrapped ConfigValue will lose some
050     * information that was present in the original such as its origin, but it
051     * will have matching values.
052     *
053     * <p>
054     * If you pass in a <code>ConfigValue</code> to this
055     * function, it will be returned unmodified. (The
056     * <code>originDescription</code> will be ignored in this
057     * case.)
058     *
059     * <p>
060     * This function throws if you supply a value that cannot be converted to a
061     * ConfigValue, but supplying such a value is a bug in your program, so you
062     * should never handle the exception. Just fix your program (or report a bug
063     * against this library).
064     * 
065     * @param object
066     *            object to convert to ConfigValue
067     * @param originDescription
068     *            name of origin file or brief description of what the value is
069     * @return a new value
070     */
071    public static ConfigValue fromAnyRef(Object object, String originDescription) {
072        return ConfigImpl.fromAnyRef(object, originDescription);
073    }
074
075    /**
076     * See the {@link #fromAnyRef(Object,String)} documentation for details.
077     * This is a typesafe wrapper that only works on {@link java.util.Map} and
078     * returns {@link ConfigObject} rather than {@link ConfigValue}.
079     * 
080     * <p>
081     * If your <code>Map</code> has a key "foo.bar" then you will get one object
082     * with a key called "foo.bar", rather than an object with a key "foo"
083     * containing another object with a key "bar". The keys in the map are keys;
084     * not path expressions. That is, the <code>Map</code> corresponds exactly
085     * to a single {@code ConfigObject}. The keys will not be parsed or
086     * modified, and the values are wrapped in ConfigValue. To get nested
087     * {@code ConfigObject}, some of the values in the map would have to be more
088     * maps.
089     * 
090     * <p>
091     * See also {@link ConfigFactory#parseMap(Map,String)} which interprets the
092     * keys in the map as path expressions.
093     * 
094     * @param values map from keys to plain Java values
095     * @param originDescription description to use in {@link ConfigOrigin} of created values
096     * @return a new {@link ConfigObject} value
097     */
098    public static ConfigObject fromMap(Map<String, ? extends Object> values,
099            String originDescription) {
100        return (ConfigObject) fromAnyRef(values, originDescription);
101    }
102
103    /**
104     * See the {@link #fromAnyRef(Object,String)} documentation for details.
105     * This is a typesafe wrapper that only works on {@link java.lang.Iterable}
106     * and returns {@link ConfigList} rather than {@link ConfigValue}.
107     *
108     * @param values list of plain Java values
109     * @param originDescription description to use in {@link ConfigOrigin} of created values
110     * @return a new {@link ConfigList} value
111     */
112    public static ConfigList fromIterable(Iterable<? extends Object> values,
113            String originDescription) {
114        return (ConfigList) fromAnyRef(values, originDescription);
115    }
116
117    /**
118     * See the other overload {@link #fromAnyRef(Object,String)} for details,
119     * this one just uses a default origin description.
120     *
121     * @param object a plain Java value
122     * @return a new {@link ConfigValue}
123     */
124    public static ConfigValue fromAnyRef(Object object) {
125        return fromAnyRef(object, null);
126    }
127
128    /**
129     * See the other overload {@link #fromMap(Map,String)} for details, this one
130     * just uses a default origin description.
131     *
132     * <p>
133     * See also {@link ConfigFactory#parseMap(Map)} which interprets the keys in
134     * the map as path expressions.
135     *
136     * @param values map from keys to plain Java values
137     * @return a new {@link ConfigObject}
138     */
139    public static ConfigObject fromMap(Map<String, ? extends Object> values) {
140        return fromMap(values, null);
141    }
142
143    /**
144     * See the other overload of {@link #fromIterable(Iterable, String)} for
145     * details, this one just uses a default origin description.
146     *
147     * @param values list of plain Java values
148     * @return a new {@link ConfigList}
149     */
150    public static ConfigList fromIterable(Iterable<? extends Object> values) {
151        return fromIterable(values, null);
152    }
153}