package cc.blynk.utils; import java.io.File; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.CodeSource; import java.util.Map; import java.util.Properties; /** * Java properties class wrapper. * Loads properties file from class path. After that loads properties * from dir where jar file is. On every stage properties override previous. * * The Blynk Project. * Created by Dmitriy Dumanskiy. * Created on 2/12/2015. */ public class ServerProperties extends Properties { public static final String SERVER_PROPERTIES_FILENAME = "server.properties"; public static final String jarPath; static { jarPath = getJarPath(); } public ServerProperties(Map<String, String> cmdProperties) { this(cmdProperties, SERVER_PROPERTIES_FILENAME); } public ServerProperties(Map<String, String> cmdProperties, String serverConfig) { String propertiesFileName = cmdProperties.get(serverConfig); if (propertiesFileName == null) { initProperties(serverConfig); } else { initProperties(Paths.get(propertiesFileName)); } putAll(cmdProperties); } public ServerProperties(String propertiesFileName) { initProperties(propertiesFileName); } private static String getJarPath() { try { CodeSource codeSource = ServerProperties.class.getProtectionDomain().getCodeSource(); File jarFile = new File(codeSource.getLocation().toURI().getPath()); return jarFile.getParentFile().getPath(); } catch (Exception e) { throw new RuntimeException(e); } } public static Path getFileInCurrentDir(String filename) { return Paths.get(jarPath, filename); } /** * First loads properties file from class path after that from current folder. * So properties file in current folder is always overrides properties in classpath. * * @param filePropertiesName - name of properties file, for example "twitter4j.properties" */ private void initProperties(String filePropertiesName) { readFromClassPath(filePropertiesName); Path curDirPath = getFileInCurrentDir(filePropertiesName); if (Files.exists(curDirPath)) { try (InputStream curFolder = Files.newInputStream(curDirPath)) { if (curFolder != null) { load(curFolder); } } catch (Exception e) { throw new RuntimeException("Error getting properties file : " + filePropertiesName, e); } } } private void readFromClassPath(String filePropertiesName) { if (!filePropertiesName.startsWith("/")) { filePropertiesName = "/" + filePropertiesName; } try (InputStream classPath = ServerProperties.class.getResourceAsStream(filePropertiesName)) { if (classPath != null) { load(classPath); } } catch (Exception e) { throw new RuntimeException("Error getting properties file : " + filePropertiesName, e); } } private void initProperties(Path path) { if (!Files.exists(path)) { System.out.println("Path " + path + " not found."); System.exit(1); } readFromClassPath(SERVER_PROPERTIES_FILENAME); try (InputStream curFolder = Files.newInputStream(path)) { if (curFolder != null) { load(curFolder); } } catch (Exception e) { System.out.println("Error reading properties file : '" + path + "'. Reason : " + e.getMessage()); System.exit(1); } } public int getIntProperty(String propertyName) { return ParseUtil.parseInt(getProperty(propertyName)); } public int getIntProperty(String propertyName, int defaultValue) { String prop = getProperty(propertyName); if (prop == null || prop.isEmpty()) { return defaultValue; } return ParseUtil.parseInt(getProperty(propertyName)); } public boolean getBoolProperty(String propertyName) { return Boolean.parseBoolean(getProperty(propertyName)); } public long getLongProperty(String propertyName) { return ParseUtil.parseLong(getProperty(propertyName)); } public long getLongProperty(String propertyName, long defaultValue) { String prop = getProperty(propertyName); if (prop == null || prop.isEmpty()) { return defaultValue; } return ParseUtil.parseLong(prop); } public String[] getCommaSeparatedValueAsArray(String propertyName) { String val = getProperty(propertyName); if (val == null) { return null; } return val.toLowerCase().split(","); } }