Skip to content

Commit

Permalink
Modified configuration loading mechanism.
Browse files Browse the repository at this point in the history
Renamed *ConfigLoader to *PropertiesLoader.
Introduced PropertyLoader and DefaultPropertyLoader
Introduced ProxyConfig which contains just the proxy config settings
Renamed package to org.concordion.cubano.config
Made Config and WebDriverConfig final
Removed inheritance from Config and WebDriverConfig
Introduced singletons for DefaultPropertiesLoader, Config and WebDriverConfig to ensure that properties files are only read once, and make it easy to access Config and WebDriverConfig
Removed HttpEasyConfig, since this just uses ProxyConfig
Modified WebDriverConfig to mirror Config and delegate to PropertyLoader

Any specific AppConfig, it will no longer be able to inherit from Config or WebDriverConfig and will need to be modified to delegate to PropertyLoader. See WebDriverConfig for example code.
  • Loading branch information
nigelcharman committed Oct 23, 2017
1 parent 5af705f commit cd6eb05
Show file tree
Hide file tree
Showing 34 changed files with 1,181 additions and 1,101 deletions.
@@ -1,4 +1,4 @@
package org.concordion.cubano.utils;
package org.concordion.cubano.config;

import java.util.Map;
import java.util.Properties;
Expand Down
@@ -0,0 +1,93 @@
package org.concordion.cubano.config;

import java.util.Properties;

/**
* Reads and supplies properties from the <code>config.properties</code> file that are required by the framework.
* <p>
* An optional <code>user.properties</code> file can set user specific values and allow overriding of defaults.
* The <code>user.properties</code> file should NEVER be checked into source control.
*
* @author Andrew Sumner
*/
public final class Config {

private final DefaultPropertyLoader propertyLoader;
private final ProxyConfig proxyConfig = new ProxyConfig();
private String environment;

private static class ConfigHolder {
static final Config INSTANCE = new Config();
}

public static Config getInstance() {
return ConfigHolder.INSTANCE;
}

/**
* Uses DefaultPropertiesLoader to import the config and user properties files.
*/
protected Config() {
this(DefaultPropertiesLoader.getInstance());
}

/**
* Uses the supplied PropertiesLoader to import the config and user properties files.
*
* @param propertiesLoader Configuration loader
*/
protected Config(PropertiesLoader propertiesLoader) {
this(propertiesLoader.getProperties(), propertiesLoader.getUserProperties());
}

/**
* Allow injection of properties for testing purposes.
*
* @param properties Default properties
*/
protected Config(Properties properties) {
this(properties, null);
}

/**
* Load the properties for this configuration.
*
* @param properties Default properties
* @param userProperties User specific overrides
*/
protected Config(Properties properties, Properties userProperties) {
propertyLoader = new DefaultPropertyLoader(properties, userProperties);

// Try environment variable first
environment = System.getProperty("environment", "");

if (environment.isEmpty()) {
environment = propertyLoader.getProperty("environment");
}

propertyLoader.setEnvironment(environment);

proxyConfig.loadProxyProperties(this, propertyLoader);
}

/**
* @return Configured environment.
*/
public String getEnvironment() {
return environment;
}

/**
* @return Configuration for proxy.
*/
public ProxyConfig getProxyConfig() {
return proxyConfig;
}

/**
* @return a loader for loading properties across config.properties and user.properties, taking environment into account.
*/
public PropertyLoader getPropertyLoader() {
return propertyLoader;
}
}
@@ -1,65 +1,73 @@
package org.concordion.cubano.utils;

import java.io.File;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;

/**
* Loads configuration from config.properties and user.properties located in projects root folder.
*
* It also ensures that any single slash character '\' does not require a double slash. This means that
* using \ to wrap long property values across multiple lines won't work.
*/
public class DefaultConfigLoader implements ConfigLoader {
private static final String CONFIG_FILE = "config.properties";
private static final String USER_CONFIG_FILE = "user.properties";

private final Properties properties;
private final Properties userProperties;

/** Ensure properties have been loaded before any property is used. */
public DefaultConfigLoader() {
synchronized (DefaultConfigLoader.class) {
properties = loadFile(CONFIG_FILE);

if (new File(USER_CONFIG_FILE).exists()) {
userProperties = loadFile(USER_CONFIG_FILE);
} else {
userProperties = null;
}
}
}

/**
* Read properties from file, will ignoring the case of properties.
*
* @param filename Name of file to read, expected that it will be located in the projects root folder
* @return {@link CaselessProperties}
*/
private Properties loadFile(final String filename) {
Properties prop = new CaselessProperties();

try {
String content = new String(Files.readAllBytes(Paths.get(filename)));

// By default property files treat \ as an escape character
prop.load(new StringReader(content.replace("\\", "\\\\")));
} catch (Exception e) {
throw new RuntimeException("Unable to read properties file.", e);
}

return prop;
}

@Override
public Properties getProperties() {
return properties;
}

@Override
public Properties getUserProperties() {
return userProperties;
}
}
package org.concordion.cubano.config;

import java.io.File;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;

/**
* Loads configuration from config.properties and user.properties located in projects root folder.
*
* It also ensures that any single slash character '\' does not require a double slash. This means that
* using \ to wrap long property values across multiple lines won't work.
*/
public class DefaultPropertiesLoader implements PropertiesLoader {
private static final String CONFIG_FILE = "config.properties";
private static final String USER_CONFIG_FILE = "user.properties";

private final Properties properties;
private final Properties userProperties;

private static class DPHolder {
static final DefaultPropertiesLoader INSTANCE = new DefaultPropertiesLoader();
}

public static DefaultPropertiesLoader getInstance() {
return DPHolder.INSTANCE;
}

/** Ensure properties have been loaded before any property is used. */
private DefaultPropertiesLoader() {
synchronized (DefaultPropertiesLoader.class) {
properties = loadFile(CONFIG_FILE);

if (new File(USER_CONFIG_FILE).exists()) {
userProperties = loadFile(USER_CONFIG_FILE);
} else {
userProperties = null;
}
}
}

/**
* Read properties from file, will ignoring the case of properties.
*
* @param filename Name of file to read, expected that it will be located in the projects root folder
* @return {@link CaselessProperties}
*/
private Properties loadFile(final String filename) {
Properties prop = new CaselessProperties();

try {
String content = new String(Files.readAllBytes(Paths.get(filename)));

// By default property files treat \ as an escape character
prop.load(new StringReader(content.replace("\\", "\\\\")));
} catch (Exception e) {
throw new RuntimeException("Unable to read properties file.", e);
}

return prop;
}

@Override
public Properties getProperties() {
return properties;
}

@Override
public Properties getUserProperties() {
return userProperties;
}
}

0 comments on commit cd6eb05

Please sign in to comment.