com.sugarcrm.candybean.configuration.Configuration.java Source code

Java tutorial

Introduction

Here is the source code for com.sugarcrm.candybean.configuration.Configuration.java

Source

/**
 * 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();
    }
}