967f93673d7da4d458798aa895cb4262ee61e1e5
[jSite.git] / src / main / java / de / todesbaum / jsite / main / ConfigurationLocator.java
1 /*
2  * jSite - ConfigurationLocator.java - Copyright © 2011–2012 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
25 /**
26  * Locator for configuration files in different places.
27  *
28  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
29  */
30 public class ConfigurationLocator {
31
32         /**
33          * The location of the configuration directory.
34          *
35          * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
36          */
37         public enum ConfigurationLocation {
38
39                 /** The configuration is in the same directory as the JAR file. */
40                 NEXT_TO_JAR_FILE,
41
42                 /**
43                  * The configuration is in the user’s home directory. This is the
44                  * pre-0.9.3 default.
45                  */
46                 HOME_DIRECTORY,
47
48                 /** Custom location. */
49                 CUSTOM,
50
51         }
52
53         /** The possible configuration locations. */
54         private final Map<ConfigurationLocation, String> configurationFiles = new HashMap<ConfigurationLocation, String>();
55
56         /**
57          * Creates a new configuration locator. If this class is loaded from a JAR
58          * file, {@link ConfigurationLocation#NEXT_TO_JAR_FILE} is added to the list
59          * of possible configuration file locations.
60          * {@link ConfigurationLocation#HOME_DIRECTORY} is always added to this
61          * list, {@link ConfigurationLocation#CUSTOM} has to be enabled by calling
62          * {@link #setCustomLocation(String)}.
63          */
64         public ConfigurationLocator() {
65                 /* are we executed from a JAR file? */
66                 String resource = getClass().getResource("/" + getClass().getName().replace(".", "/") + ".class").toString();
67                 if (resource.startsWith("jar:")) {
68                         String jarFileLocation = resource.substring(9, resource.indexOf(".jar!") + 4);
69                         String jarFileDirectory = new File(jarFileLocation).getParent();
70                         File configurationFile = new File(jarFileDirectory, "jSite.conf");
71                         configurationFiles.put(ConfigurationLocation.NEXT_TO_JAR_FILE, configurationFile.getPath());
72                 }
73                 File homeDirectoryFile = new File(System.getProperty("user.home"), ".jSite/config7");
74                 configurationFiles.put(ConfigurationLocation.HOME_DIRECTORY, homeDirectoryFile.getPath());
75         }
76
77         //
78         // ACCESSORS
79         //
80
81         /**
82          * Sets the location of the custom configuration file.
83          *
84          * @param customFile
85          *            The custom location of the configuration file
86          */
87         public void setCustomLocation(String customFile) {
88                 configurationFiles.put(ConfigurationLocation.CUSTOM, customFile);
89         }
90
91         /**
92          * Returns whether the given location is valid. Certain locations (such as
93          * {@link ConfigurationLocation#NEXT_TO_JAR_FILE}) may be invalid in certain
94          * circumstances (such as the application not being run from a JAR file). A
95          * location being valid does not imply that a configuration file does exist
96          * at the given location, use {@link #hasFile(ConfigurationLocation)} to
97          * check for a configuration file at the desired location.
98          *
99          * @param configurationLocation
100          *            The configuration location
101          * @return {@code true} if the location is valid, {@code false} otherwise
102          */
103         public boolean isValidLocation(ConfigurationLocation configurationLocation) {
104                 return configurationFiles.containsKey(configurationLocation);
105         }
106
107         /**
108          * Checks whether a configuration file exists at the given location.
109          *
110          * @param configurationLocation
111          *            The configuration location
112          * @return {@code true} if a configuration file exists at the given
113          *         location, {@code false} otherwise
114          */
115         public boolean hasFile(ConfigurationLocation configurationLocation) {
116                 if (!isValidLocation(configurationLocation)) {
117                         return false;
118                 }
119                 return new File(configurationFiles.get(configurationLocation)).exists();
120         }
121
122         /**
123          * Returns the configuration file for the given location.
124          *
125          * @param configurationLocation
126          *            The location to get the file for
127          * @return The name of the configuration file at the given location, or
128          *         {@code null} if the given location is invalid
129          */
130         public String getFile(ConfigurationLocation configurationLocation) {
131                 return configurationFiles.get(configurationLocation);
132         }
133
134         //
135         // ACTIONS
136         //
137
138         /**
139          * Finds the preferred location of the configuration file.
140          *
141          * @see #findPreferredLocation(ConfigurationLocation)
142          * @return The preferred location of the configuration file
143          */
144         public ConfigurationLocation findPreferredLocation() {
145                 return findPreferredLocation(ConfigurationLocation.NEXT_TO_JAR_FILE);
146         }
147
148         /**
149          * Finds the preferred location of the configuration file. The following
150          * checks are performed: if a custom configuration location has been defined
151          * (by calling {@link #setCustomLocation(String)})
152          * {@link ConfigurationLocation#CUSTOM} is returned. If the application is
153          * run from a JAR file and a configuration file is found next to the JAR
154          * file (i.e. in the same directory),
155          * {@link ConfigurationLocation#NEXT_TO_JAR_FILE} is returned. If a
156          * configuration file exists in the user’s home directory,
157          * {@link ConfigurationLocation#HOME_DIRECTORY} is returned. Otherwise, the
158          * given {@code defaultLocation} is returned.
159          *
160          * @param defaultLocation
161          *            The default location to return if no other configuration file
162          *            is found
163          * @return The configuration location to load the configuration from
164          */
165         public ConfigurationLocation findPreferredLocation(ConfigurationLocation defaultLocation) {
166                 if (hasFile(ConfigurationLocation.CUSTOM)) {
167                         return ConfigurationLocation.CUSTOM;
168                 }
169                 if (hasFile(ConfigurationLocation.NEXT_TO_JAR_FILE)) {
170                         return ConfigurationLocation.NEXT_TO_JAR_FILE;
171                 }
172                 if (hasFile(ConfigurationLocation.HOME_DIRECTORY)) {
173                         return ConfigurationLocation.HOME_DIRECTORY;
174                 }
175                 if (isValidLocation(defaultLocation)) {
176                         return defaultLocation;
177                 }
178                 return ConfigurationLocation.HOME_DIRECTORY;
179         }
180
181 }