2b19f3e3fe2169e3b0160fc5cf02d0e2be31e032
[jSite.git] / src / main / java / de / todesbaum / jsite / main / ConfigurationLocator.java
1 /*
2  * jSite - ConfigurationLocator.java - Copyright © 2011–2014 David Roden
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18
19 package de.todesbaum.jsite.main;
20
21 import java.io.File;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Optional;
25
26 /**
27  * Locator for configuration files in different places.
28  *
29  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
30  */
31 public class ConfigurationLocator {
32
33         /**
34          * The location of the configuration directory.
35          *
36          * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
37          */
38         public enum ConfigurationLocation {
39
40                 /** The configuration is in the same directory as the JAR file. */
41                 NEXT_TO_JAR_FILE,
42
43                 /**
44                  * The configuration is in the user’s home directory. This is the
45                  * pre-0.9.3 default.
46                  */
47                 HOME_DIRECTORY,
48
49                 /** Custom location. */
50                 CUSTOM,
51
52         }
53
54         /** The possible configuration locations. */
55         private final Map<ConfigurationLocation, String> configurationFiles = new HashMap<ConfigurationLocation, String>();
56
57         /**
58          * Creates a new configuration locator. If this class is loaded from a JAR
59          * file, {@link ConfigurationLocation#NEXT_TO_JAR_FILE} is added to the list
60          * of possible configuration file locations.
61          * {@link ConfigurationLocation#HOME_DIRECTORY} is always added to this
62          * list, {@link ConfigurationLocation#CUSTOM} has to be enabled by calling
63          * {@link #setCustomLocation(String)}.
64          */
65         public ConfigurationLocator(JarFileLocator jarFileLocator) {
66                 /* are we executed from a JAR file? */
67                 Optional<File> jarFile = jarFileLocator.locateJarFile();
68                 if (jarFile.isPresent()) {
69                         File configurationFile = new File(jarFile.get().getParent(), "jSite.conf");
70                         configurationFiles.put(ConfigurationLocation.NEXT_TO_JAR_FILE, configurationFile.getPath());
71                 }
72                 File homeDirectoryFile = new File(System.getProperty("user.home"), ".jSite/config7");
73                 configurationFiles.put(ConfigurationLocation.HOME_DIRECTORY, homeDirectoryFile.getPath());
74         }
75
76         //
77         // ACCESSORS
78         //
79
80         /**
81          * Sets the location of the custom configuration file.
82          *
83          * @param customFile
84          *            The custom location of the configuration file
85          */
86         public void setCustomLocation(String customFile) {
87                 configurationFiles.put(ConfigurationLocation.CUSTOM, customFile);
88         }
89
90         /**
91          * Returns whether the given location is valid. Certain locations (such as
92          * {@link ConfigurationLocation#NEXT_TO_JAR_FILE}) may be invalid in certain
93          * circumstances (such as the application not being run from a JAR file). A
94          * location being valid does not imply that a configuration file does exist
95          * at the given location, use {@link #hasFile(ConfigurationLocation)} to
96          * check for a configuration file at the desired location.
97          *
98          * @param configurationLocation
99          *            The configuration location
100          * @return {@code true} if the location is valid, {@code false} otherwise
101          */
102         public boolean isValidLocation(ConfigurationLocation configurationLocation) {
103                 return configurationFiles.containsKey(configurationLocation);
104         }
105
106         /**
107          * Checks whether a configuration file exists at the given location.
108          *
109          * @param configurationLocation
110          *            The configuration location
111          * @return {@code true} if a configuration file exists at the given
112          *         location, {@code false} otherwise
113          */
114         public boolean hasFile(ConfigurationLocation configurationLocation) {
115                 if (!isValidLocation(configurationLocation)) {
116                         return false;
117                 }
118                 return new File(configurationFiles.get(configurationLocation)).exists();
119         }
120
121         /**
122          * Returns the configuration file for the given location.
123          *
124          * @param configurationLocation
125          *            The location to get the file for
126          * @return The name of the configuration file at the given location, or
127          *         {@code null} if the given location is invalid
128          */
129         public String getFile(ConfigurationLocation configurationLocation) {
130                 return configurationFiles.get(configurationLocation);
131         }
132
133         //
134         // ACTIONS
135         //
136
137         /**
138          * Finds the preferred location of the configuration file.
139          *
140          * @see #findPreferredLocation(ConfigurationLocation)
141          * @return The preferred location of the configuration file
142          */
143         public ConfigurationLocation findPreferredLocation() {
144                 return findPreferredLocation(ConfigurationLocation.NEXT_TO_JAR_FILE);
145         }
146
147         /**
148          * Finds the preferred location of the configuration file. The following
149          * checks are performed: if a custom configuration location has been defined
150          * (by calling {@link #setCustomLocation(String)})
151          * {@link ConfigurationLocation#CUSTOM} is returned. If the application is
152          * run from a JAR file and a configuration file is found next to the JAR
153          * file (i.e. in the same directory),
154          * {@link ConfigurationLocation#NEXT_TO_JAR_FILE} is returned. If a
155          * configuration file exists in the user’s home directory,
156          * {@link ConfigurationLocation#HOME_DIRECTORY} is returned. Otherwise, the
157          * given {@code defaultLocation} is returned.
158          *
159          * @param defaultLocation
160          *            The default location to return if no other configuration file
161          *            is found
162          * @return The configuration location to load the configuration from
163          */
164         public ConfigurationLocation findPreferredLocation(ConfigurationLocation defaultLocation) {
165                 if (hasFile(ConfigurationLocation.CUSTOM)) {
166                         return ConfigurationLocation.CUSTOM;
167                 }
168                 if (hasFile(ConfigurationLocation.NEXT_TO_JAR_FILE)) {
169                         return ConfigurationLocation.NEXT_TO_JAR_FILE;
170                 }
171                 if (hasFile(ConfigurationLocation.HOME_DIRECTORY)) {
172                         return ConfigurationLocation.HOME_DIRECTORY;
173                 }
174                 if (isValidLocation(defaultLocation)) {
175                         return defaultLocation;
176                 }
177                 return ConfigurationLocation.HOME_DIRECTORY;
178         }
179
180 }