This commit is contained in:
Marconi Lanna 2017-11-06 19:08:48 +00:00 committed by GitHub
commit 3d5d65c410
5 changed files with 149 additions and 57 deletions

View File

@ -803,7 +803,7 @@ public interface Config extends ConfigMergeable {
* href="https://github.com/lightbend/config/blob/master/HOCON.md">the
* spec</a>. This method never returns null.
*
* @since 1.3.0
* @since 1.3.2
*
* @param path
* path expression
@ -822,7 +822,11 @@ public interface Config extends ConfigMergeable {
* This method will first try get get the value as a java.time.Duration, and if unsuccessful,
* then as a java.time.Period.
* This means that values like "5m" will be parsed as 5 minutes rather than 5 months
* @param path path expression
*
* @since 1.3.2
*
* @param path
* path expression
* @return the temporal value at the requested path
* @throws ConfigException.Missing
* if value is absent or null
@ -1070,6 +1074,43 @@ public interface Config extends ConfigMergeable {
*/
List<Duration> getDurationList(String path);
/**
* Gets a list, converting each value in the list to a period,
* using same rules as {@link #getPeriod(String)}.
*
* @since 1.3.3
*
* @param path
* path expression
* @return list of periods
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to Long or String
* @throws ConfigException.BadValue
* if value cannot be parsed as a number of the given TimeUnit
*/
List<Period> getPeriodList(String path);
/**
* Gets a list, converting each value in the list to a temporal amount,
* using the same rules as {@link #getTemporal(String)}.
*
* @since 1.3.3
*
* @param path
* path expression
* @return list of temporal values
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to Long or String
* @throws ConfigException.BadValue
* if value cannot be parsed as a TemporalAmount
*/
List<TemporalAmount> getTemporalList(String path);
/**
* Clone the config with only the given path (and its children) retained;
* all sibling paths are removed.

View File

@ -545,6 +545,50 @@ final class SimpleConfig implements Config, MergeableValue, Serializable {
return builder;
}
@Override
public List<Period> getPeriodList(String path) {
List<Period> l = new ArrayList<Period>();
List<? extends ConfigValue> list = getList(path);
for (ConfigValue v : list) {
String value;
if (v.valueType() == ConfigValueType.STRING) {
value = (String) v.unwrapped();
} else if (v.valueType() == ConfigValueType.NUMBER) {
value = "" + ((Number) v.unwrapped()).longValue();
} else {
throw new ConfigException.WrongType(v.origin(), path,
"period string",
v.valueType().name());
}
l.add(parsePeriod(value, v.origin(), path));
}
return l;
}
@Override
public List<TemporalAmount> getTemporalList(String path) {
List<TemporalAmount> l = new ArrayList<TemporalAmount>();
List<? extends ConfigValue> list = getList(path);
for (ConfigValue v : list) {
String value;
if (v.valueType() == ConfigValueType.STRING) {
value = (String) v.unwrapped();
} else if (v.valueType() == ConfigValueType.NUMBER) {
value = "" + ((Number) v.unwrapped()).longValue();
} else {
throw new ConfigException.WrongType(v.origin(), path,
"duration or period string",
v.valueType().name());
}
try{
l.add(Duration.ofNanos(parseDuration(value, v.origin(), path)));
} catch (ConfigException.BadValue e){
l.add(parsePeriod(value, v.origin(), path));
}
}
return l;
}
@Deprecated
@Override
public List<Long> getMillisecondsList(String path) {

View File

@ -38,6 +38,8 @@
"ofBoolean" : [true, false],
"ofArray" : [${arrays.ofString}, ${arrays.ofString}, ${arrays.ofString}],
"ofObject" : [${ints}, ${booleans}, ${strings}],
"ofPeriod" : [1d, 2, 3 weeks, 5 mo, 8y],
"ofTemporal" : [1d, 2, 3 weeks, 5 mo, 8y, 13m],
"firstElementNotASubst" : [ "a", ${strings.b} ]
},

View File

@ -3,7 +3,8 @@
*/
package com.typesafe.config.impl
import java.time.temporal.{ ChronoUnit, TemporalUnit }
import java.time.{ Duration, Period }
import java.time.temporal.ChronoUnit
import org.junit.Assert._
import org.junit._
@ -602,6 +603,10 @@ class ConfigTest extends TestUtils {
val listOfLists = conf.getAnyRefList("arrays.ofArray").asScala map { _.asInstanceOf[java.util.List[_]].asScala }
assertEquals(Seq(Seq("a", "b", "c"), Seq("a", "b", "c"), Seq("a", "b", "c")), listOfLists)
assertEquals(3, conf.getObjectList("arrays.ofObject").asScala.length)
val listOfPeriods = Seq(Period.ofDays(1), Period.ofDays(2), Period.ofWeeks(3), Period.ofMonths(5), Period.ofYears(8))
assertEquals(listOfPeriods, conf.getPeriodList("arrays.ofPeriod").asScala)
val listOfTemporals = Seq(Duration.ofHours(24), Duration.ofMillis(2), Period.ofWeeks(3), Period.ofMonths(5), Period.ofYears(8), Duration.ofMinutes(13))
assertEquals(listOfTemporals, conf.getTemporalList("arrays.ofTemporal").asScala)
assertEquals(Seq("a", "b"), conf.getStringList("arrays.firstElementNotASubst").asScala)

View File

@ -280,13 +280,13 @@ class ConfigValueTest extends TestUtils {
}
/**
* Reproduces the issue <a href=https://github.com/lightbend/config/issues/461>#461</a>.
* <p>
* We use a custom de-/serializer that encodes String objects in a JDK-incompatible way. Encoding used here
* is rather simplistic: a long indicating the length in bytes (JDK uses a variable length integer) followed
* by the string's bytes. Running this test with the original SerializedConfigValue.readExternal()
* implementation results in an EOFException thrown during deserialization.
*/
* Reproduces the issue <a href=https://github.com/lightbend/config/issues/461>#461</a>.
* <p>
* We use a custom de-/serializer that encodes String objects in a JDK-incompatible way. Encoding used here
* is rather simplistic: a long indicating the length in bytes (JDK uses a variable length integer) followed
* by the string's bytes. Running this test with the original SerializedConfigValue.readExternal()
* implementation results in an EOFException thrown during deserialization.
*/
@Test
def configConfigCustomSerializable() {
val aMap = configMap("a" -> 1, "b" -> 2, "c" -> 3)