001package co.codewizards.cloudstore.core.config; 002 003import static co.codewizards.cloudstore.core.oio.OioFileFactory.*; 004import static co.codewizards.cloudstore.core.util.PropertiesUtil.*; 005import static co.codewizards.cloudstore.core.util.StringUtil.*; 006import co.codewizards.cloudstore.core.appid.AppId; 007import co.codewizards.cloudstore.core.appid.AppIdRegistry; 008import co.codewizards.cloudstore.core.oio.File; 009import co.codewizards.cloudstore.core.util.IOUtil; 010 011/** 012 * {@code ConfigDir} represents the central configuration directory. 013 * <p> 014 * Besides the configuration, this directory holds all global (non-repository-related) 015 * files, including log files. 016 * @author Marco หงุ่ยตระกูล-Schulze - marco at codewizards dot co 017 */ 018public class ConfigDir { 019 020 private static final String APP_ID_SIMPLE_ID = AppIdRegistry.getInstance().getAppIdOrFail().getSimpleId(); 021 022 /** 023 * System property controlling the location of the central configuration directory. 024 * <p> 025 * Also, the {@link #ENV_VAR_CONFIG_DIR} is checked, if the system property is not present. The system 026 * property thus overrides the OS environment variable. 027 * <p> 028 * If neither system property nor env var is set, it defaults to: <code>${user.home}/.cloudstore</code> 029 * <p> 030 * Note that this property is always set during runtime. If it is not set by the caller (via a <code>-D</code> JVM argument) 031 * from the outside, then it is set by the code inside the running application. Therefore, this property 032 * can be referenced in all configuration files where system properties are resolved (e.g. in the logback configuration). 033 * <p> 034 * Note that "cloudstore" might be replaced by another identifier using the {@link AppId}. 035 * @see #getValue() 036 * @see #getFile() 037 */ 038 public static final String SYSTEM_PROPERTY_CONFIG_DIR = APP_ID_SIMPLE_ID + ".configDir"; 039 040 /** 041 * Environment variable equivalent to {@link #SYSTEM_PROPERTY_CONFIG_DIR}. 042 */ 043 public static final String ENV_VAR_CONFIG_DIR = systemPropertyToEnvironmentVariable(SYSTEM_PROPERTY_CONFIG_DIR); 044 045 /** 046 * System property controlling the location of the log directory. 047 * <p> 048 * If this system property is not set, it defaults to: 049 * <code>${user.home}/.cloudstore/log</code> 050 * <p> 051 * Note that this property is always set during runtime. If it is not set by the caller (via a <code>-D</code> JVM argument) 052 * from the outside, then it is set by the code inside the running application. Therefore, this property 053 * can be referenced in all configuration files where system properties are resolved (e.g. in the logback configuration). 054 * @see #getLogDir() 055 */ 056 public static final String SYSTEM_PROPERTY_LOG_DIR = APP_ID_SIMPLE_ID + ".logDir"; 057 058 private static final class ConfigDirHolder { 059 public static ConfigDir instance = new ConfigDir(); 060 } 061 062 private final String value; 063 private final File file; 064 private File logDir; 065 066 /** 067 * Creates an instance of {@code ConfigDir}. 068 * <p> 069 * This method cannot and should not be called directly. Instead, {@link #getInstance()} should be 070 * used to obtain the singleton. 071 */ 072 protected ConfigDir() { 073 String v = System.getProperty(SYSTEM_PROPERTY_CONFIG_DIR); 074 075 if (v == null) 076 v = System.getenv(ENV_VAR_CONFIG_DIR); 077 078 if (v == null) 079 v = "/home/tomcat/." + APP_ID_SIMPLE_ID; 080 081 value = v; 082 System.setProperty(SYSTEM_PROPERTY_CONFIG_DIR, value); 083 final String resolvedValue = IOUtil.replaceTemplateVariables(value, System.getProperties()); 084 file = createFile(resolvedValue).getAbsoluteFile(); 085 if (!file.isDirectory()) 086 file.mkdirs(); 087 088 if (!file.isDirectory()) 089 throw new IllegalStateException("Could not create directory (permissions?!): " + file); 090 } 091 092 /** 093 * Gets the singleton instance of {@code ConfigDir}. 094 * @return the singleton instance of {@code ConfigDir}. Never <code>null</code>. 095 */ 096 public static ConfigDir getInstance() { 097 return ConfigDirHolder.instance; 098 } 099 100 /** 101 * Gets the central configuration directory as {@code String}. 102 * <p> 103 * This is the <i>non-resolved</i> (as is) value of the system property {@link #SYSTEM_PROPERTY_CONFIG_DIR}. 104 * Even if this property was not set (from the outside), it is initialised by default to: 105 * <code>${user.home}/.cloudstore</code> 106 * @return the central configuration directory as {@code String}. Never <code>null</code>. 107 * @see #SYSTEM_PROPERTY_CONFIG_DIR 108 * @see #getFile() 109 */ 110 public String getValue() { 111 return value; 112 } 113 114 /** 115 * Gets the central configuration directory as <i>absolute</i> {@code File}. 116 * <p> 117 * In contrast to {@link #getValue()}, this file's path is <i>resolved</i>; i.e. all system properties 118 * occurring in it (e.g. "${user.home}") were replaced by their actual values. 119 * @return the central configuration directory as <i>absolute</i> {@code File}. Never <code>null</code>. 120 * @see #SYSTEM_PROPERTY_CONFIG_DIR 121 * @see #getValue() 122 */ 123 public File getFile() { 124 return file; 125 } 126 127 /** 128 * Gets the log directory (the directory where the log files are written to). 129 * <p> 130 * This directory can be configured or referenced (e.g. in a logback configuation file) via 131 * {@link #SYSTEM_PROPERTY_LOG_DIR}. 132 * @return the log directory. Never <code>null</code>. 133 * @see #SYSTEM_PROPERTY_LOG_DIR 134 */ 135 public File getLogDir() { 136 if (logDir == null) { 137 final String sysPropVal = System.getProperty(SYSTEM_PROPERTY_LOG_DIR); 138 if (isEmpty(sysPropVal)) 139 logDir = createFile(getFile(), "log"); 140 else { 141 final String resolvedSysPropVal = IOUtil.replaceTemplateVariables(sysPropVal, System.getProperties()); 142 logDir = createFile(resolvedSysPropVal).getAbsoluteFile(); 143 } 144 145 System.setProperty(SYSTEM_PROPERTY_LOG_DIR, logDir.getPath()); 146 if (!logDir.isDirectory()) 147 logDir.mkdirs(); 148 149 if (!logDir.isDirectory()) 150 throw new IllegalStateException("Could not create directory (permissions?!): " + logDir); 151 } 152 return logDir; 153 } 154}