package co.codewizards.cloudstore.core.config;
import static co.codewizards.cloudstore.core.oio.OioFileFactory.*;
import static co.codewizards.cloudstore.core.util.PropertiesUtil.*;
import static co.codewizards.cloudstore.core.util.StringUtil.*;
import co.codewizards.cloudstore.core.appid.AppId;
import co.codewizards.cloudstore.core.appid.AppIdRegistry;
import co.codewizards.cloudstore.core.oio.File;
import co.codewizards.cloudstore.core.util.IOUtil;
/**
* {@code ConfigDir} represents the central configuration directory.
* <p>
* Besides the configuration, this directory holds all global (non-repository-related)
* files, including log files.
* @author Marco หงุ่ยตระกูล-Schulze - marco at codewizards dot co
*/
public class ConfigDir {
private static final String APP_ID_SIMPLE_ID = AppIdRegistry.getInstance().getAppIdOrFail().getSimpleId();
/**
* System property controlling the location of the central configuration directory.
* <p>
* Also, the {@link #ENV_VAR_CONFIG_DIR} is checked, if the system property is not present. The system
* property thus overrides the OS environment variable.
* <p>
* If neither system property nor env var is set, it defaults to: <code>${user.home}/.cloudstore</code>
* <p>
* Note that this property is always set during runtime. If it is not set by the caller (via a <code>-D</code> JVM argument)
* from the outside, then it is set by the code inside the running application. Therefore, this property
* can be referenced in all configuration files where system properties are resolved (e.g. in the logback configuration).
* <p>
* Note that "cloudstore" might be replaced by another identifier using the {@link AppId}.
* @see #getValue()
* @see #getFile()
*/
public static final String SYSTEM_PROPERTY_CONFIG_DIR = APP_ID_SIMPLE_ID + ".configDir";
/**
* Environment variable equivalent to {@link #SYSTEM_PROPERTY_CONFIG_DIR}.
*/
public static final String ENV_VAR_CONFIG_DIR = systemPropertyToEnvironmentVariable(SYSTEM_PROPERTY_CONFIG_DIR);
/**
* System property controlling the location of the log directory.
* <p>
* If this system property is not set, it defaults to:
* <code>${user.home}/.cloudstore/log</code>
* <p>
* Note that this property is always set during runtime. If it is not set by the caller (via a <code>-D</code> JVM argument)
* from the outside, then it is set by the code inside the running application. Therefore, this property
* can be referenced in all configuration files where system properties are resolved (e.g. in the logback configuration).
* @see #getLogDir()
*/
public static final String SYSTEM_PROPERTY_LOG_DIR = APP_ID_SIMPLE_ID + ".logDir";
private static final class ConfigDirHolder {
public static ConfigDir instance = new ConfigDir();
}
private final String value;
private final File file;
private File logDir;
/**
* Creates an instance of {@code ConfigDir}.
* <p>
* This method cannot and should not be called directly. Instead, {@link #getInstance()} should be
* used to obtain the singleton.
*/
protected ConfigDir() {
String v = System.getProperty(SYSTEM_PROPERTY_CONFIG_DIR);
if (v == null)
v = System.getenv(ENV_VAR_CONFIG_DIR);
if (v == null)
v = "${user.home}/." + APP_ID_SIMPLE_ID;
value = v;
System.setProperty(SYSTEM_PROPERTY_CONFIG_DIR, value);
final String resolvedValue = IOUtil.replaceTemplateVariables(value, System.getProperties());
file = createFile(resolvedValue).getAbsoluteFile();
if (!file.isDirectory())
file.mkdirs();
if (!file.isDirectory())
throw new IllegalStateException("Could not create directory (permissions?!): " + file);
}
/**
* Gets the singleton instance of {@code ConfigDir}.
* @return the singleton instance of {@code ConfigDir}. Never <code>null</code>.
*/
public static ConfigDir getInstance() {
return ConfigDirHolder.instance;
}
/**
* Gets the central configuration directory as {@code String}.
* <p>
* This is the <i>non-resolved</i> (as is) value of the system property {@link #SYSTEM_PROPERTY_CONFIG_DIR}.
* Even if this property was not set (from the outside), it is initialised by default to:
* <code>${user.home}/.cloudstore</code>
* @return the central configuration directory as {@code String}. Never <code>null</code>.
* @see #SYSTEM_PROPERTY_CONFIG_DIR
* @see #getFile()
*/
public String getValue() {
return value;
}
/**
* Gets the central configuration directory as <i>absolute</i> {@code File}.
* <p>
* In contrast to {@link #getValue()}, this file's path is <i>resolved</i>; i.e. all system properties
* occurring in it (e.g. "${user.home}") were replaced by their actual values.
* @return the central configuration directory as <i>absolute</i> {@code File}. Never <code>null</code>.
* @see #SYSTEM_PROPERTY_CONFIG_DIR
* @see #getValue()
*/
public File getFile() {
return file;
}
/**
* Gets the log directory (the directory where the log files are written to).
* <p>
* This directory can be configured or referenced (e.g. in a logback configuation file) via
* {@link #SYSTEM_PROPERTY_LOG_DIR}.
* @return the log directory. Never <code>null</code>.
* @see #SYSTEM_PROPERTY_LOG_DIR
*/
public File getLogDir() {
if (logDir == null) {
final String sysPropVal = System.getProperty(SYSTEM_PROPERTY_LOG_DIR);
if (isEmpty(sysPropVal))
logDir = createFile(getFile(), "log");
else {
final String resolvedSysPropVal = IOUtil.replaceTemplateVariables(sysPropVal, System.getProperties());
logDir = createFile(resolvedSysPropVal).getAbsoluteFile();
}
System.setProperty(SYSTEM_PROPERTY_LOG_DIR, logDir.getPath());
if (!logDir.isDirectory())
logDir.mkdirs();
if (!logDir.isDirectory())
throw new IllegalStateException("Could not create directory (permissions?!): " + logDir);
}
return logDir;
}
}