James Moger
2014-10-26 3ef46ee3e4a58a78b7cb6fe6c0b6f45da4ae21b9
src/main/java/com/gitblit/FileSettings.java
@@ -18,10 +18,13 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import com.gitblit.utils.FileUtils;
import com.gitblit.utils.StringUtils;
/**
 * Dynamically loads and reloads a properties file by keeping track of the last
@@ -81,6 +84,9 @@
            is = new FileInputStream(propertiesFile);
            props.load(is);
            // ticket-110
            props = readIncludes(props);
            // load properties after we have successfully read file
            properties.clear();
            properties.putAll(props);
@@ -104,6 +110,72 @@
   }
   /**
    * Recursively read "include" properties files.
    *
    * @param properties
    * @return
    * @throws IOException
    */
   private Properties readIncludes(Properties properties) throws IOException {
      Properties baseProperties = new Properties();
      String include = (String) properties.remove("include");
      if (!StringUtils.isEmpty(include)) {
         // allow for multiples
         List<String> names = StringUtils.getStringsFromValue(include, " ");
         for (String name : names) {
            // try co-located
            File file = new File(propertiesFile.getParentFile(), name.trim());
            if (!file.exists()) {
               // try absolute path
               file = new File(name.trim());
            }
            if (file.exists()) {
               // load properties
               try (FileInputStream iis = new FileInputStream(file)) {
                  baseProperties.load(iis);
               }
               // read nested includes
               baseProperties = readIncludes(baseProperties);
            }
         }
      }
      // includes are "default" properties, they must be set first and the
      // props which specified the "includes" must override
      Properties merged = new Properties();
      merged.putAll(baseProperties);
      merged.putAll(properties);
      return merged;
   }
   @Override
   public boolean saveSettings() {
      String content = FileUtils.readContent(propertiesFile, "\n");
      for (String key : removals) {
         String regex = "(?m)^(" + regExEscape(key) + "\\s*+=\\s*+)"
                + "(?:[^\r\n\\\\]++|\\\\(?:\r?\n|\r|.))*+$";
         content = content.replaceAll(regex, "");
      }
      removals.clear();
      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;
   }
   /**
    * Updates the specified settings in the settings file.
    */
   @Override