From c5da9ec26b80622bc6a2247f2114cd24611a87b8 Mon Sep 17 00:00:00 2001 From: "Luigi R. Viggiano" Date: Wed, 4 Dec 2013 01:26:50 +0100 Subject: [PATCH] implemented variable expansion in @Key annotation. See issue #63. --- .../owner/PropertiesInvocationHandler.java | 9 +- .../org/aeonbits/owner/util/EntryMap.java | 53 +++++++ .../org/aeonbits/owner/util/package-info.java | 12 ++ .../variableexpansion/KeyExpansionTest.java | 134 ++++++++++++++++++ .../variableexpansion/KeyExpansionExample.xml | 16 +++ 5 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 owner/src/main/java/org/aeonbits/owner/util/EntryMap.java create mode 100644 owner/src/main/java/org/aeonbits/owner/util/package-info.java create mode 100644 owner/src/test/java/org/aeonbits/owner/variableexpansion/KeyExpansionTest.java create mode 100644 owner/src/test/resources/org/aeonbits/owner/variableexpansion/KeyExpansionExample.xml diff --git a/owner/src/main/java/org/aeonbits/owner/PropertiesInvocationHandler.java b/owner/src/main/java/org/aeonbits/owner/PropertiesInvocationHandler.java index 21ee858c..2006a60f 100644 --- a/owner/src/main/java/org/aeonbits/owner/PropertiesInvocationHandler.java +++ b/owner/src/main/java/org/aeonbits/owner/PropertiesInvocationHandler.java @@ -76,7 +76,7 @@ private boolean equals(Method a, Method b) { } private Object resolveProperty(Method method, Object... args) { - String key = key(method); + String key = expandKey(method); String value = propertiesManager.getProperty(key); if (value == null) return null; @@ -85,6 +85,13 @@ private Object resolveProperty(Method method, Object... args) { return result; } + private String expandKey(Method method) { + String key = key(method); + if (isFeatureDisabled(method, VARIABLE_EXPANSION)) + return key; + return substitutor.replace(key); + } + private String format(Method method, String format, Object... args) { if (isFeatureDisabled(method, PARAMETER_FORMATTING)) return format; diff --git a/owner/src/main/java/org/aeonbits/owner/util/EntryMap.java b/owner/src/main/java/org/aeonbits/owner/util/EntryMap.java new file mode 100644 index 00000000..bb8bfa3a --- /dev/null +++ b/owner/src/main/java/org/aeonbits/owner/util/EntryMap.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013, Luigi R. Viggiano + * All rights reserved. + * + * This software is distributable under the BSD license. + * See the terms of the BSD license in the documentation provided with this software. + */ + +package org.aeonbits.owner.util; + +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.Set; + +import static java.util.Arrays.asList; +import static java.util.Collections.unmodifiableSet; + +/** + * Utility class to create a Map from a single entry (key-value pair). + * + *

+ * Example of usage: + *

