package edu.uncc.cs.watsonsim;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Configuration {
protected final String data_path = "data/";
public final Map<String, String> config;
@SuppressWarnings({ "unchecked", "rawtypes" }) // From Properties -> Map
public Configuration() {
/*
* Normally, wrapping a IOException with a RuntimeException is bad
* but if you cannot find a configuration file many bad things will
* happen, and basically every useful feature will fail. So you might
* as well just quit here.
*/
try {
// Check the data path
File f = new File(data_path);
if (!(f.exists() && f.isDirectory())) {
throw new IOException(data_path + " should be a directory.");
}
// Read the configuration
Properties props = null;
for (String prefix : new String[]{this.data_path, ""}) {
try (Reader s = new InputStreamReader(
new FileInputStream(prefix + "config.properties"), "UTF-8")){
// Make it, then link it if it works.
Properties _local_props = new Properties();
_local_props.load(s);
props = _local_props;
} catch (FileNotFoundException e) {
// This is only an error if none are found.
}
}
// If it didn't link, all the reads failed.
if (props == null) {
throw new IOException("Failed to read config.properties in either "
+ this.data_path
+ " or "
+ System.getProperty("user.dir") // CWD
+ " You can create one by making a copy of"
+ " config.properties.sample. Check the README as well.");
}
// Now make properties immutable.
Map<Object, Object> m = new HashMap<>();
m.putAll(props);
this.config = Collections.unmodifiableMap((Map) m);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Convenience method for getting a setting.
* @param config Map from the configuration file (config.properties)
* @param key The key that must exist in the properties
* @return The non-null String value, or else throw a RuntimeException.
*/
public String getConfOrDie(String key) {
String value = config.get(key);
if (value == null) throw new RuntimeException("Required key (" + key + ") missing from configuration file.");
return value;
}
/**
* Get the path to a resource, ensuring it exists.
* This is mostly to give helpful errors and fail fast if you missed a
* step setting up.
* @param resource The relative path of the resource without leading /
*/
public String pathMustExist(String resource) {
String path = data_path + File.separator + resource;
if (!new File(path).exists()) {
throw new RuntimeException("The data directory is missing the"
+ " expected resource: " + path);
}
return path;
}
}