Project

General

Profile

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

    
68
    /**
69
     * suggested sub folder for web app related data and configurations.
70
     * Each webapp instance should use a dedicated subfolder or file
71
     * which is named by the data source bean id.
72
     */
73
    public static final String SUBFOLDER_WEBAPP = "remote-webapp";
74

    
75
    protected Environment env;
76

    
77
    @Override
78
    public void setEnvironment(Environment environment) {
79
        this.env = environment;
80
        if(userHome == null){
81
            ConfigFileUtil.userHome = env.getRequiredProperty("user.home");
82
            ConfigFileUtil.perUserCdmFolder = new File(userHome + File.separator + CDM_FOLDER_NAME );
83
            logger.info("user.home is set to " + ConfigFileUtil.userHome);
84
        }
85
    }
86

    
87
    public static File getCdmHomeDir() {
88
       return perUserCdmFolder;
89
    }
90

    
91
    @Deprecated
92
    public static File getCdmHomeDirFallback() {
93
        return new File(perUserCdmFolder, CDM_FOLDER_NAME);
94
     }
95

    
96

    
97
    /**
98
     * Returns specified the sub folder of  {@link #CDM_FOLDER_NAME}.
99
     * If the sub folder does not exist it will be created.
100
     *
101
     * @param subFolderName
102
     * @return the sub folder or null in case the folder did not exist ant the attempt to create it has failed.
103
     *
104
     * @see {@link #SUBFOLDER_WEBAPP}
105
     */
106
    public static File getCdmHomeSubDir(String subFolderName) {
107
        try{
108
            File parentFolder = getCdmHomeDir();
109
            return ensureSubfolderExists(parentFolder, subFolderName);
110
        }catch(Exception e){
111
            File parentFolder = perUserCdmFolderFallback();
112
            return ensureSubfolderExists(parentFolder, subFolderName);
113
        }
114
    }
115

    
116
    /**
117
     * Returns an instance specific folder folder in  {@link #CDM_FOLDER_NAME}/<code>subFolderName</code>
118
     * Non existing folders will be created.
119
     *
120
     * @param subFolderName
121
     *      The name of a subfolded. In most cases this will be {@link #SUBFOLDER_WEBAPP}
122
     * @param instanceName
123
     *      The name of the application instance. The name should be related to the data source id.
124
     * @return the sub folder or null in case the folder did not exist ant the attempt to create it has failed.
125
     *
126
     * @see {@link #SUBFOLDER_WEBAPP}
127
     */
128
    public static File getCdmInstanceSubDir(String subFolderName, String instanceName) {
129

    
130
        File subfolder = ensureSubfolderExists(getCdmHomeDir(), subFolderName);
131
        return ensureSubfolderExists(subfolder, instanceName);
132
    }
133

    
134
    /**
135
     * @param subFolderName
136
     * @param parentFolder
137
     * @return
138
     */
139
    private static File ensureSubfolderExists(File parentFolder, String subFolderName) {
140
        if (!parentFolder.exists()){
141
            if (!parentFolder.mkdir()) {
142
                throw new RuntimeException("Parent folder could not be created: " + parentFolder.getAbsolutePath());
143
            }
144
        }
145

    
146
        File subfolder = new File(parentFolder, subFolderName);
147
        // if the directory does not exist, create it
148
        if (!subfolder.exists()) {
149
            if (!subfolder.mkdir()) {
150
                throw new RuntimeException("Subfolder could not be created: " + subfolder.getAbsolutePath());
151
            }
152
        }
153
        return subfolder;
154
    }
155
    public static final String CDM_CONFIGFILE_OVERRIDE = "cdm.configfile.override.";
156

    
157
    private Properties props = null;
158

    
159
    private String defaultContent = "";
160

    
161
    public ConfigFileUtil(){
162
        super();
163
    }
164

    
165
    public ConfigFileUtil setDefaultContent(String content) {
166
        if(content != null){
167
            defaultContent = content;
168
        }
169
        return this;
170
    }
171

    
172
    /**
173
     * Per default the <code>propertiesSet</code> is loaded from a file located in
174
     * <code>~/.cdmLibrary/remote-webapp/{instanceName}/{propertiesSet}.properties</code>.
175
     * <p>
176
     * This behavior can be overwritten by setting the java System property
177
     * <code>cdm.configfile.override.{propertiesSet}</code> to an alternative file location.
178
     * This mechanism should only be used for unit and integration tests.
179
     *
180
     * @param instanceName the name of the cdm instance. This value can be retrieved from the
181
     *      Spring environment with the key DataSourceConfigurer.CDM_DATA_SOURCE_ID ("")
182
     * @param propertiesSet
183
     *      The base name of the properties file to be loaded. This name is extended with
184
     *      ".properties" to form the actual filename
185
     *
186
     * @return
187
     *      The file containing the properties
188
     */
189
    public File getPropertiesFile(String instanceName, String propertiesSet) {
190

    
191
        if(propertiesSet == null){
192
            throw new NullPointerException();
193
        }
194
        String override = System.getProperty(CDM_CONFIGFILE_OVERRIDE + propertiesSet);
195
        if(override != null){
196
            return new File(override);
197
        } else {
198
            File configFolder = ConfigFileUtil.getCdmInstanceSubDir(ConfigFileUtil.SUBFOLDER_WEBAPP, instanceName);
199
            return new File(configFolder, propertiesSet + ".properties");
200
        }
201
    }
202

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

    
222
        if(instanceName == null){
223
            throw new NullPointerException();
224
        }
225
        if(props == null){
226
            props = new Properties();
227
            File uiPropertiesFile = getPropertiesFile(instanceName, propertiesName);
228
            if(!uiPropertiesFile.exists()){
229
                BufferedWriter writer = Files.newBufferedWriter(uiPropertiesFile.toPath());
230
                writer.write(defaultContent);
231
                writer.close();
232
            }
233
            try {
234
                props.load(new FileInputStream(uiPropertiesFile));
235
            } catch (FileNotFoundException e) {
236
                // must not happen since we checked before
237
            }
238

    
239
        }
240
        return props;
241
    }
242
}
(8-8/11)