From 217fced7e1c29a08658a6b274e67c570c0fcbfc8 Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 11 Jun 2018 05:38:44 +0100 Subject: [PATCH 1/3] Rearrange methods on Configuration, so non-static methods come first and the various factories sit at the end. --- .../java/co/unruly/config/Configuration.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/main/java/co/unruly/config/Configuration.java b/src/main/java/co/unruly/config/Configuration.java index 9909849..7ebb061 100644 --- a/src/main/java/co/unruly/config/Configuration.java +++ b/src/main/java/co/unruly/config/Configuration.java @@ -21,10 +21,6 @@ public Configuration(ConfigurationSource map) { this.func = map; } - public static Configuration from(ConfigurationSource func) { - return new Configuration(func); - } - public Optional get(String s) { return Optional.ofNullable(func.get(s)); } @@ -33,9 +29,17 @@ public Configuration or(ConfigurationSource next) { return new Configuration(this.func.or(next)); } + public static Configuration from(ConfigurationSource func) { + return new Configuration(func); + } + + public static Configuration of(ConfigurationSource... sources) { + return new Configuration(Stream.of(sources).reduce(FIND_NOTHING, ConfigurationSource::or)); + } + public static ConfigurationSource map(Map map){ return map::get; - }; + } public static ConfigurationSource properties(String s) { Properties properties = new Properties(); @@ -46,13 +50,12 @@ public static ConfigurationSource properties(String s) { return properties::getProperty; } + public static ConfigurationSource properties(Properties properties) { + return properties::getProperty; + } public static ConfigurationSource environment() { return (key) -> System.getenv(key.toUpperCase()); } - - public static Configuration of(ConfigurationSource... sources) { - return new Configuration(Stream.of(sources).reduce(FIND_NOTHING, ConfigurationSource::or)); - } } From 486a4f3e68db83faf5cb52dfa2eb2f7eecab7bfa Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 11 Jun 2018 05:57:00 +0100 Subject: [PATCH 2/3] Add methods to Configuration to more easily express the default-value and throw-if-absent modes --- .../java/co/unruly/config/Configuration.java | 8 ++++++++ .../co/unruly/config/ConfigurationMissing.java | 8 ++++++++ .../co/unruly/config/ConfigurationTest.java | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/main/java/co/unruly/config/ConfigurationMissing.java diff --git a/src/main/java/co/unruly/config/Configuration.java b/src/main/java/co/unruly/config/Configuration.java index 7ebb061..1d1206d 100644 --- a/src/main/java/co/unruly/config/Configuration.java +++ b/src/main/java/co/unruly/config/Configuration.java @@ -25,6 +25,14 @@ public Optional get(String s) { return Optional.ofNullable(func.get(s)); } + public String get(String s, String defaultValue) { + return get(s).orElse(defaultValue); + } + + public String require(String s) { + return get(s).orElseThrow(() -> new ConfigurationMissing(s)); + } + public Configuration or(ConfigurationSource next) { return new Configuration(this.func.or(next)); } diff --git a/src/main/java/co/unruly/config/ConfigurationMissing.java b/src/main/java/co/unruly/config/ConfigurationMissing.java new file mode 100644 index 0000000..5efc2bb --- /dev/null +++ b/src/main/java/co/unruly/config/ConfigurationMissing.java @@ -0,0 +1,8 @@ +package co.unruly.config; + +public class ConfigurationMissing extends RuntimeException { + + public ConfigurationMissing(String property) { + super(property + " not found in configuration"); + } +} diff --git a/src/test/java/co/unruly/config/ConfigurationTest.java b/src/test/java/co/unruly/config/ConfigurationTest.java index 575f329..3369409 100644 --- a/src/test/java/co/unruly/config/ConfigurationTest.java +++ b/src/test/java/co/unruly/config/ConfigurationTest.java @@ -27,6 +27,24 @@ public void shouldReturnEmptyOptionalIfValueNotFound() { assertThat(config.get("some-variable"), is(empty())); } + @Test + public void shouldReturnDefaultValueIfProvidedAndValueNotFound() { + Map input = Collections.emptyMap(); + + Configuration config = Configuration.from(map(input)); + + assertThat(config.get("some-variable", "default-value"), is("default-value")); + } + + @Test(expected = ConfigurationMissing.class) + public void shouldThrowIfRequiredValueNotFound() { + Map input = Collections.emptyMap(); + + Configuration config = Configuration.from(map(input)); + + config.require("some-variable"); + } + @Test public void shouldReturnOptionalIfValueIsPresent() { Map input = new HashMap<>(); From 08e2142387b63900f689f7b949ffd2f342f0f3ef Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 11 Jun 2018 10:14:38 +0100 Subject: [PATCH 3/3] Add documentation for the different access patterns --- README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fd7366a..75ea6d8 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,21 @@ Configuration config = Configuration.of( map(credentials) ); -// look in properties file first, else look in the map. -String username = config.get("username"); +// look in properties file first, else look in the map, +// and if still not found, return Optional.empty() +Optional username = config.get("username"); +``` + +You can also provide a use-site default value: + +```java +String username = config.get("username", "Titus Andromedon"); +``` + +Or state that a value is _required_, and throw a `ConfigurationMissing` exception if if is not defined: + +```java +String username = config.require("username"); ``` ## Configuration Sources