+ * + *
+ * import static org.aeonbits.owner.util.EntryMap.map;
+ *
+ * Map<String, String> myMap = map("foo", "bar");
+ *
+ * String bar = myMap.get("foo");
+ * 
+ * + * @since 1.0.6 + * @author Luigi R. Viggiano + */ +public class EntryMap extends AbstractMap { + private final Entry entry; + private final Set> entrySet; + + private EntryMap(final K key, final V value) { + entry = new SimpleEntry(key, value); + entrySet = unmodifiableSet(new HashSet>(asList(entry))); + } + + @Override + public Set> entrySet() { + return entrySet; + } + + public static EntryMap map(K key, V value) { + return new EntryMap(key, value); + } +} diff --git a/owner/src/main/java/org/aeonbits/owner/util/package-info.java b/owner/src/main/java/org/aeonbits/owner/util/package-info.java new file mode 100644 index 00000000..a301deb6 --- /dev/null +++ b/owner/src/main/java/org/aeonbits/owner/util/package-info.java @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2013, Luigi R. Viggiano + * All rights reserved. + * + * This software is distributable under the BSD license. + * See the terms of the BSD license in the documentation provided with this software. + */ + +/** + * Provides utility interfaces and classes. + */ +package org.aeonbits.owner.util; diff --git a/owner/src/test/java/org/aeonbits/owner/variableexpansion/KeyExpansionTest.java b/owner/src/test/java/org/aeonbits/owner/variableexpansion/KeyExpansionTest.java new file mode 100644 index 00000000..0226f9ad --- /dev/null +++ b/owner/src/test/java/org/aeonbits/owner/variableexpansion/KeyExpansionTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013, Luigi R. Viggiano + * All rights reserved. + * + * This software is distributable under the BSD license. + * See the terms of the BSD license in the documentation provided with this software. + */ + +package org.aeonbits.owner.variableexpansion; + +import org.aeonbits.owner.Config; +import org.aeonbits.owner.Config.DisableFeature; +import org.aeonbits.owner.Config.Sources; +import org.aeonbits.owner.ConfigFactory; +import org.junit.Test; + +import static org.aeonbits.owner.Config.DisableableFeature.VARIABLE_EXPANSION; +import static org.aeonbits.owner.util.EntryMap.map; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +/** + * @author Luigi R. Viggiano + */ +public class KeyExpansionTest { + + + @Sources("classpath:org/aeonbits/owner/variableexpansion/KeyExpansionExample.xml") + public interface MyConfig extends Config { + @Key("servers.${env}.name") + String name(); + + @Key("servers.${env}.hostname") + String hostname(); + + @Key("servers.${env}.port") + Integer port(); + + @Key("servers.${env}.user") + String user(); + + @DisableFeature(VARIABLE_EXPANSION) + @Key("servers.${env}.password") + String password(); + } + + @Test + public void testKeyExpansion() { + MyConfig cfg = ConfigFactory.create(MyConfig.class, map("env", "dev")); + + assertEquals("DEV", cfg.name()); + assertEquals("devhost", cfg.hostname()); + assertEquals(new Integer(6000), cfg.port()); + assertEquals("myuser1", cfg.user()); + assertNull(cfg.password()); // expansion is disabled on method level + } + + @DisableFeature(VARIABLE_EXPANSION) + @Sources("classpath:org/aeonbits/owner/variableexpansion/KeyExpansionExample.xml") + public interface MyConfigWithExpansionDisabled extends Config { + @Key("servers.${env}.name") + String name(); + + @Key("servers.${env}.hostname") + String hostname(); + + @Key("servers.${env}.port") + Integer port(); + + @Key("servers.${env}.user") + String user(); + + @Key("servers.${env}.password") + String password(); + } + + @Test + public void testKeyExpansionDisabled() { + MyConfigWithExpansionDisabled cfg = + ConfigFactory.create(MyConfigWithExpansionDisabled.class, map("env", "dev")); + + assertNull(cfg.name()); + assertNull(cfg.hostname()); + assertNull(cfg.port()); + assertNull(cfg.user()); + assertNull(cfg.password()); + } + + @Sources("classpath:org/aeonbits/owner/variableexpansion/KeyExpansionExample.xml") + public interface ExpandsFromAnotherKey extends Config { + + @DefaultValue("dev") + String env(); + + @Key("servers.${env}.name") + String name(); + + @Key("servers.${env}.hostname") + String hostname(); + + @Key("servers.${env}.port") + Integer port(); + + @Key("servers.${env}.user") + String user(); + + @DisableFeature(VARIABLE_EXPANSION) + @Key("servers.${env}.password") + String password(); + } + + @Test + public void testKeyExpansionFromAnotherKey() { + ExpandsFromAnotherKey cfg = ConfigFactory.create(ExpandsFromAnotherKey.class); + + assertEquals("DEV", cfg.name()); + assertEquals("devhost", cfg.hostname()); + assertEquals(new Integer(6000), cfg.port()); + assertEquals("myuser1", cfg.user()); + assertNull(cfg.password()); // expansion is disabled on method level + } + + @Test + public void testKeyExpansionFromAnotherKeyWithImportOverriding() { + ExpandsFromAnotherKey cfg = ConfigFactory.create(ExpandsFromAnotherKey.class, map("env", "uat")); + + assertEquals("UAT", cfg.name()); + assertEquals("uathost", cfg.hostname()); + assertEquals(new Integer(60020), cfg.port()); + assertEquals("myuser2", cfg.user()); + assertNull("mypass2", cfg.password()); // expansion is disabled on method level + } + +} diff --git a/owner/src/test/resources/org/aeonbits/owner/variableexpansion/KeyExpansionExample.xml b/owner/src/test/resources/org/aeonbits/owner/variableexpansion/KeyExpansionExample.xml new file mode 100644 index 00000000..61e5aaef --- /dev/null +++ b/owner/src/test/resources/org/aeonbits/owner/variableexpansion/KeyExpansionExample.xml @@ -0,0 +1,16 @@ + + + DEV + devhost + 6000 + myuser1 + mypass1 + + + UAT + uathost + 60020 + myuser2 + mypass2 + +