package elw.dao; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.*; /** * Configuration is better to be exposed as * bean delegating back to CompositeConfiguration directly. * <p/> * Here we create/cache CompositeConfiguration instances * for any given baseName (which should be product/component-dependent). * * @see CompositeConfiguration */ public class ConfigLoader { private static final Logger log = LoggerFactory.getLogger(ConfigLoader.class); public static final int RELOAD_DELAY_MILLIS = 5 * 60 * 1000; public static final int RELOAD_DELAY_DEVMODE_MILLIS = 100; private static final Map<String, CompositeConfiguration> baseNameToCompositeConf = new TreeMap<String, CompositeConfiguration>(); public static CompositeConfiguration getConfiguration( final String baseName ) { final boolean devMode = new File( System.getProperty("user.home"), "devmode" ).exists(); synchronized (ConfigLoader.class) { final CompositeConfiguration existing = baseNameToCompositeConf.get(baseName); if (existing != null) { return existing; } final CompositeConfiguration created = loadConfig( baseName, devMode ? RELOAD_DELAY_DEVMODE_MILLIS : RELOAD_DELAY_MILLIS ); baseNameToCompositeConf.put(baseName, created); return created; } } protected static CompositeConfiguration loadConfig( final String baseName, final int refreshDelay ) { try { return loadConfigChecked(baseName, refreshDelay); } catch (MalformedURLException e) { throw new IllegalStateException( "URLs formed this way should not be malformed, I think", e ); } catch (ConfigurationException e) { throw new IllegalStateException( "Not sure what is going on, thus propagate", e ); } } protected static CompositeConfiguration loadConfigChecked( final String baseName, final int refreshDelay ) throws MalformedURLException, ConfigurationException { final FileChangedReloadingStrategy reloadStrategy = new FileChangedReloadingStrategy(); reloadStrategy.setRefreshDelay(refreshDelay); final Collection<Configuration> configurations = new ArrayList<Configuration>(); final String fileName = baseName + ".properties"; final File cwdFile = new File(System.getProperty("user.dir"), fileName); if (cwdFile.isFile()) { log.info("found config in {}", cwdFile.getPath()); configurations.add( createConf(cwdFile.toURI().toURL(), reloadStrategy) ); } final File homeFile = new File(System.getProperty("user.home"), fileName); if (homeFile.isFile()) { log.info("found config in {}", homeFile.getPath()); configurations.add( createConf(homeFile.toURI().toURL(), reloadStrategy) ); } final String osName = System.getProperty("os.name").toLowerCase(); if (osName.contains("linux") || osName.contains("unix")) { final File etcDir = new File("/etc"); if (etcDir.isDirectory()) { final File etcFile = new File(etcDir, fileName); if (etcFile.isFile()) { log.info("found config in {}", etcFile.getPath()); configurations.add( createConf(etcFile.toURI().toURL(), reloadStrategy) ); } } } final URL classpathUrl = ConfigLoader.class.getClassLoader().getResource("/" + fileName); if (classpathUrl != null) { log.info("found config in {}", classpathUrl); configurations.add(createConf(classpathUrl, null)); } return new CompositeConfiguration(configurations); } protected static PropertiesConfiguration createConf( final URL resourceUrl, final FileChangedReloadingStrategy reloadStrategy ) throws ConfigurationException { final PropertiesConfiguration propConf = new PropertiesConfiguration(); propConf.setListDelimiter((char) 0); propConf.setDelimiterParsingDisabled(true); if (reloadStrategy != null) { propConf.setReloadingStrategy(reloadStrategy); } propConf.load(resourceUrl); return propConf; } }