From 0bbdd9f9adf12ad9082a4c49ae1c9a0778b00bb4 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Wed, 28 Nov 2012 17:39:12 -0500 Subject: [PATCH] Fixed focus for keystore password prompt --- src/com/gitblit/FileSettings.java | 209 ++++++++++++++++++++++++---------------------------- 1 files changed, 97 insertions(+), 112 deletions(-) diff --git a/src/com/gitblit/FileSettings.java b/src/com/gitblit/FileSettings.java index 371b734..be1f44f 100644 --- a/src/com/gitblit/FileSettings.java +++ b/src/com/gitblit/FileSettings.java @@ -1,143 +1,128 @@ +/* + * Copyright 2011 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.gitblit; 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 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 Properties properties = new Properties(); + protected final File propertiesFile; - private long lastread = 0; + private final Properties properties = new Properties(); - private final Logger logger = LoggerFactory.getLogger(FileSettings.class); + private volatile long lastModified; + + private volatile boolean forceReload; - @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; + 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 boolean getBoolean(String name, boolean defaultValue) { - Properties props = read(); - if (props.containsKey(name)) { + protected synchronized Properties read() { + if (propertiesFile.exists() && (forceReload || (propertiesFile.lastModified() > lastModified))) { + FileInputStream is = null; 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; - } + Properties props = new Properties(); + is = new FileInputStream(propertiesFile); + props.load(is); - @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 (Exception e) { - } - return strings; - } - - private synchronized Properties read() { - File file = new File(Constants.PROPERTIES_FILE); - if (file.exists() && (file.lastModified() > lastread)) { - try { - properties = new Properties(); - properties.load(new FileInputStream(Constants.PROPERTIES_FILE)); - lastread = file.lastModified(); + // load properties after we have successfully read file + properties.clear(); + properties.putAll(props); + lastModified = propertiesFile.lastModified(); + forceReload = false; } 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 { + is.close(); + } catch (Throwable t) { + // IGNORE + } + } } } 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|.))*+$"; + String oldContent = content; + content = content.replaceAll(regex, setting.getKey() + " = " + setting.getValue()); + if (content.equals(oldContent)) { + // did not replace value because it does not exist in the file + // append new setting to content (issue-85) + content += "\n" + setting.getKey() + " = " + setting.getValue(); + } + } + FileUtils.writeContent(propertiesFile, content); + // manually set the forceReload flag because not all JVMs support real + // millisecond resolution of lastModified. (issue-55) + forceReload = true; + return true; + } + private String regExEscape(String input) { + return input.replace(".", "\\."); + } + + /** + * @return the last modification date of the properties file + */ + protected long lastModified() { + return lastModified; + } + + /** + * @return the state of the force reload flag + */ + protected boolean forceReload() { + return forceReload; + } + @Override public String toString() { - return getClass().getSimpleName() + ": " + new File(Constants.PROPERTIES_FILE).getAbsolutePath(); + return propertiesFile.getAbsolutePath(); } } -- Gitblit v1.9.1