Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement map based properties per issue #41. #52

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/main/java/org/aeonbits/owner/Config.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ public interface Config {
String value();
}

/**
* The key used for map properties (map1 in map1.value1). If not present, values such as map1.value1 will be treated as standard properties.
*/
@Retention(RUNTIME)
@Target(METHOD)
@Documented
@interface MapValue {
String value();
}

/**
* Specifies the policy type to use to load the {@link org.aeonbits.owner.Config.Sources} files for properties.
*
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/org/aeonbits/owner/PropertiesInvocationHandler.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static org.aeonbits.owner.Config.DisableableFeature.PARAMETER_FORMATTING;
import static org.aeonbits.owner.Config.DisableableFeature.VARIABLE_EXPANSION;
Expand Down Expand Up @@ -74,12 +75,16 @@ private boolean equals(Method a, Method b) {

private Object resolveProperty(Method method, Object... args) {
String key = key(method);
String value = propertiesManager.getProperty(key);
if (value == null)
return null;
Object result = convert(method, method.getReturnType(), format(method, expandVariables(method, value), args));
if (result == Converters.NULL) return null;
return result;
if (method.getReturnType().equals(Map.class)) {
return propertiesManager.getObject(key);
} else {
String value = propertiesManager.getProperty(key);
if (value == null)
return null;
Object result = convert(method, method.getReturnType(), format(method, expandVariables(method, value), args));
if (result == Converters.NULL) return null;
return result;
}
}

private String format(Method method, String format, Object... args) {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/aeonbits/owner/PropertiesManager.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import static java.util.Collections.synchronizedList;
import static org.aeonbits.owner.Config.LoadType.FIRST;
import static org.aeonbits.owner.PropertiesMapper.defaults;
import static org.aeonbits.owner.PropertiesMapper.mapValues;
import static org.aeonbits.owner.Util.asString;
import static org.aeonbits.owner.Util.eq;
import static org.aeonbits.owner.Util.ignore;
Expand Down Expand Up @@ -170,6 +171,7 @@ private Properties load(Properties props) {
loading = true;
defaults(props, clazz);
Properties loadedFromFile = doLoad();
mapValues(loadedFromFile, props, clazz);
merge(props, loadedFromFile);
merge(props, reverse(imports));
return props;
Expand Down Expand Up @@ -289,6 +291,15 @@ private static void merge(Properties results, Map<?, ?>... inputs) {
results.putAll(input);
}

public Object getObject(String key) {
readLock.lock();
try {
return properties.get(key);
} finally {
readLock.unlock();
}
}

@Delegate
public String getProperty(String key) {
readLock.lock();
Expand Down
31 changes: 30 additions & 1 deletion src/main/java/org/aeonbits/owner/PropertiesMapper.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import org.aeonbits.owner.Config.Key;

import java.lang.reflect.Method;
import java.util.Properties;
import java.util.*;

import static org.aeonbits.owner.Util.prohibitInstantiation;

Expand Down Expand Up @@ -46,4 +46,33 @@ static void defaults(Properties properties, Class<? extends Config> clazz) {
properties.put(key, value);
}
}

static String mapValue(Method method) {
Config.MapValue mapValue = method.getAnnotation(Config.MapValue.class);
return mapValue != null ? mapValue.value() : null;
}

static void mapValues(Properties inputProperties, Properties outputProperties, Class<? extends Config> clazz) {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
String value = mapValue(method);
if (value != null) {
Map<String, String> map = new HashMap<String, String>();
List<String> keysToRemove = new ArrayList<String>();
for(java.util.Map.Entry<Object, Object> property : inputProperties.entrySet()) {
String propKey = (String) property.getKey();
if (propKey.startsWith(value)) {
String realKey = propKey.replaceFirst(value + ".", "");
map.put(realKey, (String) property.getValue());
keysToRemove.add(propKey);
}
}

for(String key : keysToRemove) {
inputProperties.remove(key);
}
outputProperties.put(value, map);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.aeonbits.owner.variableexpansion;

import org.aeonbits.owner.Config;
import org.aeonbits.owner.ConfigFactory;
import org.aeonbits.owner.Config.Sources;
import org.junit.Test;

import java.util.Map;

import static junit.framework.TestCase.assertNotNull;
import static org.junit.Assert.assertEquals;

public class MapPropertiesTest {
@Sources({"file:${user.dir}/src/test/resources/maps.properties"})
public static interface MapConfig extends Config {
public String nonmap();

@MapValue("map1")
public Map<String, String> map1();

@MapValue("map2")
public Map<String, String> map2();
}

@Test
public void testPropertyMaps() {
MapConfig config = ConfigFactory.create(MapConfig.class);

assertEquals("nope", config.nonmap());

assertNotNull(config.map1());
assertNotNull(config.map2());

assertEquals("a", config.map1().get("value1"));
assertEquals("b", config.map1().get("value2"));
assertEquals("1", config.map2().get("value3"));
assertEquals("2", config.map2().get("value4"));
}
}
7 changes: 7 additions & 0 deletions src/test/resources/maps.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
nonmap=nope

map1.value1=a
map1.value2=b

map2.value3=1
map2.value4=2