mirror of
https://github.com/lightbend/config.git
synced 2025-01-15 23:01:05 +08:00
add Config.entrySet() which returns the set of paths and non-null values
This commit is contained in:
parent
38fb8d6834
commit
f6fd02508e
@ -4,6 +4,8 @@
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An immutable map from config paths to config values.
|
||||
@ -54,10 +56,11 @@ import java.util.List;
|
||||
* are performed for you though.
|
||||
*
|
||||
* <p>
|
||||
* If you want to iterate over the contents of a {@code Config}, you have to get
|
||||
* its {@code ConfigObject} with {@link #root()}, and then iterate over the
|
||||
* {@code ConfigObject}.
|
||||
*
|
||||
* 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>
|
||||
* <em>Do not implement {@code Config}</em>; it should only be implemented by
|
||||
@ -256,6 +259,17 @@ public interface Config extends ConfigMergeable {
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns the set of path-value pairs, excluding any null values, found by
|
||||
* recursing {@link #root() the root object}. Note that this is very
|
||||
* different from <code>root().entrySet()</code> which returns the set of
|
||||
* immediate-child keys in the root object and includes null values.
|
||||
*
|
||||
* @return set of paths with non-null values, built up by recursing the
|
||||
* entire tree of {@link ConfigObject}
|
||||
*/
|
||||
Set<Map.Entry<String, ConfigValue>> entrySet();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
|
@ -3,10 +3,13 @@
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.typesafe.config.Config;
|
||||
@ -20,12 +23,10 @@ import com.typesafe.config.ConfigValue;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
/**
|
||||
* One thing to keep in mind in the future: if any Collection-like APIs are
|
||||
* added here, including iterators or size() or anything, then we'd have to
|
||||
* grapple with whether ConfigNull values are "in" the Config (probably not) and
|
||||
* we'd probably want to make the collection look flat - not like a tree. So the
|
||||
* key-value pairs would be all the tree's leaf values, in a big flat list with
|
||||
* their full paths.
|
||||
* One thing to keep in mind in the future: as Collection-like APIs are added
|
||||
* here, including iterators or size() or anything, they should be consistent
|
||||
* with a one-level java.util.Map from paths to non-null values. Null values are
|
||||
* not "in" the map.
|
||||
*/
|
||||
final class SimpleConfig implements Config, MergeableValue {
|
||||
|
||||
@ -73,6 +74,31 @@ final class SimpleConfig implements Config, MergeableValue {
|
||||
return object.isEmpty();
|
||||
}
|
||||
|
||||
private static void findPaths(Set<Map.Entry<String, ConfigValue>> entries, Path parent,
|
||||
AbstractConfigObject obj) {
|
||||
for (Map.Entry<String, ConfigValue> entry : obj.entrySet()) {
|
||||
String elem = entry.getKey();
|
||||
ConfigValue v = entry.getValue();
|
||||
Path path = Path.newKey(elem);
|
||||
if (parent != null)
|
||||
path = path.prepend(parent);
|
||||
if (v instanceof AbstractConfigObject) {
|
||||
findPaths(entries, path, (AbstractConfigObject) v);
|
||||
} else if (v instanceof ConfigNull) {
|
||||
// nothing; nulls are conceptually not in a Config
|
||||
} else {
|
||||
entries.add(new AbstractMap.SimpleImmutableEntry<String, ConfigValue>(path.render(), v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Map.Entry<String, ConfigValue>> entrySet() {
|
||||
Set<Map.Entry<String, ConfigValue>> entries = new HashSet<Map.Entry<String, ConfigValue>>();
|
||||
findPaths(entries, null, object);
|
||||
return entries;
|
||||
}
|
||||
|
||||
static private AbstractConfigValue find(AbstractConfigObject self,
|
||||
String pathExpression, ConfigValueType expected, String originalPath) {
|
||||
Path path = Path.newPath(pathExpression);
|
||||
|
@ -782,6 +782,16 @@ class ConfigTest extends TestUtils {
|
||||
assertEquals(-1, o3.lineNumber)
|
||||
}
|
||||
|
||||
@Test
|
||||
def test01EntrySet() {
|
||||
val conf = ConfigFactory.load("test01")
|
||||
|
||||
val javaEntries = conf.entrySet()
|
||||
val entries = Map((javaEntries.asScala.toSeq map { e => (e.getKey(), e.getValue()) }): _*)
|
||||
assertEquals(Some(intValue(42)), entries.get("ints.fortyTwo"))
|
||||
assertEquals(None, entries.get("nulls.null"))
|
||||
}
|
||||
|
||||
@Test
|
||||
def test02SubstitutionsWithWeirdPaths() {
|
||||
val conf = ConfigFactory.load("test02")
|
||||
|
Loading…
Reference in New Issue
Block a user