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