James Moger
2012-02-16 3cc6e2de29a0fa33dd585e938e1614a6dd5f9755
commit | author | age
f13c4c 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
5fe7df 16 package com.gitblit;
JM 17
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileNotFoundException;
97a20e 21 import java.util.Map;
5fe7df 22 import java.util.Properties;
97a20e 23
JM 24 import com.gitblit.utils.FileUtils;
5fe7df 25
JM 26 /**
892570 27  * Dynamically loads and reloads a properties file by keeping track of the last
JM 28  * modification date.
29  * 
30  * @author James Moger
5fe7df 31  * 
JM 32  */
f339f5 33 public class FileSettings extends IStoredSettings {
2a7306 34
8c9a20 35     protected final File propertiesFile;
db653a 36
f339f5 37     private final Properties properties = new Properties();
5fe7df 38
892570 39     private volatile long lastModified;
5fe7df 40
28d6b2 41     public FileSettings(String file) {
f339f5 42         super(FileSettings.class);
28d6b2 43         this.propertiesFile = new File(file);
JM 44     }
db653a 45
892570 46     /**
JM 47      * Returns a properties object which contains the most recent contents of
48      * the properties file.
49      */
87cc1e 50     @Override
f339f5 51     protected synchronized Properties read() {
892570 52         if (propertiesFile.exists() && (propertiesFile.lastModified() > lastModified)) {
2a7306 53             FileInputStream is = null;
5fe7df 54             try {
f339f5 55                 Properties props = new Properties();
28d6b2 56                 is = new FileInputStream(propertiesFile);
f339f5 57                 props.load(is);
85c2e6 58
f339f5 59                 // load properties after we have successfully read file
JM 60                 properties.clear();
61                 properties.putAll(props);
892570 62                 lastModified = propertiesFile.lastModified();
5fe7df 63             } catch (FileNotFoundException f) {
2a7306 64                 // IGNORE - won't happen because file.exists() check above
5fe7df 65             } catch (Throwable t) {
f339f5 66                 logger.error("Failed to read " + propertiesFile.getName(), t);
2a7306 67             } finally {
JM 68                 if (is != null) {
69                     try {
70                         is.close();
71                     } catch (Throwable t) {
72                         // IGNORE
73                     }
74                 }
5fe7df 75             }
JM 76         }
77         return properties;
78     }
2a7306 79
892570 80     /**
97a20e 81      * Updates the specified settings in the settings file.
JM 82      */
83     public synchronized boolean saveSettings(Map<String, String> settings) {
84         String content = FileUtils.readContent(propertiesFile, "\n");
85         for (Map.Entry<String, String> setting:settings.entrySet()) {
86             String regex = "(?m)^(" + regExEscape(setting.getKey()) + "\\s*+=\\s*+)"
87                     + "(?:[^\r\n\\\\]++|\\\\(?:\r?\n|\r|.))*+$";            
88             content = content.replaceAll(regex, setting.getKey() + " = " + setting.getValue());
89         }
90         FileUtils.writeContent(propertiesFile, content);
91         return true;
92     }
93     
94     private String regExEscape(String input) {
95         return input.replace(".", "\\.");
96     }
97
98     /**
892570 99      * @return the last modification date of the properties file
JM 100      */
101     protected long lastModified() {
102         return lastModified;
85c2e6 103     }
JM 104
87cc1e 105     @Override
JM 106     public String toString() {
28d6b2 107         return propertiesFile.getAbsolutePath();
87cc1e 108     }
5fe7df 109 }