la.renzhen.rtpt.config.provider.ComposeConfigurationProvider Maven / Gradle / Ivy
package la.renzhen.rtpt.config.provider;
import com.fasterxml.jackson.databind.ObjectMapper;
import la.renzhen.rtpt.config.FluentConfiguration;
import la.renzhen.rtpt.config.ConfigurationProvider;
import la.renzhen.rtpt.config.ConfigurationSource;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.Map;
/**
*
*
* @author haiker
* @version 30/05/2018 3:04 PM
*/
@Data
@Accessors(fluent = true)
public class ComposeConfigurationProvider implements ConfigurationProvider {
ConfigurationSource configurationSource;
String environment;
String prefix;
ObjectMapper mapper = new ObjectMapper();
public ComposeConfigurationProvider(ConfigurationSource configurationSource, String environment, String prefix) {
this.configurationSource = configurationSource;
this.environment = environment;
this.prefix = prefix;
}
@Override
public Map allConfiguration() {
return configurationSource.loadAll(environment, prefix);
}
@Override
public String getProperty(String key) {
return configurationSource.get(key, environment);
}
@Override
@SneakyThrows
public T getProperty(String key, Type type, String defaultValue) {
String value = configurationSource.get(environment, key);
if (value == null) {
value = defaultValue;
}
if (type.equals(String.class)) {
return (T) value;
}
return this.mapper.readValue(value, this.mapper.constructType(type));
}
@Override
public T invoke(Class configurationClass) {
FluentConfiguration configuration = configurationClass.getAnnotation(FluentConfiguration.class);
String prefix = this.prefix;
if (configuration != null && !"".equals(configuration.value())) {
prefix = hasText(prefix) ? prefix + "." + configuration.value() : configuration.value();
}
return (T) Proxy.newProxyInstance(configurationClass.getClassLoader(), new Class>[]{configurationClass}, new BindInvocationHandler(this, prefix));
}
class BindInvocationHandler implements InvocationHandler {
private final String prefix;
private final ConfigurationProvider provider;
private BindInvocationHandler(ConfigurationProvider provider, String prefix) {
this.provider = provider;
this.prefix = prefix;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
FluentConfiguration.DefaultValue defaultValue = method.getAnnotation(FluentConfiguration.DefaultValue.class);
String key = (hasText(prefix) ? prefix + "." : "") + method.getName();
String defValue = defaultValue != null ? defaultValue.value() : null;
return provider.getProperty(key, method.getGenericReturnType(), defValue);
}
}
private static boolean hasText(String text) {
return text != null && !"".equals(text.trim());
}
}