mirror of
https://github.com/lightbend/config.git
synced 2025-01-28 21:20:07 +08:00
move a ConfigList interface up into the public API
This commit is contained in:
parent
88b970982d
commit
3019aec77f
20
src/main/java/com/typesafe/config/ConfigList.java
Normal file
20
src/main/java/com/typesafe/config/ConfigList.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A list (aka array) value corresponding to ConfigValueType.LIST or JSON's
|
||||
* "[1,2,3]" value. Implements java.util.List<ConfigValue> so you can use it
|
||||
* like a regular Java list.
|
||||
*
|
||||
*/
|
||||
public interface ConfigList extends List<ConfigValue>, ConfigValue {
|
||||
|
||||
/**
|
||||
* Recursively unwraps the list, returning a list of plain Java values such
|
||||
* as Integer or String or whatever is in the list.
|
||||
*/
|
||||
@Override
|
||||
List<Object> unwrapped();
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ import java.util.Map;
|
||||
* A ConfigObject is a read-only configuration object, which may have nested
|
||||
* child objects. Implementations of ConfigObject should be immutable (at least
|
||||
* from the perspective of anyone using this interface).
|
||||
*
|
||||
*
|
||||
* The getters all have the same semantics; they throw ConfigException.Missing
|
||||
* if the value is entirely unset, and ConfigException.WrongType if you ask for
|
||||
* a type that the value can't be converted to. ConfigException.Null is a
|
||||
@ -16,10 +16,10 @@ import java.util.Map;
|
||||
* path "a.b.c" looks for key c in object b in object a in the root object. (The
|
||||
* syntax for paths is the same as in ${} substitution expressions in config
|
||||
* files, sometimes double quotes are needed around special characters.)
|
||||
*
|
||||
*
|
||||
* ConfigObject implements the standard Java Map interface, but the mutator
|
||||
* methods all throw UnsupportedOperationException.
|
||||
*
|
||||
*
|
||||
* TODO add OrNull variants of all these getters? Or better to avoid convenience
|
||||
* API for that?
|
||||
*/
|
||||
@ -74,8 +74,16 @@ public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
|
||||
*/
|
||||
Long getNanoseconds(String path);
|
||||
|
||||
/* TODO should this return an iterator instead? */
|
||||
List<? extends ConfigValue> getList(String path);
|
||||
/**
|
||||
* Gets a list value (with any element type) as a ConfigList, which
|
||||
* implements java.util.List<ConfigValue>. Throws if the path is unset or
|
||||
* null.
|
||||
*
|
||||
* @param path
|
||||
* the path to the list value.
|
||||
* @return the ConfigList at the path
|
||||
*/
|
||||
ConfigList getList(String path);
|
||||
|
||||
List<Boolean> getBooleanList(String path);
|
||||
|
||||
|
@ -8,21 +8,22 @@ package com.typesafe.config;
|
||||
public interface ConfigValue {
|
||||
/**
|
||||
* The origin of the value, for debugging and error messages.
|
||||
*
|
||||
*
|
||||
* @return where the value came from
|
||||
*/
|
||||
ConfigOrigin origin();
|
||||
|
||||
/**
|
||||
* The type of the value; matches the JSON type schema.
|
||||
*
|
||||
*
|
||||
* @return value's type
|
||||
*/
|
||||
ConfigValueType valueType();
|
||||
|
||||
/**
|
||||
* Returns the config value as a plain Java boxed value, should be a String,
|
||||
* Number, etc. matching the valueType() of the ConfigValue.
|
||||
* Number, etc. matching the valueType() of the ConfigValue. If the value is
|
||||
* a ConfigObject or ConfigList, it is recursively unwrapped.
|
||||
*/
|
||||
Object unwrapped();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.typesafe.config.Config;
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigList;
|
||||
import com.typesafe.config.ConfigObject;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
@ -293,7 +294,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends ConfigValue> getList(String path) {
|
||||
public ConfigList getList(String path) {
|
||||
AbstractConfigValue v = find(path, ConfigValueType.LIST, path);
|
||||
return (ConfigList) v;
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ final class Parser {
|
||||
return new SimpleConfigObject(objectOrigin, null, values);
|
||||
}
|
||||
|
||||
private ConfigList parseArray() {
|
||||
private SimpleConfigList parseArray() {
|
||||
// invoked just after the OPEN_SQUARE
|
||||
ConfigOrigin arrayOrigin = lineOrigin();
|
||||
List<AbstractConfigValue> values = new ArrayList<AbstractConfigValue>();
|
||||
@ -333,7 +333,7 @@ final class Parser {
|
||||
|
||||
// special-case the first element
|
||||
if (t == Tokens.CLOSE_SQUARE) {
|
||||
return new ConfigList(arrayOrigin,
|
||||
return new SimpleConfigList(arrayOrigin,
|
||||
Collections.<AbstractConfigValue> emptyList());
|
||||
} else if (Tokens.isValue(t)) {
|
||||
values.add(parseValue(t));
|
||||
@ -351,7 +351,7 @@ final class Parser {
|
||||
// just after a value
|
||||
t = nextTokenIgnoringNewline();
|
||||
if (t == Tokens.CLOSE_SQUARE) {
|
||||
return new ConfigList(arrayOrigin, values);
|
||||
return new SimpleConfigList(arrayOrigin, values);
|
||||
} else if (t == Tokens.COMMA) {
|
||||
// OK
|
||||
} else {
|
||||
|
@ -7,15 +7,16 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigList;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
final class ConfigList extends AbstractConfigValue implements List<ConfigValue> {
|
||||
final class SimpleConfigList extends AbstractConfigValue implements ConfigList {
|
||||
|
||||
private List<AbstractConfigValue> value;
|
||||
|
||||
ConfigList(ConfigOrigin origin, List<AbstractConfigValue> value) {
|
||||
SimpleConfigList(ConfigOrigin origin, List<AbstractConfigValue> value) {
|
||||
super(origin);
|
||||
this.value = value;
|
||||
}
|
||||
@ -35,7 +36,7 @@ final class ConfigList extends AbstractConfigValue implements List<ConfigValue>
|
||||
}
|
||||
|
||||
@Override
|
||||
ConfigList resolveSubstitutions(SubstitutionResolver resolver, int depth,
|
||||
SimpleConfigList resolveSubstitutions(SubstitutionResolver resolver, int depth,
|
||||
boolean withFallbacks) {
|
||||
// lazy-create for optimization
|
||||
List<AbstractConfigValue> changed = null;
|
||||
@ -65,7 +66,7 @@ final class ConfigList extends AbstractConfigValue implements List<ConfigValue>
|
||||
if (changed.size() != value.size())
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"substituted list's size doesn't match");
|
||||
return new ConfigList(origin(), changed);
|
||||
return new SimpleConfigList(origin(), changed);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
@ -73,15 +74,15 @@ final class ConfigList extends AbstractConfigValue implements List<ConfigValue>
|
||||
|
||||
@Override
|
||||
protected boolean canEqual(Object other) {
|
||||
return other instanceof ConfigList;
|
||||
return other instanceof SimpleConfigList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
// note that "origin" is deliberately NOT part of equality
|
||||
if (other instanceof ConfigList) {
|
||||
if (other instanceof SimpleConfigList) {
|
||||
// optimization to avoid unwrapped() for two ConfigList
|
||||
return canEqual(other) && value.equals(((ConfigList) other).value);
|
||||
return canEqual(other) && value.equals(((SimpleConfigList) other).value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
@ -6,6 +6,7 @@ import com.typesafe.config.ConfigValue
|
||||
import java.util.Collections
|
||||
import scala.collection.JavaConverters._
|
||||
import com.typesafe.config.ConfigObject
|
||||
import com.typesafe.config.ConfigList
|
||||
|
||||
class ConfigValueTest extends TestUtils {
|
||||
|
||||
@ -69,10 +70,10 @@ class ConfigValueTest extends TestUtils {
|
||||
@Test
|
||||
def configListEquality() {
|
||||
val aScalaSeq = Seq(1, 2, 3) map { intValue(_): AbstractConfigValue }
|
||||
val aList = new ConfigList(fakeOrigin(), aScalaSeq.asJava)
|
||||
val sameAsAList = new ConfigList(fakeOrigin(), aScalaSeq.asJava)
|
||||
val aList = new SimpleConfigList(fakeOrigin(), aScalaSeq.asJava)
|
||||
val sameAsAList = new SimpleConfigList(fakeOrigin(), aScalaSeq.asJava)
|
||||
val bScalaSeq = Seq(4, 5, 6) map { intValue(_): AbstractConfigValue }
|
||||
val bList = new ConfigList(fakeOrigin(), bScalaSeq.asJava)
|
||||
val bList = new SimpleConfigList(fakeOrigin(), bScalaSeq.asJava)
|
||||
|
||||
checkEqualObjects(aList, aList)
|
||||
checkEqualObjects(aList, sameAsAList)
|
||||
@ -101,7 +102,7 @@ class ConfigValueTest extends TestUtils {
|
||||
nullValue().toString()
|
||||
boolValue(true).toString()
|
||||
(new SimpleConfigObject(fakeOrigin(), null, Collections.emptyMap[String, AbstractConfigValue]())).toString()
|
||||
(new ConfigList(fakeOrigin(), Collections.emptyList[AbstractConfigValue]())).toString()
|
||||
(new SimpleConfigList(fakeOrigin(), Collections.emptyList[AbstractConfigValue]())).toString()
|
||||
subst("a").toString()
|
||||
substInString("b").toString()
|
||||
}
|
||||
@ -153,8 +154,9 @@ class ConfigValueTest extends TestUtils {
|
||||
|
||||
@Test
|
||||
def configListImplementsList() {
|
||||
val l: ConfigList = new ConfigList(fakeOrigin(), List[AbstractConfigValue](stringValue("a"), stringValue("b"), stringValue("c")).asJava)
|
||||
val scalaSeq = Seq(stringValue("a"), stringValue("b"), stringValue("c"))
|
||||
val scalaSeq = Seq[AbstractConfigValue](stringValue("a"), stringValue("b"), stringValue("c"))
|
||||
val l: ConfigList = new SimpleConfigList(fakeOrigin(),
|
||||
scalaSeq.asJava)
|
||||
|
||||
assertEquals(scalaSeq(0), l.get(0))
|
||||
assertEquals(scalaSeq(1), l.get(1))
|
||||
|
@ -51,7 +51,7 @@ class JsonTest extends TestUtils {
|
||||
fields.foreach({ field => m.put(field.name, fromLift(field.value)) })
|
||||
new SimpleConfigObject(fakeOrigin(), null, m)
|
||||
case lift.JArray(values) =>
|
||||
new ConfigList(fakeOrigin(), values.map(fromLift(_)).asJava)
|
||||
new SimpleConfigList(fakeOrigin(), values.map(fromLift(_)).asJava)
|
||||
case lift.JField(name, value) =>
|
||||
throw new IllegalStateException("either JField was a toplevel from lift-json or this function is buggy")
|
||||
case lift.JInt(i) =>
|
||||
|
Loading…
Reference in New Issue
Block a user