ConfigFactory
是 GATK(Genome Analysis Toolkit)中用于管理和加载配置文件的类。虽然在 GATK 的不同版本中可能有不同的实现方式,但 ConfigFactory
通常是一个用于加载、解析和提供配置信息的实用工具类。以下是对 ConfigFactory
类的详细介绍:
功能概述
-
配置文件加载:
ConfigFactory
主要负责从配置文件(例如.properties
文件、JSON
文件或YAML
文件)中读取配置信息。通过这种方式,程序可以灵活地管理各种参数和设置,而不需要硬编码到程序中。
-
配置缓存:
- 配置信息通常在程序启动时加载并缓存,避免在每次需要访问配置时重新加载文件。
ConfigFactory
可能会提供静态方法或单例模式来确保配置文件只加载一次,并在整个应用程序中共享。
- 配置信息通常在程序启动时加载并缓存,避免在每次需要访问配置时重新加载文件。
-
提供默认值:
- 在配置文件中可能缺少某些参数时,
ConfigFactory
可以提供默认值,确保程序的健壮性。
- 在配置文件中可能缺少某些参数时,
-
环境变量支持:
- 一些版本的
ConfigFactory
可能会支持从环境变量中加载配置,这样可以根据部署环境动态调整配置。
- 一些版本的
-
类型转换:
ConfigFactory
通常会包含类型转换功能,将字符串形式的配置值转换为适当的数据类型,例如整数、布尔值或列表。
ConfigFactor源码
package org.broadinstitute.hellbender.utils.config;
import com.google.common.annotations.VisibleForTesting;
import htsjdk.samtools.util.Log;
import org.aeonbits.owner.Config;
import org.aeonbits.owner.ConfigCache;
import org.aeonbits.owner.Factory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.broadinstitute.hellbender.exceptions.GATKException;
import org.broadinstitute.hellbender.exceptions.UserException;
import org.broadinstitute.hellbender.utils.ClassUtils;
import org.broadinstitute.hellbender.utils.LoggingUtils;
import org.broadinstitute.hellbender.utils.Utils;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A singleton class to act as a user interface for loading configuration files from {@link org.aeonbits.owner}.
* This class wraps functionality in the {@link org.aeonbits.owner} configuration utilities to be a more GATK-specific
* interface.
* Created by jonn on 7/19/17.
*/
public final class ConfigFactory {
private static final Logger logger = LogManager.getLogger(ConfigFactory.class);
//=======================================
// Singleton members / methods:
private static final ConfigFactory instance;
static {
instance = new ConfigFactory();
}
/**
* @return An instance of this {@link ConfigFactory}, which can be used to create a configuration.
*/
public static ConfigFactory getInstance() {
return instance;
}
// This class is a singleton, so no public construction.
private ConfigFactory() {}
//=======================================
/**
* A regex to use to look for variables in the Sources annotation
*/
private static final Pattern sourcesAnnotationPathVariablePattern = Pattern.compile("\\$\\{(.*)}");
/**
* Value to set each variable for configuration file paths when the variable
* has not been set in either Java System properties or environment properties.
*/
@VisibleForTesting
static final String NO_PATH_VARIABLE_VALUE = "/dev/null";
/**
* A set to keep track of the classes we've already resolved for configuration path purposes:
*/
private final Set<Class<? extends Config>> alreadyResolvedPathVariables = new HashSet<>();
// =================================================================================================================
/**
* Checks each of the given {@code filenameProperties} for if they are defined in system {@link System#getProperties()}
* or environment {@link System#getenv()} properties. If they are not, this method will set them in the
* {@link org.aeonbits.owner.ConfigFactory} to an empty file path so the {@link org.aeonbits.owner.ConfigFactory} will know to try to resolve them as
* variables at load-time (and not as raw paths).
* @param filenameProperties A {@link List} of filename properties as specified in {@link Config} {@link org.aeonbits.owner.Config.Sources} annotations to check for existence in system and environment properties.
*/
@VisibleForTesting
void checkFileNamePropertyExistenceAndSetConfigFactoryProperties(final List<String> filenameProperties) {
// Grab the system properties:
final Properties systemProperties = System.getProperties();
// Grab the environment properties:
final Map<String, String> environmentProperties = System.getenv();
// Make sure that if our property isn't in the system, environment, and ConfigFactory
// properties, that we set it to a neutral value that will not contain
// anything (so that the property will fall back into the next value).
for (final String property : filenameProperties) {
if ( environmentProperties.containsKey(property) ) {
logger.debug("Config path variable found in Environment Properties: " + property + "=" + environmentProperties.get(property) + " - will search for config here.");
}
else if ( systemProperties.containsKey(property) ) {
logger.debug("Config path variable found in System Properties: " + property + "=" + systemProperties.get(property) + " - will search for config here.");
}
else if ( org.aeonbits.owner.ConfigFactory.getProperties().containsKey(property) ) {
logger.debug("Config path variable found in Config Factory Properties(probably from the command-line): " + property + "=" + org.aeonbits.owner.ConfigFactory.getProperty(property) + " - will search for config here.");
}
else {
logger.debug("Config path variable not found: " + property +
" - setting value to default empty variable: " + (NO_PATH_VARIABLE_VALUE == null ? "null" : String.valueOf(NO_PATH_VARIABLE_VALUE)) );
org.aeonbits.owner.ConfigFactory.setProperty(property, NO_PATH_VARIABLE_VALUE);
}
}
}
/**
* Get a list of the config file variables from the given {@link Config} classes.
* @param configurationClasses A list of configuration classes from which to extract variable names in their {@link org.aeonbits.owner.Config.Sources}.
* @return A list of variables in the {@link org.aeonbits.owner.Config.Sources} of the given {@code configurationClasses}
*/
@VisibleForTesting
List<String> getConfigPathVariableNamesFromConfigClasses(final List<Class<?>> configurationClasses) {
final List<String> configPathVariableNames = new ArrayList<>();
// Loop through our classes and grab any sources with variables in there:
for ( final Class<?> clazz : ClassUtils.getClassesOfType(Config.class, configurationClasses) ) {
@SuppressWarnings("unchecked")
final Class<? extends Config> castedClass = (Class<? extends Config>) clazz;
configPathVariableNames.addAll( getSourcesAnnotationPathVariables(castedClass));
}
return configPathVariableNames;
}
/**
* Get a list of the config file variables from the given {@link Config} class.
* @param configClass A configuration class from which to extract variable names in its {@link org.aeonbits.owner.Config.Sources}.
* @return A list of variables in the {@link org.aeonbits.owner.Config.Sources} of the given {