package com.github.rojanu.config;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.github.rojanu.config.encryption.EncryptedStringDeserializer;
import com.github.rojanu.config.encryption.StringEncryptor;
import com.github.rojanu.util.io.FileUtils;
import com.github.rojanu.util.io.Resource;
import com.google.common.base.Preconditions;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
public abstract class Config {
public final Config $this = this;
public Resource configFolder;
public static <T extends Config> T load(Class<T> configClazz, String configPath) throws IOException, ConfigValidationException {
return load(configClazz, configPath, null);
}
public static <T extends Config> T load(Class<T> configClazz, String configPath, String defaultConfigPath) throws IOException, ConfigValidationException {
Objects.requireNonNull(configClazz);
Objects.requireNonNull(configPath);
InputStream defaultConfigInput = null;
if (defaultConfigPath != null) {
defaultConfigInput = FileUtils.getInputStream(Preconditions.checkNotNull(defaultConfigPath));
}
try (InputStream configInput = FileUtils.getInputStream(Preconditions.checkNotNull(configPath))) {
return load(configClazz, configInput, configPath, defaultConfigInput);
} finally {
if (defaultConfigInput != null) {
try {
defaultConfigInput.close();
} catch (Exception ignored) {
}
}
}
}
public static <T extends Config> T load(Class<T> configClazz, InputStream configInput, String configPath) throws IOException, ConfigValidationException {
return load(configClazz, configInput, configPath, null);
}
public static <T extends Config> T load(Class<T> configClazz, InputStream configInput, String configPath, InputStream defaultConfigInput) throws IOException, ConfigValidationException {
Objects.requireNonNull(configClazz);
Objects.requireNonNull(configInput);
final ObjectMapper mapper = createObjectMapper();
T defaultConfig;
ObjectReader updater = null;
if (defaultConfigInput != null) {
defaultConfig = mapper.readValue(defaultConfigInput, configClazz);
updater = mapper.readerForUpdating(defaultConfig);
}
T config;
if (updater != null) {
config = updater.readValue(configInput);
} else {
config = mapper.readValue(configInput, configClazz);
}
config.configFolder = Resource.from(configPath).getParent();
//validate(config);
return config;
}
private static ObjectMapper createObjectMapper() {
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
mapper.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.registerModule(getConfigEncryptionModule());
return mapper;
}
private static SimpleModule getConfigEncryptionModule() {
SimpleModule encryptionModule = new SimpleModule("encryption-module", new Version(1, 0, 0, null, "com.sagepay", "encryption-module"));
encryptionModule.addDeserializer(String.class, new EncryptedStringDeserializer(StringEncryptor.INSTANCE));
return encryptionModule;
}
public static <T extends Config> T load(TypeReference<?> configClazz, String configPath) throws IOException, ConfigValidationException {
return load(configClazz, configPath, null);
}
public static <T extends Config> T load(TypeReference<?> configClazz, String configPath, String defaultConfigPath) throws IOException, ConfigValidationException {
Objects.requireNonNull(configClazz);
Objects.requireNonNull(configPath);
InputStream defaultConfigInput = null;
if (defaultConfigPath != null) {
defaultConfigInput = FileUtils.getInputStream(Preconditions.checkNotNull(defaultConfigPath));
}
try (InputStream configInput = FileUtils.getInputStream(Preconditions.checkNotNull(configPath))) {
return load(configClazz, configInput, configPath, defaultConfigInput);
} finally {
if (defaultConfigInput != null) {
try {
defaultConfigInput.close();
} catch (Exception ignored) {
}
}
}
}
public static <T extends Config> T load(TypeReference<?> configClazz, InputStream configInput, String configPath) throws IOException, ConfigValidationException {
return load(configClazz, configInput, configPath, null);
}
public static <T extends Config> T load(TypeReference<?> configClazz, InputStream configInput, String configPath, InputStream defaultConfigInput) throws IOException, ConfigValidationException {
Objects.requireNonNull(configClazz);
Objects.requireNonNull(configInput);
final ObjectMapper mapper = createObjectMapper();
T defaultConfig;
ObjectReader updater = null;
if (defaultConfigInput != null) {
defaultConfig = mapper.readValue(defaultConfigInput, configClazz);
updater = mapper.readerForUpdating(defaultConfig);
}
T config;
if (updater != null) {
config = updater.readValue(configInput);
} else {
config = mapper.readValue(configInput, configClazz);
}
config.configFolder = Resource.from(configPath).getParent();
//validate(config);
return config;
}
public Resource relativize(Resource resource) {
return configFolder.relativize(resource);
}
public Resource relativize(String path) {
return configFolder.relativize(path);
}
}