public static ApplicationConfiguration readConfiguration(final String... resources) { if (resources == null) return new ApplicationConfiguration(ImmutableMap.of()); final HashMap<String, String> result = new HashMap<>(); for (String resource : resources) { if (StringTools.isNullOrEmpty(resource)) continue; // Read anything from an external config file or resource if (FileTools.fileExistsAndCanRead(resource)) { mergeConfigMaps(readConfigFileLines(resource), result); } else { mergeConfigMaps(ResourceTools.readResourceTextFileAsMap(resource), result); } } // Check for system properties/envs for overrides // for the known configuration options and apply them // as overrides final Map<String, String> environmentMatches = MapTools.intersectKeysCaseInsensitive(result, System.getenv()); for (Map.Entry<String, String> matchEntry : environmentMatches.entrySet()) { final String envOverride = System.getenv().get(matchEntry.getValue()); if (!StringTools.isNullOrEmpty(envOverride)) { result.put(matchEntry.getKey(), envOverride); } } // Ultimately - command-line properties override everything final Map<String, Object> propertiesMatches = MapTools.intersectKeys( result, System.getProperties(), String::toLowerCase, key -> { if (key instanceof String) { return ((String) key).toLowerCase(); } else { // Do not support non-string matching return UUID.randomUUID().toString(); } }); for (Map.Entry<String, Object> matchEntry : propertiesMatches.entrySet()) { final Object propertiesOverride = System.getProperties().get(matchEntry.getValue()); if (propertiesOverride instanceof String && !StringTools.isNullOrEmpty((String) propertiesOverride)) { result.put(matchEntry.getKey(), (String) propertiesOverride); } } return new ApplicationConfiguration(ImmutableMap.copyOf(result)); }