mirror of
https://github.com/lightbend/config.git
synced 2025-01-29 05:30:08 +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;
|
package com.typesafe.config;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An immutable map from config paths to config values.
|
* An immutable map from config paths to config values.
|
||||||
@ -54,10 +56,11 @@ import java.util.List;
|
|||||||
* are performed for you though.
|
* are performed for you though.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* If you want to iterate over the contents of a {@code Config}, you have to get
|
* If you want to iterate over the contents of a {@code Config}, you can get its
|
||||||
* its {@code ConfigObject} with {@link #root()}, and then iterate over the
|
* {@code ConfigObject} with {@link #root()}, and then iterate over the
|
||||||
* {@code ConfigObject}.
|
* {@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>
|
* <p>
|
||||||
* <em>Do not implement {@code Config}</em>; it should only be implemented by
|
* <em>Do not implement {@code Config}</em>; it should only be implemented by
|
||||||
@ -256,6 +259,17 @@ public interface Config extends ConfigMergeable {
|
|||||||
*/
|
*/
|
||||||
boolean isEmpty();
|
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
|
* @param path
|
||||||
|
@ -3,10 +3,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.typesafe.config.impl;
|
package com.typesafe.config.impl;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.typesafe.config.Config;
|
import com.typesafe.config.Config;
|
||||||
@ -20,12 +23,10 @@ import com.typesafe.config.ConfigValue;
|
|||||||
import com.typesafe.config.ConfigValueType;
|
import com.typesafe.config.ConfigValueType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One thing to keep in mind in the future: if any Collection-like APIs are
|
* One thing to keep in mind in the future: as Collection-like APIs are added
|
||||||
* added here, including iterators or size() or anything, then we'd have to
|
* here, including iterators or size() or anything, they should be consistent
|
||||||
* grapple with whether ConfigNull values are "in" the Config (probably not) and
|
* with a one-level java.util.Map from paths to non-null values. Null values are
|
||||||
* we'd probably want to make the collection look flat - not like a tree. So the
|
* not "in" the map.
|
||||||
* key-value pairs would be all the tree's leaf values, in a big flat list with
|
|
||||||
* their full paths.
|
|
||||||
*/
|
*/
|
||||||
final class SimpleConfig implements Config, MergeableValue {
|
final class SimpleConfig implements Config, MergeableValue {
|
||||||
|
|
||||||
@ -73,6 +74,31 @@ final class SimpleConfig implements Config, MergeableValue {
|
|||||||
return object.isEmpty();
|
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,
|
static private AbstractConfigValue find(AbstractConfigObject self,
|
||||||
String pathExpression, ConfigValueType expected, String originalPath) {
|
String pathExpression, ConfigValueType expected, String originalPath) {
|
||||||
Path path = Path.newPath(pathExpression);
|
Path path = Path.newPath(pathExpression);
|
||||||
|
@ -782,6 +782,16 @@ class ConfigTest extends TestUtils {
|
|||||||
assertEquals(-1, o3.lineNumber)
|
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
|
@Test
|
||||||
def test02SubstitutionsWithWeirdPaths() {
|
def test02SubstitutionsWithWeirdPaths() {
|
||||||
val conf = ConfigFactory.load("test02")
|
val conf = ConfigFactory.load("test02")
|
||||||
|
Loading…
Reference in New Issue
Block a user