Java tutorial
/** * Candybean is a next generation automation and testing framework suite. * It is a collection of components that foster test automation, execution * configuration, data abstraction, results illustration, tag-based execution, * top-down and bottom-up batches, mobile variants, test translation across * languages, plain-language testing, and web service testing. * Copyright (C) 2013 SugarCRM, Inc. <candybean@sugarcrm.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.sugarcrm.candybean.configuration; import java.io.*; import java.util.Enumeration; import com.sugarcrm.candybean.exceptions.CandybeanException; import org.json.simple.JSONObject; import java.util.Map; import java.util.Properties; import java.util.logging.Logger; import com.sugarcrm.candybean.utilities.Utils; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; /** * Configuration is an object that represents a set of key-value pairs. * * When requesting a value for a given key, the configuration object will first try to * return the system defined environment variable for the key. If it is not defined, * configuration will return the value defined in the properties file, and finally return * a default value if it not found using the first two methods. */ public class Configuration { /** * The tangible file associated with this object. */ public final File configFile; /** * The .properties file associated with this object. */ private Properties properties; /** * A private logger for this object. */ private Logger logger; /** * A Configuration object with no physical file path given. The properties initialized * with the default properties. */ public Configuration() { this.configFile = null; properties = new Properties(); this.logger = Logger.getLogger(Configuration.class.getSimpleName()); } /** * A Configuration object with physical file path given * @param configFile * @throws IOException * @throws CandybeanException */ public Configuration(File configFile) throws IOException, CandybeanException { if (!configFile.exists()) { throw new CandybeanException(configFile.getAbsolutePath() + " does not exist."); } this.configFile = configFile; properties = new Properties(); this.logger = Logger.getLogger(Configuration.class.getSimpleName()); this.load(configFile); } /** * This method finds and returns the proper cascading configuration value for a given key. * * Returns the system value if defined otherwise it looks in the properties and * finally the defaults. * * @param key * @return cascading configuration value */ public String getValue(String key) { String systemValue = System.getProperty(key); return systemValue != null ? systemValue : properties.getProperty(key); } /** * This method looks for the key-value pair in the system and properties object and returns * the default value if it is not found. * * @param key * @param defaultValue * @return cascading value or default value */ public String getValue(String key, String defaultValue) { return getValue(key) != null ? getValue(key) : defaultValue; } /** * Sets the key value pair in the properties variable. * * @param key * @param value * @return the previously stored value for the key or null if none. */ public Object setValue(String key, String value) { logger.info("Set key value property: {" + key + ", " + value + "}"); return properties.setProperty(key, value); } /** * @return copy of the properties */ public Properties getPropertiesCopy() { return (Properties) properties.clone(); } /** * This is a newly added method (without defaultValue) to retrieve a path * from the properties file and safely return it after calling Utils.adjustPath * * @param key * @return adjusted path or null if it does not exist. */ public String getPathValue(String key) { String pathValue = getValue(key); return Utils.adjustPath(pathValue); } public void load(File file) throws IOException { try { if (file == null) { throw new FileNotFoundException("Given file is null."); } else { this.load(new FileInputStream(file)); } } catch (FileNotFoundException e) { // get file name using substring of adjustedPath that starts after the last / logger.severe(e.getMessage()); } catch (IOException e) { logger.warning("Unable to load " + file.getCanonicalPath() + ".\n"); logger.severe(e.getMessage()); } catch (NullPointerException e) { logger.warning("File path is null.\n"); logger.severe(e.getMessage()); } } private void load(InputStream in) throws IOException { this.properties.load(in); String platform = Utils.getCurrentPlatform(); Enumeration<?> e = properties.propertyNames(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); String value = properties.getProperty(key); JSONParser parser = new JSONParser(); String newValue; try { Object valueObject = parser.parse(value); //get value for current platform key if (valueObject instanceof Map) { JSONObject valueMap = (JSONObject) valueObject; newValue = (String) valueMap.get(platform); } else { newValue = value; } } catch (ParseException pe) { //parsedString is not a smartValue/json object. newValue = value; } properties.setProperty(key, newValue); } } public static String getPlatformValue(Properties props, String key) { String platform = Utils.getCurrentPlatform(); String valueStr = props.getProperty(key); JSONParser parser = new JSONParser(); try { Object valueObject = parser.parse(valueStr); if (valueObject instanceof Map) { JSONObject valueMap = (JSONObject) valueObject; return (String) valueMap.get(platform); } else { return valueStr; } } catch (ParseException pe) { return valueStr; } } /** * Writes the property list from the Properties table to the file path in a format suitable for loading into * a properties table using the load(InputStream) or load(String) method. * * @param file * @throws IOException */ public void store(File file) throws IOException { try { store(new FileOutputStream(file)); } catch (IOException e) { logger.warning("Unable to store " + file.getCanonicalPath() + ".\n"); logger.severe(e.getMessage()); } } /* * Stores the current properties to the provided file * @param properties * @param file * @throws IOException */ private void store(Properties properties, File file) throws IOException { try { properties.store(new FileOutputStream(file), ""); } catch (IOException e) { logger.warning("Unable to store " + file.getCanonicalPath() + ".\n"); logger.severe(e.getMessage()); } } public boolean hasKey(String key) { return properties.containsKey(key); } /** * Writes the property list from the Properties table to the output stream in a format suitable for loading into * a properties table using the load(InputStream) method. * * @param out */ public void store(OutputStream out) throws IOException { properties.store(out, null); } /** * Overwrites the config file associated with this Configuration with the new properties * @param properties * @throws IOException */ public void overwrite(Properties properties) throws IOException { store(properties, configFile); } /** * Describes this Configuration object in string format. */ @Override public String toString() { return "Configuration(" + properties.toString() + ")"; } /** * Clears the Properties object so that it contains no keys. */ public void clear() { logger.warning("Clearing properties..."); properties.clear(); } }