Merge pull request #257 from typesafehub/duration

Support java.time.Duration getters on Config
This commit is contained in:
Havoc Pennington 2015-02-26 08:55:48 -05:00
commit a73fe1f1e9
5 changed files with 73 additions and 0 deletions

View File

@ -3,6 +3,7 @@
*/
package com.typesafe.config;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -673,6 +674,28 @@ public interface Config extends ConfigMergeable {
*/
long getDuration(String path, TimeUnit unit);
/**
* Gets a value as a java.time.Duration. If the value is
* already a number, then it's taken as milliseconds; if it's
* a string, it's parsed understanding units suffixes like
* "10m" or "5ns" as documented in the <a
* href="https://github.com/typesafehub/config/blob/master/HOCON.md">the
* spec</a>. This method never returns null.
*
* @since 1.3.0
*
* @param path
* path expression
* @return the duration value at the requested path
* @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
*/
Duration getDuration(String path);
/**
* Gets a list value (with any element type) as a {@link ConfigList}, which
* implements {@code java.util.List<ConfigValue>}. Throws if the path is
@ -742,6 +765,17 @@ public interface Config extends ConfigMergeable {
*/
List<Long> getDurationList(String path, TimeUnit unit);
/**
* Gets a list, converting each value in the list to a duration, using the
* same rules as {@link #getDuration(String)}.
*
* @since 1.3.0
* @param path
* a path expression
* @return list of durations
*/
List<Duration> getDurationList(String path);
/**
* Clone the config with only the given path (and its children) retained;
* all sibling paths are removed.

View File

@ -6,6 +6,7 @@ package com.typesafe.config.impl;
import java.io.File;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -241,6 +242,8 @@ public class ConfigImpl {
return ConfigNumber.newNumber(origin,
((Number) object).doubleValue(), null);
}
} else if (object instanceof Duration) {
return new ConfigLong(origin, ((Duration) object).toMillis(), null);
} else if (object instanceof Map) {
if (((Map<?, ?>) object).isEmpty())
return emptyObject(origin);

View File

@ -7,6 +7,7 @@ import java.io.ObjectStreamException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Duration;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
@ -272,6 +273,13 @@ final class SimpleConfig implements Config, MergeableValue, Serializable {
return result;
}
@Override
public Duration getDuration(String path) {
ConfigValue v = find(path, ConfigValueType.STRING);
long nanos = parseDuration((String) v.unwrapped(), v.origin(), path);
return Duration.ofNanos(nanos);
}
@SuppressWarnings("unchecked")
private <T> List<T> getHomogeneousUnwrappedList(String path,
ConfigValueType expected) {
@ -437,6 +445,16 @@ final class SimpleConfig implements Config, MergeableValue, Serializable {
return l;
}
@Override
public List<Duration> getDurationList(String path) {
List<Long> l = getDurationList(path, TimeUnit.NANOSECONDS);
List<Duration> builder = new ArrayList<Duration>(l.size());
for (Long value : l) {
builder.add(Duration.ofNanos(value));
}
return builder;
}
@Deprecated
@Override
public List<Long> getMillisecondsList(String path) {

View File

@ -769,6 +769,17 @@ class ConfigTest extends TestUtils {
conf.getNanosecondsList("durations.secondsList").asScala)
assertEquals(500L, conf.getMilliseconds("durations.halfSecond"))
// get durations as java.time.Duration
assertEquals(1000L, conf.getDuration("durations.second").toMillis)
assertEquals(asNanos(1), conf.getDuration("durations.second").toNanos)
assertEquals(1000L, conf.getDuration("durations.secondAsNumber").toMillis)
assertEquals(asNanos(1), conf.getDuration("durations.secondAsNumber").toNanos)
assertEquals(Seq(1000L, 2000L, 3000L, 4000L),
conf.getDurationList("durations.secondsList").asScala.map(_.toMillis))
assertEquals(Seq(asNanos(1), asNanos(2), asNanos(3), asNanos(4)),
conf.getDurationList("durations.secondsList").asScala.map(_.toNanos))
assertEquals(500L, conf.getDuration("durations.halfSecond").toMillis)
def assertDurationAsTimeUnit(unit: TimeUnit): Unit = {
def ms2unit(l: Long) = unit.convert(l, MILLISECONDS)
def s2unit(i: Int) = unit.convert(i, SECONDS)

View File

@ -14,6 +14,7 @@ import scala.collection.mutable
import equiv03.SomethingInEquiv03
import java.io.StringReader
import java.net.URL
import java.time.Duration
class PublicApiTest extends TestUtils {
@Test
@ -175,6 +176,12 @@ class PublicApiTest extends TestUtils {
testFromValue(longValue(512), ConfigMemorySize.ofBytes(512));
}
@Test
def fromDuration() {
testFromValue(longValue(1000), Duration.ofMillis(1000));
testFromValue(longValue(1000*60*60*24), Duration.ofDays(1));
}
@Test
def roundTripUnwrap() {
val conf = ConfigFactory.load("test01")