mirror of
https://github.com/lightbend/config.git
synced 2025-01-15 23:01:05 +08:00
more work
This commit is contained in:
parent
9ca157d34a
commit
6b54720ddd
@ -1,13 +1,150 @@
|
|||||||
package com.typesafe.config;
|
package com.typesafe.config;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.typesafe.config.impl.ConfigFactory;
|
import com.typesafe.config.impl.ConfigFactory;
|
||||||
|
|
||||||
public class Config {
|
public final class Config {
|
||||||
public static ConfigObject load(ConfigConfig configConfig) {
|
public static ConfigObject load(ConfigConfig configConfig) {
|
||||||
return ConfigFactory.getConfig(configConfig);
|
return ConfigFactory.loadConfig(configConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConfigObject load(String rootPath) {
|
public static ConfigObject load(String rootPath) {
|
||||||
return ConfigFactory.getConfig(new ConfigConfig(rootPath, null));
|
return ConfigFactory.loadConfig(new ConfigConfig(rootPath, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getUnits(String s) {
|
||||||
|
int i = s.length() - 1;
|
||||||
|
while (i >= 0) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
if (!Character.isLetter(c))
|
||||||
|
break;
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
return s.substring(i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a duration string. If no units are specified in the string, it is
|
||||||
|
* assumed to be in milliseconds. The returned duration is in nanoseconds.
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* the string to parse
|
||||||
|
* @param originForException
|
||||||
|
* origin of the value being parsed
|
||||||
|
* @param pathForException
|
||||||
|
* path to include in exceptions
|
||||||
|
* @return duration in nanoseconds
|
||||||
|
* @throws ConfigException
|
||||||
|
* if string is invalid
|
||||||
|
*/
|
||||||
|
public static long parseDuration(String input,
|
||||||
|
ConfigOrigin originForException, String pathForException) {
|
||||||
|
String s = input.trim();
|
||||||
|
String unitString = getUnits(s);
|
||||||
|
String numberString = s.substring(0, s.length() - unitString.length()).trim();
|
||||||
|
TimeUnit units = null;
|
||||||
|
|
||||||
|
// note that this is deliberately case-sensitive
|
||||||
|
if (unitString == "" || unitString == "ms" || unitString == "milliseconds") {
|
||||||
|
units = TimeUnit.MILLISECONDS;
|
||||||
|
} else if (unitString == "us" || unitString == "microseconds") {
|
||||||
|
units = TimeUnit.MICROSECONDS;
|
||||||
|
} else if (unitString == "ns" || unitString == "nanoseconds") {
|
||||||
|
units = TimeUnit.NANOSECONDS;
|
||||||
|
} else if (unitString == "d" || unitString == "days") {
|
||||||
|
units = TimeUnit.DAYS;
|
||||||
|
} else if (unitString == "s" || unitString == "seconds") {
|
||||||
|
units = TimeUnit.SECONDS;
|
||||||
|
} else if (unitString == "m" || unitString == "minutes") {
|
||||||
|
units = TimeUnit.MINUTES;
|
||||||
|
} else {
|
||||||
|
throw new ConfigException.BadValue(originForException,
|
||||||
|
pathForException, "Could not parse time unit '"
|
||||||
|
+ unitString + "' (try ns, us, ms, s, m, d)");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// if the string is purely digits, parse as an integer to avoid possible precision loss;
|
||||||
|
// otherwise as a double.
|
||||||
|
if (numberString.matches("[0-9]+")) {
|
||||||
|
return units.toNanos(Long.parseLong(numberString));
|
||||||
|
} else {
|
||||||
|
long nanosInUnit = units.toNanos(1);
|
||||||
|
return (new Double(Double.parseDouble(numberString) * nanosInUnit)).longValue();
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ConfigException.BadValue(originForException, pathForException,
|
||||||
|
"Could not parse duration number '"
|
||||||
|
+ numberString + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static enum MemoryUnit {
|
||||||
|
BYTES(1), KILOBYTES(1024), MEGABYTES(1024 * 1024), GIGABYTES(
|
||||||
|
1024 * 1024 * 1024);
|
||||||
|
|
||||||
|
int bytes;
|
||||||
|
MemoryUnit(int bytes) {
|
||||||
|
this.bytes = bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a memory-size string. If no units are specified in the string, it
|
||||||
|
* is assumed to be in bytes. The returned value is in bytes.
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* the string to parse
|
||||||
|
* @param originForException
|
||||||
|
* origin of the value being parsed
|
||||||
|
* @param pathForException
|
||||||
|
* path to include in exceptions
|
||||||
|
* @return size in bytes
|
||||||
|
* @throws ConfigException
|
||||||
|
* if string is invalid
|
||||||
|
*/
|
||||||
|
public static long parseMemorySize(String input,
|
||||||
|
ConfigOrigin originForException, String pathForException) {
|
||||||
|
String s = input.trim();
|
||||||
|
String unitString = getUnits(s);
|
||||||
|
String unitStringLower = unitString.toLowerCase();
|
||||||
|
String numberString = s.substring(0, s.length() - unitString.length())
|
||||||
|
.trim();
|
||||||
|
MemoryUnit units = null;
|
||||||
|
|
||||||
|
// the short abbreviations are case-insensitive but you can't write the
|
||||||
|
// long form words in all caps.
|
||||||
|
if (unitString == "" || unitStringLower == "b"
|
||||||
|
|| unitString == "bytes") {
|
||||||
|
units = MemoryUnit.BYTES;
|
||||||
|
} else if (unitStringLower == "k" || unitString == "kilobytes") {
|
||||||
|
units = MemoryUnit.KILOBYTES;
|
||||||
|
} else if (unitStringLower == "m" || unitString == "megabytes") {
|
||||||
|
units = MemoryUnit.MEGABYTES;
|
||||||
|
} else if (unitStringLower == "g" || unitString == "gigabytes") {
|
||||||
|
units = MemoryUnit.GIGABYTES;
|
||||||
|
} else {
|
||||||
|
throw new ConfigException.BadValue(originForException,
|
||||||
|
pathForException, "Could not parse size unit '"
|
||||||
|
+ unitString + "' (try b, k, m, g)");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// if the string is purely digits, parse as an integer to avoid
|
||||||
|
// possible precision loss;
|
||||||
|
// otherwise as a double.
|
||||||
|
if (numberString.matches("[0-9]+")) {
|
||||||
|
return Long.parseLong(numberString) * units.bytes;
|
||||||
|
} else {
|
||||||
|
return (new Double(Double.parseDouble(numberString)
|
||||||
|
* units.bytes)).longValue();
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ConfigException.BadValue(originForException,
|
||||||
|
pathForException, "Could not parse memory size number '"
|
||||||
|
+ numberString
|
||||||
|
+ "'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package com.typesafe.config;
|
|||||||
/**
|
/**
|
||||||
* Configuration for a configuration!
|
* Configuration for a configuration!
|
||||||
*/
|
*/
|
||||||
public class ConfigConfig {
|
public final class ConfigConfig {
|
||||||
|
|
||||||
private String rootPath;
|
private String rootPath;
|
||||||
private ConfigTransformer extraTransformer;
|
private ConfigTransformer extraTransformer;
|
||||||
|
@ -81,6 +81,27 @@ public class ConfigException extends RuntimeException {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class BadValue extends ConfigException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public BadValue(ConfigOrigin origin, String path, String message,
|
||||||
|
Throwable cause) {
|
||||||
|
super(origin, "Invalid value at '" + path + "': " + message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadValue(ConfigOrigin origin, String path, String message) {
|
||||||
|
this(origin, path, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadValue(String path, String message, Throwable cause) {
|
||||||
|
super("Invalid value at '" + path + "': " + message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadValue(String path, String message) {
|
||||||
|
this(path, message, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class BadPath extends ConfigException {
|
public static class BadPath extends ConfigException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -30,6 +30,23 @@ public interface ConfigObject extends ConfigValue {
|
|||||||
|
|
||||||
ConfigValue get(String path);
|
ConfigValue get(String path);
|
||||||
|
|
||||||
|
/** Get value as a size in bytes (parses special strings like "128M") */
|
||||||
|
Long getMemorySize(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value as a duration in milliseconds. If the value is already a
|
||||||
|
* number, then it's left alone; if it's a string, it's parsed understanding
|
||||||
|
* units suffixes like "10m" or "5ns"
|
||||||
|
*/
|
||||||
|
Long getMilliseconds(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value as a duration in nanoseconds. If the value is already a number
|
||||||
|
* it's taken as milliseconds. If it's a string, it's parsed understanding
|
||||||
|
* unit suffixes.
|
||||||
|
*/
|
||||||
|
Long getNanoseconds(String path);
|
||||||
|
|
||||||
List<ConfigValue> getList(String path);
|
List<ConfigValue> getList(String path);
|
||||||
|
|
||||||
List<Boolean> getBooleanList(String path);
|
List<Boolean> getBooleanList(String path);
|
||||||
@ -46,6 +63,12 @@ public interface ConfigObject extends ConfigValue {
|
|||||||
|
|
||||||
List<Object> getAnyList(String path);
|
List<Object> getAnyList(String path);
|
||||||
|
|
||||||
|
List<Long> getMemorySizeList(String path);
|
||||||
|
|
||||||
|
List<Long> getMillisecondsList(String path);
|
||||||
|
|
||||||
|
List<Long> getNanosecondsList(String path);
|
||||||
|
|
||||||
boolean containsKey(String key);
|
boolean containsKey(String key);
|
||||||
|
|
||||||
Set<String> keySet();
|
Set<String> keySet();
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
package com.typesafe.config.impl;
|
package com.typesafe.config.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.typesafe.config.Config;
|
||||||
import com.typesafe.config.ConfigException;
|
import com.typesafe.config.ConfigException;
|
||||||
import com.typesafe.config.ConfigObject;
|
import com.typesafe.config.ConfigObject;
|
||||||
import com.typesafe.config.ConfigOrigin;
|
import com.typesafe.config.ConfigOrigin;
|
||||||
@ -19,6 +25,13 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
this.transformer = transformer;
|
this.transformer = transformer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This looks up the key with no transformation or type conversion of any
|
||||||
|
* kind, and returns null if the key is not present.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return the unmodified raw value or null
|
||||||
|
*/
|
||||||
protected abstract ConfigValue peek(String key);
|
protected abstract ConfigValue peek(String key);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -26,6 +39,18 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
return ConfigValueType.OBJECT;
|
return ConfigValueType.OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AbstractConfigObject transformed(AbstractConfigObject obj,
|
||||||
|
ConfigTransformer transformer) {
|
||||||
|
if (obj.transformer != transformer)
|
||||||
|
return new TransformedConfigObject(transformer, obj);
|
||||||
|
else
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AbstractConfigObject transformed(AbstractConfigObject obj) {
|
||||||
|
return transformed(obj, transformer);
|
||||||
|
}
|
||||||
|
|
||||||
static private ConfigValue resolve(AbstractConfigObject self, String path,
|
static private ConfigValue resolve(AbstractConfigObject self, String path,
|
||||||
ConfigValueType expected, ConfigTransformer transformer,
|
ConfigValueType expected, ConfigTransformer transformer,
|
||||||
String originalPath) {
|
String originalPath) {
|
||||||
@ -59,6 +84,58 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
return resolve(this, path, expected, transformer, originalPath);
|
return resolve(this, path, expected, transformer, originalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack should be from overrides to fallbacks (earlier items win). Test
|
||||||
|
* suite should check: merging of objects with a non-object in the middle.
|
||||||
|
* Override of object with non-object, override of non-object with object.
|
||||||
|
* Merging 0, 1, N objects.
|
||||||
|
*/
|
||||||
|
static AbstractConfigObject merge(ConfigOrigin origin,
|
||||||
|
List<AbstractConfigObject> stack,
|
||||||
|
ConfigTransformer transformer) {
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
return new SimpleConfigObject(origin, transformer,
|
||||||
|
Collections.<String, ConfigValue> emptyMap());
|
||||||
|
} else if (stack.size() == 1) {
|
||||||
|
return transformed(stack.get(0), transformer);
|
||||||
|
} else {
|
||||||
|
// for non-objects, we just take the first value; but for objects we
|
||||||
|
// have to do work to combine them.
|
||||||
|
Map<String, ConfigValue> merged = new HashMap<String, ConfigValue>();
|
||||||
|
Map<String, List<AbstractConfigObject>> objects = new HashMap<String, List<AbstractConfigObject>>();
|
||||||
|
for (AbstractConfigObject obj : stack) {
|
||||||
|
for (String key : obj.keySet()) {
|
||||||
|
ConfigValue v = obj.peek(key);
|
||||||
|
if (!merged.containsKey(key)) {
|
||||||
|
if (v.valueType() == ConfigValueType.OBJECT) {
|
||||||
|
// requires recursive merge and transformer fixup
|
||||||
|
List<AbstractConfigObject> stackForKey = null;
|
||||||
|
if (objects.containsKey(key)) {
|
||||||
|
stackForKey = objects.get(key);
|
||||||
|
} else {
|
||||||
|
stackForKey = new ArrayList<AbstractConfigObject>();
|
||||||
|
}
|
||||||
|
stackForKey.add(transformed(
|
||||||
|
(AbstractConfigObject) v,
|
||||||
|
transformer));
|
||||||
|
} else {
|
||||||
|
if (!objects.containsKey(key)) {
|
||||||
|
merged.put(key, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String key : objects.keySet()) {
|
||||||
|
List<AbstractConfigObject> stackForKey = objects.get(key);
|
||||||
|
AbstractConfigObject obj = merge(origin, stackForKey, transformer);
|
||||||
|
merged.put(key, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SimpleConfigObject(origin, transformer, merged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigValue get(String path) {
|
public ConfigValue get(String path) {
|
||||||
return resolve(path, null, path);
|
return resolve(path, null, path);
|
||||||
@ -105,8 +182,9 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractConfigObject getObject(String path) {
|
public AbstractConfigObject getObject(String path) {
|
||||||
ConfigValue v = resolve(path, ConfigValueType.OBJECT, path);
|
AbstractConfigObject obj = (AbstractConfigObject) resolve(path,
|
||||||
return (AbstractConfigObject) v;
|
ConfigValueType.OBJECT, path);
|
||||||
|
return transformed(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,6 +193,36 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
return v.unwrapped();
|
return v.unwrapped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getMemorySize(String path) {
|
||||||
|
Long size = null;
|
||||||
|
try {
|
||||||
|
size = getLong(path);
|
||||||
|
} catch (ConfigException.WrongType e) {
|
||||||
|
ConfigValue v = resolve(path, ConfigValueType.STRING, path);
|
||||||
|
size = Config.parseMemorySize((String) v.unwrapped(), v.origin(),
|
||||||
|
path);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getMilliseconds(String path) {
|
||||||
|
return TimeUnit.NANOSECONDS.toMillis(getNanoseconds(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getNanoseconds(String path) {
|
||||||
|
Long ns = null;
|
||||||
|
try {
|
||||||
|
ns = getLong(path);
|
||||||
|
} catch (ConfigException.WrongType e) {
|
||||||
|
ConfigValue v = resolve(path, ConfigValueType.STRING, path);
|
||||||
|
ns = Config.parseDuration((String) v.unwrapped(), v.origin(), path);
|
||||||
|
}
|
||||||
|
return ns;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T> List<T> getHomogeneousUnwrappedList(String path,
|
private <T> List<T> getHomogeneousUnwrappedList(String path,
|
||||||
ConfigValueType expected) {
|
ConfigValueType expected) {
|
||||||
@ -177,7 +285,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
if (v.valueType() != ConfigValueType.OBJECT)
|
if (v.valueType() != ConfigValueType.OBJECT)
|
||||||
throw new ConfigException.WrongType(v.origin(), path,
|
throw new ConfigException.WrongType(v.origin(), path,
|
||||||
ConfigValueType.OBJECT.name(), v.valueType().name());
|
ConfigValueType.OBJECT.name(), v.valueType().name());
|
||||||
l.add((ConfigObject) v);
|
l.add(transformed((AbstractConfigObject) v));
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@ -191,4 +299,55 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> getMemorySizeList(String path) {
|
||||||
|
List<Long> l = new ArrayList<Long>();
|
||||||
|
List<ConfigValue> list = getList(path);
|
||||||
|
for (ConfigValue v : list) {
|
||||||
|
if (v.valueType() == ConfigValueType.NUMBER) {
|
||||||
|
l.add(((Number) v.unwrapped()).longValue());
|
||||||
|
} else if (v.valueType() == ConfigValueType.STRING) {
|
||||||
|
String s = (String) v.unwrapped();
|
||||||
|
Long n = Config.parseMemorySize(s, v.origin(), path);
|
||||||
|
l.add(n);
|
||||||
|
} else {
|
||||||
|
throw new ConfigException.WrongType(v.origin(), path,
|
||||||
|
"memory size string or number of bytes", v.valueType()
|
||||||
|
.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> getMillisecondsList(String path) {
|
||||||
|
List<Long> nanos = getNanosecondsList(path);
|
||||||
|
List<Long> l = new ArrayList<Long>();
|
||||||
|
for (Long n : nanos) {
|
||||||
|
l.add(TimeUnit.NANOSECONDS.toMillis(n));
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> getNanosecondsList(String path) {
|
||||||
|
List<Long> l = new ArrayList<Long>();
|
||||||
|
List<ConfigValue> list = getList(path);
|
||||||
|
for (ConfigValue v : list) {
|
||||||
|
if (v.valueType() == ConfigValueType.NUMBER) {
|
||||||
|
l.add(((Number) v.unwrapped()).longValue());
|
||||||
|
} else if (v.valueType() == ConfigValueType.STRING) {
|
||||||
|
String s = (String) v.unwrapped();
|
||||||
|
Long n = Config.parseDuration(s, v.origin(), path);
|
||||||
|
l.add(n);
|
||||||
|
} else {
|
||||||
|
throw new ConfigException.WrongType(v.origin(), path,
|
||||||
|
"duration string or number of nanoseconds", v
|
||||||
|
.valueType().name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ import com.typesafe.config.ConfigValue;
|
|||||||
|
|
||||||
/** This is public but is only supposed to be used by the "config" package */
|
/** This is public but is only supposed to be used by the "config" package */
|
||||||
public class ConfigFactory {
|
public class ConfigFactory {
|
||||||
public static ConfigObject getConfig(ConfigConfig configConfig) {
|
public static ConfigObject loadConfig(ConfigConfig configConfig) {
|
||||||
AbstractConfigObject system = null;
|
AbstractConfigObject system = null;
|
||||||
try {
|
try {
|
||||||
system = systemPropertiesConfig()
|
system = systemPropertiesConfig()
|
||||||
@ -29,23 +29,36 @@ public class ConfigFactory {
|
|||||||
if (system != null)
|
if (system != null)
|
||||||
stack.add(system);
|
stack.add(system);
|
||||||
|
|
||||||
List<ConfigTransformer> transformerStack = new ArrayList<ConfigTransformer>();
|
ConfigTransformer transformer = withExtraTransformer(configConfig
|
||||||
transformerStack.add(defaultConfigTransformer());
|
.extraTransformer());
|
||||||
ConfigTransformer extraTransformer = configConfig.extraTransformer();
|
|
||||||
if (extraTransformer != null)
|
|
||||||
transformerStack.add(extraTransformer);
|
|
||||||
ConfigTransformer transformer = new StackTransformer(transformerStack);
|
|
||||||
|
|
||||||
StackConfigObject stackConfig = new StackConfigObject(
|
AbstractConfigObject merged = AbstractConfigObject
|
||||||
new SimpleConfigOrigin("config for " + configConfig.rootPath()),
|
.merge(new SimpleConfigOrigin("config for "
|
||||||
transformer,
|
+ configConfig.rootPath()), stack, transformer);
|
||||||
stack);
|
|
||||||
|
|
||||||
return stackConfig;
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConfigObject getEnvironmentAsConfig() {
|
public static ConfigObject getEnvironmentAsConfig(
|
||||||
return envVariablesConfig();
|
ConfigTransformer extraTransformer) {
|
||||||
|
// This should not need to create a new config object
|
||||||
|
// as long as the transformer is just the default transformer.
|
||||||
|
return AbstractConfigObject.transformed(envVariablesConfig(),
|
||||||
|
withExtraTransformer(extraTransformer));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ConfigTransformer withExtraTransformer(
|
||||||
|
ConfigTransformer extraTransformer) {
|
||||||
|
// idea is to avoid creating a new, unique transformer if there's no
|
||||||
|
// extraTransformer
|
||||||
|
if (extraTransformer != null) {
|
||||||
|
List<ConfigTransformer> transformerStack = new ArrayList<ConfigTransformer>();
|
||||||
|
transformerStack.add(defaultConfigTransformer());
|
||||||
|
transformerStack.add(extraTransformer);
|
||||||
|
return new StackTransformer(transformerStack);
|
||||||
|
} else {
|
||||||
|
return defaultConfigTransformer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ConfigTransformer defaultTransformer = null;
|
private static ConfigTransformer defaultTransformer = null;
|
||||||
|
@ -11,6 +11,10 @@ import com.typesafe.config.ConfigOrigin;
|
|||||||
import com.typesafe.config.ConfigTransformer;
|
import com.typesafe.config.ConfigTransformer;
|
||||||
import com.typesafe.config.ConfigValue;
|
import com.typesafe.config.ConfigValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is unused for now, decided that it was too annoying to "lazy merge" and
|
||||||
|
* better to do the full merge up-front.
|
||||||
|
*/
|
||||||
final class StackConfigObject extends AbstractConfigObject {
|
final class StackConfigObject extends AbstractConfigObject {
|
||||||
|
|
||||||
private List<AbstractConfigObject> stack;
|
private List<AbstractConfigObject> stack;
|
||||||
|
Loading…
Reference in New Issue
Block a user