You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2021/08/25 18:35:33 UTC
[commons-configuration] branch master updated: Add
ImmutableConfiguration.getDuration() methods.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-configuration.git
The following commit(s) were added to refs/heads/master by this push:
new 01bae76 Add ImmutableConfiguration.getDuration() methods.
01bae76 is described below
commit 01bae769673fbe8a2cbbf0591f4b455f7ca76d7b
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Wed Aug 25 14:35:30 2021 -0400
Add ImmutableConfiguration.getDuration() methods.
---
src/changes/changes.xml | 3 +
.../configuration2/AbstractConfiguration.java | 11 +
.../configuration2/ImmutableConfiguration.java | 35 ++
.../configuration2/convert/PropertyConverter.java | 30 +-
.../configuration2/TestBaseConfiguration.java | 24 ++
.../TestDefaultImmutableConfiguration.java | 369 +++++++++++++++++++++
6 files changed, 470 insertions(+), 2 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 239be52..707f719 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -75,6 +75,9 @@
<action type="add" dev="ggregory" issue="CONFIGURATION-789" due-to="Gary Gregory">
Add ImmutableConfiguration.getEnum() methods.
</action>
+ <action type="add" dev="ggregory" issue="CONFIGURATION-789" due-to="Gary Gregory">
+ Add ImmutableConfiguration.getDuration() methods.
+ </action>
<!-- UPDATES -->
<action type="update" dev="ggregory" issue="CONFIGURATION-787" due-to="Gary Gregory">
Update from Apache Commons Lang 3.9 to 3.12.0.
diff --git a/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java b/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java
index 3c0e526..3cde89c 100644
--- a/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java
+++ b/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.commons.configuration2;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -987,6 +988,16 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C
}
@Override
+ public Duration getDuration(final String key) {
+ return checkNonNullValue(key, convert(Duration.class, key, null, true));
+ }
+
+ @Override
+ public Duration getDuration(final String key, final Duration defaultValue) {
+ return convert(Duration.class, key, defaultValue, false);
+ }
+
+ @Override
public float getFloat(final String key) {
final Float f = convert(Float.class, key, null, true);
return checkNonNullValue(key, f).floatValue();
diff --git a/src/main/java/org/apache/commons/configuration2/ImmutableConfiguration.java b/src/main/java/org/apache/commons/configuration2/ImmutableConfiguration.java
index 1ba0052..96da9a1 100644
--- a/src/main/java/org/apache/commons/configuration2/ImmutableConfiguration.java
+++ b/src/main/java/org/apache/commons/configuration2/ImmutableConfiguration.java
@@ -18,11 +18,14 @@ package org.apache.commons.configuration2;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.time.Duration;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.Properties;
+import org.apache.commons.configuration2.convert.PropertyConverter;
import org.apache.commons.configuration2.ex.ConversionException;
/**
@@ -309,6 +312,38 @@ public interface ImmutableConfiguration {
Double getDouble(String key, Double defaultValue);
/**
+ * Gets a {@link Duration} associated with the given configuration key.
+ *
+ * @param key The configuration key.
+ * @return The associated Duration if key is found and has valid format, default value otherwise.
+ * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
+ * Duration.
+ * @since 2.8.0
+ */
+ default Duration getDuration(final String key) {
+ final String string = getString(key);
+ if (string == null) {
+ throw new NoSuchElementException(key);
+ }
+ return PropertyConverter.toDuration(string);
+ }
+
+ /**
+ * Gets a {@link Duration} associated with the given configuration key.
+ *
+ * @param key The configuration key.
+ * @param defaultValue The default value.
+ * @return The associated Duration if key is found and has valid format, default value otherwise.
+ * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
+ * Duration.
+ * @since 2.8.0
+ */
+ default Duration getDuration(final String key, final Duration defaultValue) {
+ Object value = getProperty(key);
+ return value == null ? defaultValue : PropertyConverter.toDuration(value);
+ }
+
+ /**
* Gets the value of a string property that is stored in encoded form in this configuration using a default
* {@code ConfigurationDecoder}. This method works like the method with the same name, but it uses a default
* {@code ConfigurationDecoder} associated with this configuration. It depends on a specific implementation how this
diff --git a/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java b/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java
index b3e53c2..b018193 100644
--- a/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java
+++ b/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java
@@ -33,6 +33,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.time.format.DateTimeParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
@@ -46,9 +48,9 @@ import org.apache.commons.lang3.StringUtils;
/**
* A utility class to convert the configuration properties into any type.
*
- * @since 1.1
+ * @since 2.8.0
*/
-final class PropertyConverter {
+public final class PropertyConverter {
/** Constant for the prefix of hex numbers. */
private static final String HEX_PREFIX = "0x";
@@ -150,6 +152,8 @@ final class PropertyConverter {
return toInternetAddress(value);
} else if (InetAddress.class.isAssignableFrom(cls)) {
return toInetAddress(value);
+ } else if (Duration.class.equals(cls)) {
+ return toDuration(value);
}
throw new ConversionException("The value '" + value + "' (" + value.getClass() + ")" + " can't be converted to a " + cls.getName() + " object");
@@ -286,6 +290,28 @@ final class PropertyConverter {
}
/**
+ * Convert the specified object into a Duration.
+ *
+ * @param value the value to convert
+ * @return the converted value
+ * @throws ConversionException thrown if the value cannot be converted to a Duration
+ * @since 2.8.0
+ */
+ public static Duration toDuration(final Object value) throws ConversionException {
+ if (value instanceof Duration) {
+ return (Duration) value;
+ }
+ if (value instanceof CharSequence) {
+ try {
+ return Duration.parse((CharSequence) value);
+ } catch (DateTimeParseException e) {
+ throw new ConversionException("Could not convert " + value + " to Duration", e);
+ }
+ }
+ throw new ConversionException("The value " + value + " can't be converted to a Duration");
+ }
+
+ /**
* Convert the specified object into a BigInteger.
*
* @param value the value to convert
diff --git a/src/test/java/org/apache/commons/configuration2/TestBaseConfiguration.java b/src/test/java/org/apache/commons/configuration2/TestBaseConfiguration.java
index 8e98d25..12eb7c0 100644
--- a/src/test/java/org/apache/commons/configuration2/TestBaseConfiguration.java
+++ b/src/test/java/org/apache/commons/configuration2/TestBaseConfiguration.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -308,6 +309,29 @@ public class TestBaseConfiguration {
}
@Test
+ public void testGetDuration() {
+ final Duration d = Duration.ofSeconds(1);
+ config.setProperty("durationD", d.toString());
+ final Duration oneD = Duration.ofSeconds(1);
+ final Duration twoD = Duration.ofSeconds(2);
+ assertEquals("This returns 1(Duration)", oneD, config.getDuration("durationD"));
+ assertEquals("This returns 1(Duration)", oneD, config.getDuration("durationD", twoD));
+ assertEquals("This returns 2(default Duration)", twoD, config.getDuration("numberNotInConfig", twoD));
+ assertEquals("This returns 1(Duration)", oneD, config.getDuration("durationD", twoD));
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testGetDurationIncompatibleType() {
+ config.setProperty("test.empty", "");
+ config.getDuration("test.empty");
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void testGetDurationUnknown() {
+ config.getDuration("numberNotInConfig");
+ }
+
+ @Test
public void testGetEnum() {
config.setProperty("testEnum", EnumFixture.SMALLTALK.name());
config.setProperty("testBadEnum", "This is not an enum value.");
diff --git a/src/test/java/org/apache/commons/configuration2/TestDefaultImmutableConfiguration.java b/src/test/java/org/apache/commons/configuration2/TestDefaultImmutableConfiguration.java
new file mode 100644
index 0000000..d0b97f3
--- /dev/null
+++ b/src/test/java/org/apache/commons/configuration2/TestDefaultImmutableConfiguration.java
@@ -0,0 +1,369 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.configuration2;
+
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Duration;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Properties;
+
+import org.apache.commons.configuration2.ex.ConversionException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link ImmutableConfiguration} default methods.
+ */
+public class TestDefaultImmutableConfiguration {
+
+ /** Tests default methods. This class MUST NOT override the default methods! */
+ private class MapImmutableConfiguration implements ImmutableConfiguration {
+
+ Map<String, Object> map = new HashMap<>();
+
+ @Override
+ public boolean containsKey(final String key) {
+ // Super is not a default method.
+ return false;
+ }
+
+ @Override
+ public <T> T get(final Class<T> cls, final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public <T> T get(final Class<T> cls, final String key, final T defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public Object getArray(final Class<?> cls, final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public Object getArray(final Class<?> cls, final String key, final Object defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(final String key, final BigDecimal defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public BigInteger getBigInteger(final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public BigInteger getBigInteger(final String key, final BigInteger defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public boolean getBoolean(final String key) {
+ // Super is not a default method.
+ return false;
+ }
+
+ @Override
+ public boolean getBoolean(final String key, final boolean defaultValue) {
+ // Super is not a default method.
+ return false;
+ }
+
+ @Override
+ public Boolean getBoolean(final String key, final Boolean defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public byte getByte(final String key) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public byte getByte(final String key, final byte defaultValue) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public Byte getByte(final String key, final Byte defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public <T> Collection<T> getCollection(final Class<T> cls, final String key, final Collection<T> target) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public <T> Collection<T> getCollection(final Class<T> cls, final String key, final Collection<T> target, final Collection<T> defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public double getDouble(final String key) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public double getDouble(final String key, final double defaultValue) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public Double getDouble(final String key, final Double defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public String getEncodedString(final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public String getEncodedString(final String key, final ConfigurationDecoder decoder) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public float getFloat(final String key) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public float getFloat(final String key, final float defaultValue) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public Float getFloat(final String key, final Float defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public int getInt(final String key) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public int getInt(final String key, final int defaultValue) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public Integer getInteger(final String key, final Integer defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public Iterator<String> getKeys() {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public Iterator<String> getKeys(final String prefix) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public <T> List<T> getList(final Class<T> cls, final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public <T> List<T> getList(final Class<T> cls, final String key, final List<T> defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public List<Object> getList(final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public List<Object> getList(final String key, final List<?> defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public long getLong(final String key) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public long getLong(final String key, final long defaultValue) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public Long getLong(final String key, final Long defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public Properties getProperties(final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public Object getProperty(final String key) {
+ // Super is not a default method.
+ return map.get(key);
+ }
+
+ @Override
+ public short getShort(final String key) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public short getShort(final String key, final short defaultValue) {
+ // Super is not a default method.
+ return 0;
+ }
+
+ @Override
+ public Short getShort(final String key, final Short defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public String getString(final String key) {
+ return Objects.toString(map.get(key), null);
+ }
+
+ @Override
+ public String getString(final String key, final String defaultValue) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public String[] getStringArray(final String key) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public ImmutableConfiguration immutableSubset(final String prefix) {
+ // Super is not a default method.
+ return null;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ // Super is not a default method.
+ return false;
+ }
+
+ @Override
+ public int size() {
+ // Super is not a default method.
+ return 0;
+ }
+
+ }
+
+ private final MapImmutableConfiguration config = new MapImmutableConfiguration();
+
+ @Before
+ @After
+ public void clearMap() {
+ config.map.clear();
+ }
+
+ @Test
+ public void testGetDuration() {
+ final Duration d = Duration.ofSeconds(1);
+ config.map.put("durationD", d.toString());
+ final Duration oneD = Duration.ofSeconds(1);
+ final Duration twoD = Duration.ofSeconds(2);
+ assertEquals("This returns 1(Duration)", oneD, config.getDuration("durationD"));
+ assertEquals("This returns 1(Duration)", oneD, config.getDuration("durationD", twoD));
+ assertEquals("This returns 2(default Duration)", twoD, config.getDuration("numberNotInConfig", twoD));
+ assertEquals("This returns 1(Duration)", oneD, config.getDuration("durationD", twoD));
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testGetDurationIncompatibleType() {
+ config.map.put("test.empty", "");
+ config.getDuration("test.empty");
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void testGetDurationUnknown() {
+ config.getDuration("numberNotInConfig");
+ }
+
+}