package org.needle4j.configuration; import java.io.FileNotFoundException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.ResourceBundle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class ConfigurationLoader { private static final Logger LOG = LoggerFactory.getLogger(ConfigurationLoader.class); private final Map<String, String> configProperties; static final String CUSTOM_CONFIGURATION_FILENAME = "needle"; private static final String DEFAULT_CONFIGURATION_FILENAME = "needle-defaults"; /** * @see #ConfigurationLoader(String) */ ConfigurationLoader() { this(CUSTOM_CONFIGURATION_FILENAME); } ConfigurationLoader(final String resourceName) { configProperties = loadResourceAndDefault(resourceName); } /** * @deprecated values are accessed in NeedleConfiguration * @param key the key look at * @return property value for given key */ @Deprecated String getProperty(final String key) { return configProperties.get(key); } /** * @deprecated values are accessed in NeedleConfiguration * @param key the key look at * @return property value for given key */ @Deprecated boolean containsKey(final String key) { return configProperties.containsKey(key); } private static Map<String, String> loadDefaults() { final Map<String, String> defaults = new HashMap<String, String>(); try { final ResourceBundle defaultResourceBundle = ResourceBundle.getBundle(DEFAULT_CONFIGURATION_FILENAME); for (final String key : defaultResourceBundle.keySet()) { addKeyValuePair(defaults, key, defaultResourceBundle.getString(key)); } final URL url = ConfigurationLoader.class.getResource("/" + DEFAULT_CONFIGURATION_FILENAME + ".properties"); LOG.debug("loaded default Needle config from: {}", url); } catch (final Exception e1) { LOG.error("should never happen", e1); throw new RuntimeException("should never happen", e1); } return defaults; } static Map<String, String> loadResourceAndDefault(final String name) { final Map<String, String> result = loadDefaults(); try { final ResourceBundle customBundle = ResourceBundle.getBundle(name); for (final String key : customBundle.keySet()) { addKeyValuePair(result, key, customBundle.getString(key)); } final URL url = NeedleConfiguration.class.getResource("/" + name + ".properties"); LOG.info("loaded Needle config named {} from {}", name, url); } catch (final Exception e) { LOG.warn(e.getMessage()); } return result; } private static void addKeyValuePair(final Map<String, String> target, final String key, final String value) { final String trimmedValue = value.trim(); if (!trimmedValue.equals(value)) { LOG.warn("trimmed value " + value + " to " + trimmedValue + " (key was " + key + ")"); } target.put(key, trimmedValue); } Map<String, String> getConfigProperties() { return configProperties; } /** * Returns an input stream for reading the specified resource. * * @param resource * the resource name * @return an input stream for reading the resource. * @throws FileNotFoundException * if the resource could not be found */ public static InputStream loadResource(final String resource) throws FileNotFoundException { final boolean hasLeadingSlash = resource.startsWith("/"); final String stripped = hasLeadingSlash ? resource.substring(1) : resource; InputStream stream = null; final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader != null) { stream = classLoader.getResourceAsStream(resource); if (stream == null && hasLeadingSlash) { stream = classLoader.getResourceAsStream(stripped); } } if (stream == null) { throw new FileNotFoundException("resource " + resource + " not found"); } return stream; } }