mirror of
https://github.com/lightbend/config.git
synced 2025-03-22 15:20:26 +08:00
make ConfigList implement java.util.List
This commit is contained in:
parent
be63b620f6
commit
88b970982d
@ -295,7 +295,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
@Override
|
@Override
|
||||||
public List<? extends ConfigValue> getList(String path) {
|
public List<? extends ConfigValue> getList(String path) {
|
||||||
AbstractConfigValue v = find(path, ConfigValueType.LIST, path);
|
AbstractConfigValue v = find(path, ConfigValueType.LIST, path);
|
||||||
return ((ConfigList) v).asJavaList();
|
return (ConfigList) v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
package com.typesafe.config.impl;
|
package com.typesafe.config.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
import com.typesafe.config.ConfigException;
|
import com.typesafe.config.ConfigException;
|
||||||
import com.typesafe.config.ConfigOrigin;
|
import com.typesafe.config.ConfigOrigin;
|
||||||
import com.typesafe.config.ConfigValue;
|
import com.typesafe.config.ConfigValue;
|
||||||
import com.typesafe.config.ConfigValueType;
|
import com.typesafe.config.ConfigValueType;
|
||||||
|
|
||||||
final class ConfigList extends AbstractConfigValue {
|
final class ConfigList extends AbstractConfigValue implements List<ConfigValue> {
|
||||||
|
|
||||||
private List<AbstractConfigValue> value;
|
private List<AbstractConfigValue> value;
|
||||||
|
|
||||||
@ -17,10 +20,6 @@ final class ConfigList extends AbstractConfigValue {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<? extends ConfigValue> asJavaList() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigValueType valueType() {
|
public ConfigValueType valueType() {
|
||||||
return ConfigValueType.LIST;
|
return ConfigValueType.LIST;
|
||||||
@ -108,4 +107,196 @@ final class ConfigList extends AbstractConfigValue {
|
|||||||
sb.append(")");
|
sb.append(")");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return value.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(Collection<?> c) {
|
||||||
|
return value.containsAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigValue get(int index) {
|
||||||
|
return value.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(Object o) {
|
||||||
|
return value.indexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return value.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<ConfigValue> iterator() {
|
||||||
|
final Iterator<AbstractConfigValue> i = value.iterator();
|
||||||
|
|
||||||
|
return new Iterator<ConfigValue>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return i.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigValue next() {
|
||||||
|
return i.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw weAreImmutable("iterator().remove");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int lastIndexOf(Object o) {
|
||||||
|
return value.lastIndexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ListIterator<ConfigValue> wrapListIterator(
|
||||||
|
final ListIterator<AbstractConfigValue> i) {
|
||||||
|
return new ListIterator<ConfigValue>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return i.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigValue next() {
|
||||||
|
return i.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw weAreImmutable("listIterator().remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(ConfigValue arg0) {
|
||||||
|
throw weAreImmutable("listIterator().add");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPrevious() {
|
||||||
|
return i.hasPrevious();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int nextIndex() {
|
||||||
|
return i.nextIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigValue previous() {
|
||||||
|
return i.previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int previousIndex() {
|
||||||
|
return i.previousIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(ConfigValue arg0) {
|
||||||
|
throw weAreImmutable("listIterator().set");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListIterator<ConfigValue> listIterator() {
|
||||||
|
return wrapListIterator(value.listIterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListIterator<ConfigValue> listIterator(int index) {
|
||||||
|
return wrapListIterator(value.listIterator(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return value.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ConfigValue> subList(int fromIndex, int toIndex) {
|
||||||
|
List<ConfigValue> list = new ArrayList<ConfigValue>();
|
||||||
|
// yay bloat caused by lack of type variance
|
||||||
|
for (AbstractConfigValue v : value.subList(fromIndex, toIndex)) {
|
||||||
|
list.add(v);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
return value.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T[] toArray(T[] a) {
|
||||||
|
return value.toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UnsupportedOperationException weAreImmutable(String method) {
|
||||||
|
return new UnsupportedOperationException(
|
||||||
|
"ConfigList is immutable, you can't call List.'" + method + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(ConfigValue e) {
|
||||||
|
throw weAreImmutable("add");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int index, ConfigValue element) {
|
||||||
|
throw weAreImmutable("add");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(Collection<? extends ConfigValue> c) {
|
||||||
|
throw weAreImmutable("addAll");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(int index, Collection<? extends ConfigValue> c) {
|
||||||
|
throw weAreImmutable("addAll");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
throw weAreImmutable("clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
throw weAreImmutable("remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigValue remove(int index) {
|
||||||
|
throw weAreImmutable("remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(Collection<?> c) {
|
||||||
|
throw weAreImmutable("removeAll");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(Collection<?> c) {
|
||||||
|
throw weAreImmutable("retainAll");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigValue set(int index, ConfigValue element) {
|
||||||
|
throw weAreImmutable("set");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,8 @@
|
|||||||
"ofNull" : [null, null, null],
|
"ofNull" : [null, null, null],
|
||||||
"ofBoolean" : [true, false],
|
"ofBoolean" : [true, false],
|
||||||
"ofArray" : [${arrays.ofString}, ${arrays.ofString}, ${arrays.ofString}],
|
"ofArray" : [${arrays.ofString}, ${arrays.ofString}, ${arrays.ofString}],
|
||||||
"ofObject" : [${ints}, ${booleans}, ${strings}]
|
"ofObject" : [${ints}, ${booleans}, ${strings}],
|
||||||
|
"firstElementNotASubst" : [ "a", ${strings.b} ]
|
||||||
},
|
},
|
||||||
|
|
||||||
"booleans" : {
|
"booleans" : {
|
||||||
|
@ -56,7 +56,7 @@ class ConfParserTest extends TestUtils {
|
|||||||
val tree = parseWithoutResolving("[${" + s + "}]")
|
val tree = parseWithoutResolving("[${" + s + "}]")
|
||||||
val result = tree match {
|
val result = tree match {
|
||||||
case list: ConfigList =>
|
case list: ConfigList =>
|
||||||
list.asJavaList().get(0) match {
|
list.get(0) match {
|
||||||
case subst: ConfigSubstitution =>
|
case subst: ConfigSubstitution =>
|
||||||
subst.pieces().get(0) match {
|
subst.pieces().get(0) match {
|
||||||
case p: Path => p
|
case p: Path => p
|
||||||
|
@ -194,6 +194,8 @@ class ConfigTest extends TestUtils {
|
|||||||
assertEquals(Seq(Seq("a", "b", "c"), Seq("a", "b", "c"), Seq("a", "b", "c")), listOfLists)
|
assertEquals(Seq(Seq("a", "b", "c"), Seq("a", "b", "c"), Seq("a", "b", "c")), listOfLists)
|
||||||
assertEquals(3, conf.getObjectList("arrays.ofObject").asScala.length)
|
assertEquals(3, conf.getObjectList("arrays.ofObject").asScala.length)
|
||||||
|
|
||||||
|
assertEquals(Seq("a", "b"), conf.getStringList("arrays.firstElementNotASubst").asScala)
|
||||||
|
|
||||||
// plain getList should work
|
// plain getList should work
|
||||||
assertEquals(Seq(intValue(1), intValue(2), intValue(3)), conf.getList("arrays.ofInt").asScala)
|
assertEquals(Seq(intValue(1), intValue(2), intValue(3)), conf.getList("arrays.ofInt").asScala)
|
||||||
assertEquals(Seq(stringValue("a"), stringValue("b"), stringValue("c")), conf.getList("arrays.ofString").asScala)
|
assertEquals(Seq(stringValue("a"), stringValue("b"), stringValue("c")), conf.getList("arrays.ofString").asScala)
|
||||||
|
@ -66,6 +66,19 @@ class ConfigValueTest extends TestUtils {
|
|||||||
checkNotEqualObjects(a, b)
|
checkNotEqualObjects(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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 bScalaSeq = Seq(4, 5, 6) map { intValue(_): AbstractConfigValue }
|
||||||
|
val bList = new ConfigList(fakeOrigin(), bScalaSeq.asJava)
|
||||||
|
|
||||||
|
checkEqualObjects(aList, aList)
|
||||||
|
checkEqualObjects(aList, sameAsAList)
|
||||||
|
checkNotEqualObjects(aList, bList)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
def configSubstitutionEquality() {
|
def configSubstitutionEquality() {
|
||||||
val a = subst("foo")
|
val a = subst("foo")
|
||||||
@ -137,4 +150,74 @@ class ConfigValueTest extends TestUtils {
|
|||||||
unsupported { m.putAll(Collections.emptyMap[String, AbstractConfigValue]()) }
|
unsupported { m.putAll(Collections.emptyMap[String, AbstractConfigValue]()) }
|
||||||
unsupported { m.remove("a") }
|
unsupported { m.remove("a") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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"))
|
||||||
|
|
||||||
|
assertEquals(scalaSeq(0), l.get(0))
|
||||||
|
assertEquals(scalaSeq(1), l.get(1))
|
||||||
|
assertEquals(scalaSeq(2), l.get(2))
|
||||||
|
|
||||||
|
assertTrue(l.contains(stringValue("a")))
|
||||||
|
|
||||||
|
assertTrue(l.containsAll(List[AbstractConfigValue](stringValue("b")).asJava))
|
||||||
|
assertFalse(l.containsAll(List[AbstractConfigValue](stringValue("d")).asJava))
|
||||||
|
|
||||||
|
assertEquals(1, l.indexOf(scalaSeq(1)))
|
||||||
|
|
||||||
|
assertFalse(l.isEmpty());
|
||||||
|
|
||||||
|
assertEquals(scalaSeq, l.iterator().asScala.toSeq)
|
||||||
|
|
||||||
|
unsupported { l.iterator().remove() }
|
||||||
|
|
||||||
|
assertEquals(1, l.lastIndexOf(scalaSeq(1)))
|
||||||
|
|
||||||
|
val li = l.listIterator()
|
||||||
|
var i = 0
|
||||||
|
while (li.hasNext()) {
|
||||||
|
assertEquals(i > 0, li.hasPrevious())
|
||||||
|
assertEquals(i, li.nextIndex())
|
||||||
|
assertEquals(i - 1, li.previousIndex())
|
||||||
|
|
||||||
|
unsupported { li.remove() }
|
||||||
|
unsupported { li.add(intValue(3)) }
|
||||||
|
unsupported { li.set(stringValue("foo")) }
|
||||||
|
|
||||||
|
val v = li.next()
|
||||||
|
assertEquals(l.get(i), v)
|
||||||
|
|
||||||
|
if (li.hasPrevious()) {
|
||||||
|
// go backward
|
||||||
|
assertEquals(scalaSeq(i), li.previous())
|
||||||
|
// go back forward
|
||||||
|
li.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
l.listIterator(1) // doesn't throw!
|
||||||
|
|
||||||
|
assertEquals(3, l.size())
|
||||||
|
|
||||||
|
assertEquals(scalaSeq.tail, l.subList(1, l.size()).asScala)
|
||||||
|
|
||||||
|
assertEquals(scalaSeq, l.toArray.toList)
|
||||||
|
|
||||||
|
assertEquals(scalaSeq, l.toArray(new Array[ConfigValue](l.size())).toList)
|
||||||
|
|
||||||
|
unsupported { l.add(intValue(3)) }
|
||||||
|
unsupported { l.add(1, intValue(4)) }
|
||||||
|
unsupported { l.addAll(List[ConfigValue]().asJava) }
|
||||||
|
unsupported { l.addAll(1, List[ConfigValue]().asJava) }
|
||||||
|
unsupported { l.clear() }
|
||||||
|
unsupported { l.remove(intValue(2)) }
|
||||||
|
unsupported { l.remove(1) }
|
||||||
|
unsupported { l.removeAll(List[ConfigValue](intValue(1)).asJava) }
|
||||||
|
unsupported { l.retainAll(List[ConfigValue](intValue(1)).asJava) }
|
||||||
|
unsupported { l.set(0, intValue(42)) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class JsonTest extends TestUtils {
|
|||||||
case v: ConfigObject =>
|
case v: ConfigObject =>
|
||||||
lift.JObject(v.keySet().asScala.map({ k => lift.JField(k, toLift(v.get(k))) }).toList)
|
lift.JObject(v.keySet().asScala.map({ k => lift.JField(k, toLift(v.get(k))) }).toList)
|
||||||
case v: ConfigList =>
|
case v: ConfigList =>
|
||||||
lift.JArray(v.asJavaList().asScala.toList.map({ elem => toLift(elem) }))
|
lift.JArray(v.asScala.toList.map({ elem => toLift(elem) }))
|
||||||
case v: ConfigBoolean =>
|
case v: ConfigBoolean =>
|
||||||
lift.JBool(v.unwrapped())
|
lift.JBool(v.unwrapped())
|
||||||
case v: ConfigInt =>
|
case v: ConfigInt =>
|
||||||
|
Loading…
Reference in New Issue
Block a user