import java.io.File;\r
import java.io.FileInputStream;\r
import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.util.List;\r
import java.util.Map;\r
import java.util.Properties;\r
\r
import com.gitblit.utils.FileUtils;\r
+import com.gitblit.utils.StringUtils;\r
\r
/**\r
* Dynamically loads and reloads a properties file by keeping track of the last\r
is = new FileInputStream(propertiesFile);\r
props.load(is);\r
\r
+ // ticket-110\r
+ props = readIncludes(props);\r
+\r
// load properties after we have successfully read file\r
properties.clear();\r
properties.putAll(props);\r
return properties;\r
}\r
\r
+ /**\r
+ * Recursively read "include" properties files.\r
+ *\r
+ * @param properties\r
+ * @return\r
+ * @throws IOException\r
+ */\r
+ private Properties readIncludes(Properties properties) throws IOException {\r
+\r
+ Properties baseProperties = new Properties();\r
+\r
+ String include = (String) properties.remove("include");\r
+ if (!StringUtils.isEmpty(include)) {\r
+\r
+ // allow for multiples\r
+ List<String> names = StringUtils.getStringsFromValue(include, " ");\r
+ for (String name : names) {\r
+\r
+ // try co-located\r
+ File file = new File(propertiesFile.getParentFile(), name.trim());\r
+ if (!file.exists()) {\r
+ // try absolute path\r
+ file = new File(name.trim());\r
+ }\r
+\r
+ if (file.exists()) {\r
+ // load properties\r
+ try (FileInputStream iis = new FileInputStream(file)) {\r
+ baseProperties.load(iis);\r
+ }\r
+\r
+ // read nested includes\r
+ baseProperties = readIncludes(baseProperties);\r
+\r
+ }\r
+\r
+ }\r
+\r
+ }\r
+\r
+ // includes are "default" properties, they must be set first and the\r
+ // props which specified the "includes" must override\r
+ Properties merged = new Properties();\r
+ merged.putAll(baseProperties);\r
+ merged.putAll(properties);\r
+\r
+ return merged;\r
+ }\r
+\r
@Override\r
public boolean saveSettings() {\r
String content = FileUtils.readContent(propertiesFile, "\n");\r