package de.tum.in.i22.uc.cm.settings; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SettingsLoader { private static final Logger _logger = LoggerFactory.getLogger(SettingsLoader.class); protected Map<String, Entry<?>> _settings; protected Properties _props; /** * Tries to load <code>propertiesFileName</code> from the directory where the jar file is executed. * If the file is not present there, it will be loaded from the jar file itself. * This enables to easily override default properties which are specified in the file which * is placed in the resource folder in the jar. * * @param propertiesFileName Name of the properties file to be loaded. * @return Properties object with loaded properties. * @throws IOException In case the file cannot be loaded. */ void initProperties(String propertiesFileName) throws IOException { _logger.debug("Loading properties file: " + propertiesFileName); InputStream is = null; File file = null; boolean fileFound = false; try { file = new File(propertiesFileName); fileFound = file.exists(); _logger.debug("Searching properties file " + propertiesFileName + " ... " + (fileFound ? "Found" : "Not found") + "."); if (!fileFound) { file = new File(new File("."), propertiesFileName); fileFound = file.exists(); _logger.debug("Searching properties file " + propertiesFileName + " in jar parent directory ... " + (fileFound ? "Found" : "Not found") + "."); } if (!fileFound) { _logger.debug("Searching properties file " + propertiesFileName + " in resources ... "); is = SettingsLoader.class.getClassLoader().getResourceAsStream(propertiesFileName); } if (fileFound && is == null) { is = new FileInputStream(file); } if (is == null) { throw new IOException("Properties file not found."); } // load a properties file _props = new Properties(); // load all the properties from this file _props.load(is); _logger.debug("Properties file '" + propertiesFileName + "' loaded."); } finally { if (is != null) { // we have loaded the properties, so close the file handler try { is.close(); } catch (IOException e) { _logger.error("Failed to close input stream for properties file.", e); } } } } protected <T extends Object> T loadSettingFinalize(boolean success, String propName, T loadedValue, T defaultValue) { T returnValue=null; if (success) { _logger.info("Property [" + propName + "] loaded. Value: [" + loadedValue + "]."); returnValue=loadedValue; } else { _logger.warn("Property [" + propName + "] not found. Using default value [" + defaultValue + "]."); returnValue=defaultValue; } _settings.put(propName, putValue(returnValue)); return returnValue; } public int loadSetting(String propName, int defaultValue) { int loadedValue = defaultValue; boolean success = false; try { if (_props != null) { loadedValue = Integer.valueOf((String) _props.get(propName)); success = true; } } catch (Exception e) { success = false; } return loadSettingFinalize(success, propName, loadedValue, defaultValue); } public String loadSetting(String propName, String defaultValue) { String loadedValue = defaultValue; boolean success = false; try { if (_props != null) { loadedValue = (String) _props.get(propName); if (loadedValue != null) { success = true; } } } catch (Exception e) { } return loadSettingFinalize(success, propName, loadedValue, defaultValue); } public boolean loadSetting(String propName, boolean defaultValue) { boolean loadedValue = defaultValue; boolean success = false; try { if (_props != null) { String s = _props.getProperty(propName); if (s != null) { loadedValue = Boolean.valueOf(s); success = true; } } } catch (Exception e) { } return loadSettingFinalize(success, propName, loadedValue, defaultValue); } public <T> void setProperty(String propName, T value) { _settings.put(propName, new Entry<T>(value.getClass(), value)); } protected Entry<Object> putValue(Object obj) { return new Entry<Object>(obj.getClass(), obj); } protected <T> T getValue(String propName) { @SuppressWarnings("unchecked") Entry<T> e = (Entry<T>) _settings.get(propName); if (e==null) return null; return e.getValue(); } protected class Entry<T> { private Class<T> _type; private T _value; @SuppressWarnings("unchecked") public Entry(Class<? extends Object> type, T value) { _type = (Class<T>) type; _value = value; } public T getValue() { return _value; } public Class<T> getType() { return _type; } } }