Project

General

Profile

Download (9.45 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.config;
10

    
11
import java.io.BufferedWriter;
12
import java.io.File;
13
import java.io.FileInputStream;
14
import java.io.FileNotFoundException;
15
import java.io.IOException;
16
import java.nio.file.Files;
17
import java.util.Properties;
18

    
19
import org.apache.log4j.Logger;
20
import org.springframework.context.EnvironmentAware;
21
import org.springframework.core.env.Environment;
22

    
23
/**
24
 * Utility class for consistent access to and creation of per instance application configuration files.
25
 *
26
 * @author a.mueller
27
 * @author a.kohlbecker
28
 */
29
public class ConfigFileUtil implements EnvironmentAware {
30

    
31
    private static final Logger logger = Logger.getLogger(ConfigFileUtil.class);
32

    
33
    private static String userHome = null;
34

    
35
    /**
36
     * The per user cdm folder name: ".cdmLibrary"
37
     */
38
    private static final String CDM_FOLDER_NAME = ".cdmLibrary";
39

    
40
    /**
41
     * The per user cdm folder "~/.cdmLibrary"
42
     */
43
    private static File perUserCdmFolder = null;
44

    
45
    public static File perUserCdmFolder() {
46
        return perUserCdmFolder;
47
    }
48

    
49
    /**
50
     * @deprecated use {@link #perUserCdmFolder()} instead
51
     */
52
    @Deprecated
53
    public static File getCdmHomeDir() {
54
        return perUserCdmFolder;
55
    }
56

    
57
    /**
58
     * Provides the <code>${user.home}./cdmLibrary</code> folder without taking
59
     * additional property sources into account which could be configured in
60
     * the Spring application context.
61
     * <p>
62
     * This method can be used if an application context is not (yet) available, but
63
     * should be used with caution, since this location might differ from the location
64
     * used by other components of the application which make use of the
65
     * {@link #perUserCdmFolder()} method.
66
     *
67
     * @deprecated Marked as deprecated as warning sign in the hope developers will
68
     * read the java doc for this method when using it.
69
     *
70
     */
71
    @Deprecated
72
    public static File perUserCdmFolderFallback() {
73
        return new File(System.getProperty("user.home"), CDM_FOLDER_NAME);
74
    }
75

    
76
    /**
77
     * @deprecated use {@link #perUserCdmFolderFallback()} instead
78
     */
79
    @Deprecated
80
    public static File getCdmHomeDirFallback() {
81
        return perUserCdmFolderFallback();
82
    }
83

    
84
    /**
85
     * suggested sub folder for web app related data and configurations.
86
     * Each webapp instance should use a dedicated subfolder or file
87
     * which is named by the data source bean id.
88
     */
89
    public static final String SUBFOLDER_WEBAPP = "remote-webapp";
90

    
91
    protected Environment env;
92

    
93
    @Override
94
    public void setEnvironment(Environment environment) {
95
        this.env = environment;
96
        if(userHome == null){
97
            ConfigFileUtil.userHome = env.getRequiredProperty("user.home");
98
            ConfigFileUtil.perUserCdmFolder = new File(userHome, CDM_FOLDER_NAME);
99
            logger.info("user.home is set to " + ConfigFileUtil.userHome);
100
        }
101
    }
102

    
103

    
104
    /**
105
     * Returns specified the sub folder of  {@link #CDM_FOLDER_NAME}.
106
     * If the sub folder does not exist it will be created.
107
     *
108
     * @param subFolderName
109
     * @return the sub folder or null in case the folder did not exist ant the attempt to create it has failed.
110
     *
111
     * @see {@link #SUBFOLDER_WEBAPP}
112
     */
113
    public static File getCdmHomeSubDir(String subFolderName) {
114

    
115
        File parentFolder = getCdmHomeDir();
116
        return ensureSubfolderExists(parentFolder, subFolderName);
117
    }
118

    
119
    /**
120
     * Provides subfolders of <code>${user.home}./cdmLibrary</code> folder without taking
121
     * additional property sources into account which could be configured in
122
     * the Spring application context.
123
     * <p>
124
     * This method can be used if an application context is not (yet) available, but
125
     * should be used with caution, since this location might differ from the location
126
     * used by other components of the application which make use of the
127
     * {@link #perUserCdmFolder()} method.
128
     *
129
     * @deprecated Marked as deprecated as warning sign in the hope developers will
130
     * read the java doc for this method when using it.
131
     *
132
     */
133
    @Deprecated
134
    public static File getCdmHomeSubDirFallback(String subFolderName) {
135

    
136
        File parentFolder = perUserCdmFolderFallback();
137
        return ensureSubfolderExists(parentFolder, subFolderName);
138
    }
139

    
140
    /**
141
     * Returns an instance specific folder folder in  {@link #CDM_FOLDER_NAME}/<code>subFolderName</code>
142
     * Non existing folders will be created.
143
     *
144
     * @param subFolderName
145
     *      The name of a subfolded. In most cases this will be {@link #SUBFOLDER_WEBAPP}
146
     * @param instanceName
147
     *      The name of the application instance. The name should be related to the data source id.
148
     * @return the sub folder or null in case the folder did not exist ant the attempt to create it has failed.
149
     *
150
     * @see {@link #SUBFOLDER_WEBAPP}
151
     */
152
    public static File getCdmInstanceSubDir(String subFolderName, String instanceName) {
153

    
154
        File subfolder = ensureSubfolderExists(getCdmHomeDir(), subFolderName);
155
        return ensureSubfolderExists(subfolder, instanceName);
156
    }
157

    
158
    /**
159
     * @param subFolderName
160
     * @param parentFolder
161
     * @return
162
     */
163
    private static File ensureSubfolderExists(File parentFolder, String subFolderName) {
164
        if (!parentFolder.exists()){
165
            if (!parentFolder.mkdir()) {
166
                throw new RuntimeException("Parent folder could not be created: " + parentFolder.getAbsolutePath());
167
            }
168
        }
169

    
170
        File subfolder = new File(parentFolder, subFolderName);
171
        // if the directory does not exist, create it
172
        if (!subfolder.exists()) {
173
            if (!subfolder.mkdir()) {
174
                throw new RuntimeException("Subfolder could not be created: " + subfolder.getAbsolutePath());
175
            }
176
        }
177
        return subfolder;
178
    }
179
    public static final String CDM_CONFIGFILE_OVERRIDE = "cdm.configfile.override.";
180

    
181
    private Properties props = null;
182

    
183
    private String defaultContent = "";
184

    
185
    public ConfigFileUtil(){
186
        super();
187
    }
188

    
189
    public ConfigFileUtil setDefaultContent(String content) {
190
        if(content != null){
191
            defaultContent = content;
192
        }
193
        return this;
194
    }
195

    
196
    /**
197
     * Per default the <code>propertiesSet</code> is loaded from a file located in
198
     * <code>~/.cdmLibrary/remote-webapp/{instanceName}/{propertiesSet}.properties</code>.
199
     * <p>
200
     * This behavior can be overwritten by setting the java System property
201
     * <code>cdm.configfile.override.{propertiesSet}</code> to an alternative file location.
202
     * This mechanism should only be used for unit and integration tests.
203
     *
204
     * @param instanceName the name of the cdm instance. This value can be retrieved from the
205
     *      Spring environment with the key DataSourceConfigurer.CDM_DATA_SOURCE_ID ("")
206
     * @param propertiesSet
207
     *      The base name of the properties file to be loaded. This name is extended with
208
     *      ".properties" to form the actual filename
209
     *
210
     * @return
211
     *      The file containing the properties
212
     */
213
    public File getPropertiesFile(String instanceName, String propertiesSet) {
214

    
215
        if(propertiesSet == null){
216
            throw new NullPointerException();
217
        }
218
        String override = System.getProperty(CDM_CONFIGFILE_OVERRIDE + propertiesSet);
219
        if(override != null){
220
            return new File(override);
221
        } else {
222
            File configFolder = ConfigFileUtil.getCdmInstanceSubDir(ConfigFileUtil.SUBFOLDER_WEBAPP, instanceName);
223
            return new File(configFolder, propertiesSet + ".properties");
224
        }
225
    }
226

    
227
    /**
228
     * Per default the <code>propertiesSet</code> is loaded from a file located in
229
     * <code>~/.cdmLibrary/remote-webapp/{instanceName}/{propertiesSet}.properties</code>.
230
     * <p>
231
     * This behavior can be overwritten by setting the java System property
232
     * <code>cdm.configfile.override.{propertiesSet}</code> to an alternative file location.
233
     * This mechanism should only be used for unit and integration tests.
234
     *
235
     * @param instanceName the name of the cdm instance. This value can be retrieved from the
236
     *      Spring environment with the key DataSourceConfigurer.CDM_DATA_SOURCE_ID ("")
237
     * @param propertiesSet
238
     *      The base name of the properties file to be loaded. This name is extended with
239
     *      ".properties" to form the actual filename
240
     *
241
     * @return
242
     *      The properties loaded from the file
243
     */
244
    public Properties getProperties(String instanceName, String propertiesName) throws IOException {
245

    
246
        if(instanceName == null){
247
            throw new NullPointerException();
248
        }
249
        if(props == null){
250
            props = new Properties();
251
            File uiPropertiesFile = getPropertiesFile(instanceName, propertiesName);
252
            if(!uiPropertiesFile.exists()){
253
                BufferedWriter writer = Files.newBufferedWriter(uiPropertiesFile.toPath());
254
                writer.write(defaultContent);
255
                writer.close();
256
            }
257
            try {
258
                props.load(new FileInputStream(uiPropertiesFile));
259
            } catch (FileNotFoundException e) {
260
                // must not happen since we checked before
261
            }
262

    
263
        }
264
        return props;
265
    }
266
}
(8-8/11)