From cb285cbfddfc0b633d6b8cdb4dc0d2bd2b8b51ef Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Thu, 05 Jan 2012 17:34:05 -0500 Subject: [PATCH] Fixed bug in receive hook for repositories in subfolders --- src/com/gitblit/FileSettings.java | 167 ++++++++++++++++--------------------------------------- 1 files changed, 50 insertions(+), 117 deletions(-) diff --git a/src/com/gitblit/FileSettings.java b/src/com/gitblit/FileSettings.java index 01176c0..8ac99f6 100644 --- a/src/com/gitblit/FileSettings.java +++ b/src/com/gitblit/FileSettings.java @@ -18,144 +18,52 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.List; +import java.util.Map; import java.util.Properties; -import java.util.regex.PatternSyntaxException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.gitblit.utils.FileUtils; /** - * Reads GitBlit settings file. + * Dynamically loads and reloads a properties file by keeping track of the last + * modification date. + * + * @author James Moger * */ -public class FileSettings implements IStoredSettings { +public class FileSettings extends IStoredSettings { - private final Logger logger = LoggerFactory.getLogger(FileSettings.class); + protected final File propertiesFile; - private final File propertiesFile; + private final Properties properties = new Properties(); - private Properties properties = new Properties(); - - private long lastread; + private volatile long lastModified; public FileSettings(String file) { + super(FileSettings.class); this.propertiesFile = new File(file); } + /** + * Returns a properties object which contains the most recent contents of + * the properties file. + */ @Override - public List<String> getAllKeys(String startingWith) { - startingWith = startingWith.toLowerCase(); - List<String> keys = new ArrayList<String>(); - Properties props = read(); - for (Object o : props.keySet()) { - String key = o.toString().toLowerCase(); - if (key.startsWith(startingWith)) { - keys.add(key); - } - } - return keys; - } - - @Override - public boolean getBoolean(String name, boolean defaultValue) { - Properties props = read(); - if (props.containsKey(name)) { - try { - String value = props.getProperty(name); - if (value != null && value.trim().length() > 0) { - return Boolean.parseBoolean(value); - } - } catch (Exception e) { - logger.warn("No override setting for " + name + " using default of " + defaultValue); - } - } - return defaultValue; - } - - @Override - public int getInteger(String name, int defaultValue) { - Properties props = read(); - if (props.containsKey(name)) { - try { - String value = props.getProperty(name); - if (value != null && value.trim().length() > 0) { - return Integer.parseInt(value); - } - } catch (Exception e) { - logger.warn("No override setting for " + name + " using default of " + defaultValue); - } - } - return defaultValue; - } - - @Override - public String getString(String name, String defaultValue) { - Properties props = read(); - if (props.containsKey(name)) { - try { - String value = props.getProperty(name); - if (value != null) { - return value; - } - } catch (Exception e) { - logger.warn("No override setting for " + name + " using default of " + defaultValue); - } - } - return defaultValue; - } - - @Override - public List<String> getStrings(String name) { - return getStrings(name, " "); - } - - @Override - public List<String> getStringsFromValue(String value) { - return getStringsFromValue(value, " "); - } - - @Override - public List<String> getStrings(String name, String separator) { - List<String> strings = new ArrayList<String>(); - Properties props = read(); - if (props.containsKey(name)) { - String value = props.getProperty(name); - strings = getStringsFromValue(value, separator); - } - return strings; - } - - @Override - public List<String> getStringsFromValue(String value, String separator) { - List<String> strings = new ArrayList<String>(); - try { - String[] chunks = value.split(separator); - for (String chunk : chunks) { - chunk = chunk.trim(); - if (chunk.length() > 0) { - strings.add(chunk); - } - } - } catch (PatternSyntaxException e) { - logger.error("Failed to parse " + value, e); - } - return strings; - } - - private synchronized Properties read() { - if (propertiesFile.exists() && (propertiesFile.lastModified() > lastread)) { + protected synchronized Properties read() { + if (propertiesFile.exists() && (propertiesFile.lastModified() > lastModified)) { FileInputStream is = null; try { - properties = new Properties(); + Properties props = new Properties(); is = new FileInputStream(propertiesFile); - properties.load(is); - lastread = propertiesFile.lastModified(); + props.load(is); + + // load properties after we have successfully read file + properties.clear(); + properties.putAll(props); + lastModified = propertiesFile.lastModified(); } catch (FileNotFoundException f) { // IGNORE - won't happen because file.exists() check above } catch (Throwable t) { - t.printStackTrace(); + logger.error("Failed to read " + propertiesFile.getName(), t); } finally { if (is != null) { try { @@ -169,6 +77,31 @@ return properties; } + /** + * Updates the specified settings in the settings file. + */ + public synchronized boolean saveSettings(Map<String, String> settings) { + String content = FileUtils.readContent(propertiesFile, "\n"); + for (Map.Entry<String, String> setting:settings.entrySet()) { + String regex = "(?m)^(" + regExEscape(setting.getKey()) + "\\s*+=\\s*+)" + + "(?:[^\r\n\\\\]++|\\\\(?:\r?\n|\r|.))*+$"; + content = content.replaceAll(regex, setting.getKey() + " = " + setting.getValue()); + } + FileUtils.writeContent(propertiesFile, content); + return true; + } + + private String regExEscape(String input) { + return input.replace(".", "\\."); + } + + /** + * @return the last modification date of the properties file + */ + protected long lastModified() { + return lastModified; + } + @Override public String toString() { return propertiesFile.getAbsolutePath(); -- Gitblit v1.9.1