ConfigData.java [src/usda/weru/util] Revision: default Date:
package usda.weru.util;
import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.logging.Logger;
/**
* Contains configuration data for WepsUI.
*
* @author wjr
* @version 2.0
*/
public class ConfigData /*implements PropertyChangeListener*/ {
static{
//The reference currency is always the United States Dollar.
// Currency.setReferenceCurrency(Currency.USD);
}
private static final Object LOCK = new Object();
public enum AccessLevel {
Write,
Read,
Hidden;
public static final AccessLevel parse(String name) {
for (AccessLevel level : AccessLevel.values()) {
if (level.toString().equalsIgnoreCase(name)) {
return level;
}
}
return null;
}
public static final AccessLevel higher(AccessLevel a, AccessLevel b) {
if (a == null && b == null) {
return null;
} else if (a == null) {
return b;
} else if (b == null) {
return a;
} else if (Write.equals(a) || Write.equals(b)) {
return Write;
} else if (Read.equals(a) || Read.equals(b)) {
return Read;
} else if (Hidden.equals(a) || Hidden.equals(b)) {
return Hidden;
} else {
return null;
}
}
public static final AccessLevel lower(AccessLevel a, AccessLevel b) {
if (a == null && b == null) {
return null;
} else if (a == null) {
return b;
} else if (b == null) {
return a;
}
else if (Hidden.equals(a) || Hidden.equals(b)) {
return Hidden;
}
else if (Read.equals(a) || Read.equals(b)) {
return Read;
}
else if (Write.equals(a) || Write.equals(b)) {
return Write;
}
else {
return null;
}
}
}
private static final Logger LOGGER = Logger.getLogger(ConfigData.class.getName());
private static final String XML_CONFIGURATION = "configuration";
private static final String XML_VERSION = "version";
private static final String XML_PARAMETER = "parameter";
private static final String XML_NAME = "name";
private static final String XML_VALUE = "value";
private static final String XML_ACCESS = "access";
private static final String CD = "CD-";
private static final String RUNTIME_ONLY = "RUNTIME_ONLY";
@FileConfigurationOption(defaultLocation="images")
public static final String ReportFileName = CD + "report file name";
public static final String Units = CD + "measurement";
public static final String OutputFreq = CD + "output report frequency";
// Submodel output flags
public static final String OPHydroDet = CD + "detailed hydro output";
public static final String OPSoilDet = CD + "detailed soil output";
public static final String OPManageDet = CD + "detailed manage output";
public static final String OPCropDet = CD + "detailed crop output";
public static final String OPDecompDet = CD + "detailed decomp output";
public static final String OPErosionDet = CD + "detailed erosion output";
public static final String OPHydroDbg = CD + "debug hydro output";
public static final String OPSoilDbg = CD + "debug soil output";
public static final String OPManageDbg = CD + "debug manage output";
public static final String OPCropDbg = CD + "debug crop output";
public static final String OPDecompDbg = CD + "debug decomp output";
public static final String OPErosionDbg = CD + "debug erosion output";
// Windgen specific
public static final String WindgenAllowedModes = CD + "windgen.allowedmodes";
@FileConfigurationOption(defaultLocation="bin")
public static final String WinExe = CD + "windgen generator";
public static final String WinCmd = CD + "windgen cmdline";
@FileConfigurationOption(defaultLocation="db/windgen")
public static final String WinData = CD + "windgen database";
@FileConfigurationOption(defaultLocation="db/windgen")
public static final String WinIndex = CD + "windgen index";
// @FileConfigurationOption(defaultLocation="db/wind_gen")
// public static final String NRCSWinShape = CD + "nrcs wind shape file";
// public static final String NRCSWinFlg = CD + "nrcs wind shape flg";
@FileConfigurationOption(defaultLocation="bin")
public static final String WindInterp1EXE = CD + "windgen interpolate 1";
@FileConfigurationOption(defaultLocation="bin")
public static final String WindInterp2EXE = CD + "windgen interpolate 2";
@FileConfigurationOption(defaultLocation="db/windgen")
public static final String WindgenInterpolationBoundaryFile = CD + "windgen.interpolate.boundary";
// Cligen specific
public static final String CligenAllowedModes = CD + "cligen.allowedmodes";
@FileConfigurationOption(defaultLocation="bin")
public static final String CliExe = CD + "cligen generator";
public static final String CliCmd = CD + "cligen cmdline";
@FileConfigurationOption(defaultLocation="db/cligen")
public static final String CliData = CD + "cligen database";
@FileConfigurationOption(defaultLocation="db/cligen")
public static final String CliIndex = CD + "cligen index";
// @FileConfigurationOption(defaultLocation="db/cligen")
// public static final String NRCSCliShape = CD + "nrcs cli shape file";
// public static final String NRCSCliFlg = CD + "nrcs cli shape flg";
// Weps specfic
@FileConfigurationOption(defaultLocation="bin")
public static final String WepsExe = CD + "WEPS exe";
public static final String WepsCmd = CD + "WEPS exe parameter";
public static final String CalWepsCmd = CD + "WEPS calibration exe parameter";
//user specific
public static final String UserFullName = CD + "user.fullname";
// Communications specific
public static final String EmailSender = CD + "SenderEmail";
public static final String UseOutlookFlg = CD + "Outlook Flg";
public static final String MailHost = CD + "SMTP_host";
public static final String CommentAddr = CD + "Dest_email";
public static final String BugsAddr = CD + "Dest_bug_email";
public static final String MantisEmail = CD + "MantisEmail";
public static final String MantisURL = CD + "Mantis URL";
public static final String MantisUser = CD + "Mantis user";
public static final String MantisPassword = CD + "Mantis password";
public static final String MantisProject = CD + "Mantis project";
@FileConfigurationOption(defaultLocation="db")
public static final String ManTemp = CD + "management template";
@FileConfigurationOption(defaultLocation="db")
public static final String ManTempSaveAs = CD + "management template save as";
@FileConfigurationOption(defaultLocation="db")
public static final String ManSkel = CD + "management skeleton";
@FileConfigurationOption(defaultLocation="db")
public static final String CropDB = CD + "cropdb";
@FileConfigurationOption(defaultLocation=".")
public static final String MCREW = CD + "MCREW";
@FileConfigurationOption(defaultLocation="db")
public static final String ManDB = CD + "manoperdb";
@FileConfigurationOption(defaultLocation="db")
public static final String SoilDB = CD + "soil database";
//public static final String SoilDBSpec = CD + "soil database spec";
public static final String SoilDBDisp = CD + "soil database display";
public static final String SoilReadonly= CD+"soil.readonly";
@FileConfigurationOption(required=false, defaultLocation="db/soil")
public static final String SoilOrganicFile = CD+"soil.organicfile";
public static final String SoilTestOrganic = CD+"soil.organictest";
@MeasureableConfigurationOption(units="mm", alternativeUnits="in")
public static final String SoilMaxOrganicDepth = CD+"soil.maxorganicdepth";
@FileConfigurationOption
public static final String ProjDir = CD + "projects path";
@FileConfigurationOption(parentOption=MCREW)
public static final String McrewDataConfigFile = CD + "mcrew data config file name";
public static final String TimeSteps = CD + "time steps";
public static final String UseMap = CD + "use map";
public static final String DispLatLon = CD + "display latitude longitude";
public static final String DispElevation = CD + "display elevation";
public static final String DispStCty = CD + "display state county";
public static final String ReadonlySlope = CD + "readonly region slope";
public static final String ReadonlyRockFragments = CD + "readonly rock fragments";
public static final String McrewEdit = CD + "mcrew edit";
public static final String SoilEstimate = CD + "soil estimate";
public static final String SoilAverageStratifiedLayers = "CD-soil.averagestratified";
public static final String SoilSkipOrganicSurfaceLayers = "CD-soil.skiporganic";
public static final String ShowWeatheFilerCheckboxes = CD + "showweatherfilecheckboxes";
public static final String WindFlag = CD + "wind flag";
@MeasureableConfigurationOption(units="km", alternativeUnits="mi")
public static final String WindRadius = CD + "wind radius";
public static final String ClimateFlag = CD + "climate flag";
@MeasureableConfigurationOption(units="km", alternativeUnits="mi")
public static final String ClimateRadius = CD + "climate radius";
public static final String SubDailyFlag = CD + "sub-daily flag";
//public static final String RunTypeDisp = CD + "runtypedisp";
public static final String DefaultRunMode = CD + "defaultrunmode";
public static final String NRCSRunLen = CD + "nrcsrunlength";
public static final String TTInit = CD + "ToolTipInit";
public static final String TTDismiss = CD + "ToolTipDismiss"; // CurrentProj is a CD entry but its stored value is not used
@FileConfigurationOption()
public static final String CurrentProj = CD + "current project";
public static final String SWEEP = CD + "SWEEP-";
@FileConfigurationOption(defaultLocation="bin")
public static final String SWEEPExe = SWEEP + "exe";
public static final String SWEEPCmd = SWEEP + "cmdLine";
public static final String SWEEPWorkDir = SWEEP + "work";
//public static final String FireProperty = "FireProperty " + CD;
public static final String DataChanged = "data changed " + CD;
public static final String Dates = "dates";
public static final String Cycle = "cycle";
public static final String NRCS = "NRCS";
//Formats for the display of data
public static final String FormatOperationDate = CD + "operation date format";
//Runs Location default
@FileConfigurationOption(required=false)
public static final String DefaultRunsLocationTemplate = CD + "default runs location Template";
public static final String DefaultRunsLocation = RUNTIME_ONLY + CD + "default runs location";
//Files to purge after running a simulation.
public static final String PurgeRunFiles = CD + "purge.filefilter";
//Flag to indicate that .cli & .win files should be deleted from run directory
public static final String PurgeRunFilesFlg = CD + "purge.flag";
//Mcrew's skel translation file
@FileConfigurationOption()
public static final String SkelTranslationFile = CD + "skel translations file";
//Don't warn about system locale
public static final String DoNotWarnAboutSystemLocale = CD + "don't warn about system locale";
//Don't estimate missing surgo values
public static final String DoNotEstimateMissingSurgoValues = CD + "do not estimate missing surgo values";
public static final String OMFractionThreshold = CD + "organic material fraction threshold";
//Use the system default mailer
public static final String UseDefaultMailClient = CD + "use default mail client";
public static final String DoNotReviewWarningsWhenRestoringRun = CD + "do not review warnings when restoring run";
@FileConfigurationOption(defaultLocation="tables")
public static final String DetailTableFilterFile = CD + "detail table filter file";
public static final String SingleProjectMode = CD + "single project mode";
public static final String HideProjectFileButtons = CD + "hide project file buttons";
public static final String HideTemplatetFileButtons = CD + "hide template file buttons";
public static final String DaysToKeepLogs = CD + "logs.daystokeep";
public static final String ReportsView = CD + "reports.view";
public static final String ReportsGeneratePDF = CD + "reports.generatepdf";
public static final String ReportsConfidenceIntervalEnabled = CD + "reports.ci.enabled";
@FileConfigurationOption(required=false)
public static final String ReportsDirectory= CD + "reports.directory";
public static final String ReportsCustomized= CD + "reports.customized";
public static final String AllowScriptCreation = CD + "script.allow";
public static final String CompatibilityNRCS = CD + "compatibility.nrcs";
public static final String BarriersReadonly = CD + "barriers.readonly";
@FileConfigurationOption()
public static final String BarriersFile = CD + "barriers.file";
@FileConfigurationOption()
public static final String GISData = CD + "gis.data";
public static final String SiteChooserShowCountry =CD + "sitechooser.showcountry";
//enable experimental xml format
public static final String FormatsXML =CD + "formats.xml";
//fules
@FileConfigurationOption
public static final String FuelDatabase = CD + "fuel.database";
public static final String FuelDefault = CD + "fuel.default";
private static ConfigData c_default;
private List<ConfigStorage> c_storage;
private ConfigStorage c_mainConfig;
private ConfigStorage c_userConfig;
private ConfigStorage c_defaultConfig;
private Map<String, AccessLevel> c_accessLevels;
public static final String PROP_CHANGED = "changed";
private boolean c_changed = true;
// /**
// * ConfigData throws a property change each time setData is called.
// * Wrapper classes listen to determine if the the event is relevant to
// * them.
// */
// private PropertyChangeSupport c_changes = new PropertyChangeSupport(this);
//
private ConfigData() {
// //TODO: does this really make sense to listen to itself?
// c_changes.addPropertyChangeListener(this);
//
//
//default data
synchronized(LOCK){
c_storage = new ArrayList<ConfigStorage>();
//special storage with all the default values
c_defaultConfig = new DefaultConfigStoage();
c_defaultConfig.load();
c_storage.add(c_defaultConfig);
}
}
private void fixUp(){
//if there is no cligen index then use the cligen data and replace the exention with .idx
String cliIndex = getDataParsed(CliIndex);
if(cliIndex == null || cliIndex.trim().length() == 0){
//no cligen index, build from the clidata value
String data = getDataParsed(CliData);
if (data != null && data.trim().length() > 0){
cliIndex = Util.purgeExtensions(data, ".par") + ".idx";
setData(CliIndex, cliIndex);
}
}
//if there is no wingen index then use the windgen data and replace the exention with .idx
String winIndex = getDataParsed(WinIndex);
if(winIndex == null || winIndex.trim().length() == 0){
//no cligen index, build from the clidata value
String data = getDataParsed(WinData);
if (data != null && data.trim().length() > 0){
winIndex = Util.purgeExtensions(data, ".wdb") + ".idx";
setData(WinIndex, winIndex);
}
}
}
private void applyCompatibility(){
//are we in nrcs compatibility mode?
if ("1".equals(getData(CompatibilityNRCS))){
//yes, nrcs install
setData(DefaultRunMode, ConfigData.NRCS);
//user is not allowed to change the modes.
setAccessLevel(DefaultRunMode, AccessLevel.lower(getAccessLevel(DefaultRunMode), AccessLevel.Read));
setAccessLevel(NRCSRunLen, AccessLevel.lower(getAccessLevel(NRCSRunLen), AccessLevel.Read));
//reports
setData(ReportsCustomized, "nrcs");
}
}
public static ConfigData getDefault() {
if (c_default == null) {
c_default = new ConfigData();
}
return c_default;
}
public void load(File main, File user) {
c_storage = new ArrayList<ConfigStorage>();
//main config
if (main != null && main.exists()) {
LOGGER.info("Config File: \"" + main.getAbsolutePath() + "\"");
synchronized(LOCK){
c_mainConfig = new ConfigStorage(main, true);
c_mainConfig.load();
c_storage.add(c_mainConfig);
}
} else {
LOGGER.warning("Config File: NULL");
LOGGER.warning("Using a default main configuration.");
}
//user's config
if (user != null) {
synchronized(LOCK){
LOGGER.info("User Config File: \"" + user.getAbsolutePath() + "\"");
c_userConfig = new ConfigStorage(user, false);
c_userConfig.load();
c_storage.add(0, c_userConfig);
}
} else {
LOGGER.info("User Config File: NULL");
}
//special storage with all the default values
c_storage.add(c_defaultConfig);
applyCompatibility();
fixUp();
}
public File getMainFile(){
return c_mainConfig.c_file;
}
public File getUserFile(){
return c_userConfig.c_file;
}
public AccessLevel getAccessLevel(String propertyName) {
AccessLevel level = null;
if (c_accessLevels != null) {
level = c_accessLevels.get(propertyName);
}
return level != null ? level : AccessLevel.Write;
}
protected void setAccessLevel(String propertyName, AccessLevel level){
if (c_accessLevels == null) {
c_accessLevels = new HashMap<String, AccessLevel>();
}
c_accessLevels.put(propertyName, level);
}
public boolean isChanged() {
return c_changed;
}
/**
* Gets data from hashtable.
*
* @param propertyName Specifies which datum to retrieve using public static final String parameters.
* @return
*/
public String getData(String propertyName) {
synchronized(LOCK){
for (ConfigStorage storage : c_storage) {
String value = storage.get(propertyName);
if (value != null) {
return value;
}
}
return null;
}
}
public String getDataParsed(String propertyName){
return Util.parse(getData(propertyName));
}
/**
* Puts data into hashtable.
*
* @param propertyName Specifies which datum to save using public static final String parameters.
* @param newData Value of datum saved.
*/
public void setData(String propertyName, String newData) {
synchronized(LOCK){
if (c_userConfig == null) {
//no user config can't set values, this could break things!
return;
}
}
if (newData != null) {
newData = newData.trim();
} else {
newData = "";
}
String oldData = getData(propertyName);
if (newData.equals(oldData)) {
//no change, leaving
return;
}
//there is a change, do we have permission
AccessLevel level = getAccessLevel(propertyName);
//we only need permission on CD properties, others are not saved to file
if (!CurrentProj.equals(propertyName) && propertyName.startsWith(CD) && !AccessLevel.Write.equals(level)) {
//we don't have access level to change this value.
return;
}
synchronized(LOCK){
c_userConfig.set(propertyName, newData);
}
// c_changes.firePropertyChange(propertyName, oldData, newData);
if (propertyName.equals(DefaultRunsLocationTemplate)) {
updateDefaultRunsLocation();
}
if (propertyName.equals(CurrentProj)) {
updateDefaultRunsLocation();
}
}
private Collection<String> keys() {
synchronized(LOCK){
List<String> temp = new LinkedList<String>();
for (ConfigStorage storage : c_storage) {
for (String key : storage.keys()) {
if (!temp.contains(key)) {
temp.add(key);
}
}
}
return temp;
}
}
// public void fireAll() {
// boolean firedDefaultRunLocation = false;
// for (String key : keys()) {
// if (DefaultRunsLocation.equals(key)) {
// firedDefaultRunLocation = true;
// }
// String value = getData(key);
// c_changes.firePropertyChange(key, null, value);
// }
//
// if (!firedDefaultRunLocation) {
// updateDefaultRunsLocation();
// }
// }
//
// public void fireAll(PropertyChangeListener... listeners) {
// boolean firedDefaultRunLocation = false;
// for (String key : keys()) {
// if (DefaultRunsLocation.equals(key)) {
// firedDefaultRunLocation = true;
// }
// String value = getData(key);
// PropertyChangeEvent event = new PropertyChangeEvent(this,key, null, value);
// for (PropertyChangeListener listener : listeners) {
// listener.propertyChange(event);
// }
// }
// if (!firedDefaultRunLocation) {
// updateDefaultRunsLocation();
// }
// }
//
// public void save() {
// if (c_userConfig != null) {
// c_userConfig.save();
// boolean old = c_changed;
// c_changed = false;
// c_changes.firePropertyChange(PROP_CHANGED, old, false);
// } else {
// LOGGER.warning("User config is null. Unable to save configuration.");
// }
// }
//
// /**
// *
// * @param l
// */
// public void addPropertyChangeListener(PropertyChangeListener l) {
// c_changes.addPropertyChangeListener(l);
// }
//
// /**
// *
// * @param l
// */
// public void removePropertyChangeListener(PropertyChangeListener l) {
// c_changes.removePropertyChangeListener(l);
// }
//
// /**
// *
// * @param l
// */
// public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
// c_changes.addPropertyChangeListener(propertyName, l);
// }
//
// /**
// *
// * @param l
// */
// public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
// c_changes.removePropertyChangeListener(propertyName, l);
// }
//
// /**
// *
// * @param e
// */
// public void propertyChange(PropertyChangeEvent e) {
// String propertyName = e.getPropertyName();
// if(propertyName == null){
// return;
// }
// if (!propertyName.startsWith(CD)) {
// return;
// }
// String valstr = (String) e.getNewValue();
// setData(propertyName, valstr);
//
// if (propertyName.startsWith(CD)) {
// boolean old = c_changed;
// c_changed = true;
// c_changes.firePropertyChange(PROP_CHANGED, old, true);
// }
//
// }
//
//
//
private void updateDefaultRunsLocation() {
try {
String template = getData(DefaultRunsLocationTemplate);
template = Util.parse(template);
File file = new File(template);
String parsedPath = file.getAbsolutePath();
//Update listeners to the parsed template path
setData(DefaultRunsLocation, parsedPath);
} catch (NullPointerException e) {
}
}
private class ConfigStorage {
protected Map<String, String> c_data;
private File c_file;
private boolean c_readAccessLevels;
protected ConfigStorage() {
}
public ConfigStorage(File file, boolean access) {
this();
c_file = file;
c_readAccessLevels = access;
}
public Collection<String> keys() {
synchronized (this) {
if (c_data == null) {
load();
}
}
return c_data.keySet();
}
public String get(String propertyName) {
synchronized (this) {
if (c_data == null) {
load();
}
}
return c_data.get(propertyName);
}
public void set(String propertyName, String value) {
synchronized (this) {
if (c_data == null) {
load();
}
}
c_data.put(propertyName, value);
}
protected void load() {
// try {
synchronized (this) {
c_data = new HashMap<String, String>();
}
if (!c_file.exists()) {
return;
}
// SAXBuilder builder = new SAXBuilder();
// FileInputStream in = new FileInputStream(c_file);
// Document document = builder.build(in);
//
// Element root = document.getRootElement();
// for (Object o : root.getChildren(XML_PARAMETER)) {
// Element parameter = (Element) o;
// String key = parameter.getChildText(XML_NAME);
// String value = parameter.getChildText(XML_VALUE);
//
// //UPGRADE PATHS
// //ignore the runtypedisp value from the config, this is only in the runfiledata now
// if ("CD-runtypedisp".equals(key)){
// LOGGER.info("Parameter \"" + key + "\" deprecated use " + DefaultRunMode);
// continue;
// }
// //END UPGRADE PATHS
//
// //read and store the access level
// if (c_readAccessLevels) {
// //stor the value
// synchronized (this) {
// c_data.put(key, value != null ? value : "");
// }
//
// String levelText = parameter.getChildText(XML_ACCESS);
// AccessLevel level = AccessLevel.parse(levelText);
// setAccessLevel(key, level);
// if (level != null) {
// setAccessLevel(key, level);
// }
// } else {
// //check access level before storing
// if (CurrentProj.equals(key) || AccessLevel.Write.equals(getAccessLevel(key))) {
// synchronized (this) {
// c_data.put(key, value != null ? value : "");
// }
// } else {
// LOGGER.warning("Parameter \"" + key + "\" ignored from user config due to access restrictions.");
// }
//
// }
// }
// return;
// } catch (UTFDataFormatException udfe) {
// LOGGER.error("Unable to load XML configuration file." + c_file.getPath(), udfe);
// return;
// } catch (JDOMException jde) {
// if (jde.getMessage().indexOf("Content is not allowed in prolog") > 0) {
// return;
// }//Assume this is not an xml file.
//
// LOGGER.error("Unable to load XML configuration file. " + c_file.getPath(), jde);
// return;
// } catch (IOException ioe) {
// LOGGER.error("Unable to load XML configuration file." + c_file.getPath(), ioe);
// return;
// }
}
// protected void save() {
// DocType type = new DocType(XML_CONFIGURATION);
// String dtd = "<!ELEMENT configuration (parameter*)>";
// dtd += "<!ELEMENT parameter (name, value)>";
// dtd += "<!ELEMENT name (#PCDATA)>";
// dtd += "<!ELEMENT value (#PCDATA)>";
// dtd += "<!ATTLIST configuration version CDATA #REQUIRED>";
// type.setInternalSubset(dtd);
// Element root = new Element(XML_CONFIGURATION);
// Document document = new Document(root, type);
//
// root = document.getRootElement().setAttribute(XML_VERSION, "1.0");
//
//
// for (String key : keys()) {
// String value = get(key);
// AccessLevel level = getAccessLevel(key);
//
// //Special case, we write current project even if it's hidden.
// if ( !CurrentProj.equals(key) && !AccessLevel.Write.equals(level)) {
// //skip ones that we aren't allowed to write
// continue;
// }
//
// //only save config values
// if (!key.startsWith(CD)) {
// continue;
// }
//
// //only save if different from main
// synchronized(LOCK){
// String main = c_mainConfig.get(key);
// if (areStringsEqual(main, value)) {
// continue;
// }
// }
//
//
// Element node = new Element(XML_PARAMETER);
// root.addContent(node);
//
// Element nameNode = new Element(XML_NAME);
// nameNode.setText(key);
// node.addContent(nameNode);
//
// Element valueNode = new Element(XML_VALUE);
// valueNode.setText(value);
// node.addContent(valueNode);
//
//
//
//
//
// }
//
// //Write the XML File
// try {
// //setup the folder structure if needed.
// java.io.File parent = c_file.getParentFile();
// if (parent != null && !parent.exists()) {
// if (!parent.mkdirs()) {
// if (!parent.exists()) {
// throw new IOException("can't create directory");
// }
// }
// }
//
// FileWriter writer = new FileWriter(c_file);
// XMLOutputter serializer = new XMLOutputter();
// serializer.setFormat(Format.getPrettyFormat());
// serializer.output(document, writer);
// writer.close();
// } catch (IOException ioe) {
// LOGGER.error("Error writing config file \"" + c_file.getPath() + "\".", ioe);
// }
// }
}
//special storage that has all the default values, sits at the bottom of the stack
private class DefaultConfigStoage extends ConfigStorage {
@Override
protected void load() {
synchronized (this) {
c_data = new HashMap<String, String>();
}
set(Units, Util.SIUnits);
set(OutputFreq, "2");
set(OPHydroDet, "0");
set(OPSoilDet, "0");
set(OPManageDet, "0");
set(OPCropDet, "0");
set(OPDecompDet, "0");
set(OPErosionDet, "0");
set(OPHydroDbg, "0");
set(OPSoilDbg, "0");
set(OPManageDbg, "0");
set(OPCropDbg, "0");
set(OPDecompDbg, "0");
set(OPErosionDbg, "0");
set(WinExe, "");
set(WinCmd, "");
set(WinData, "${weps.databases}/db/windgen/wind_gen_his_upper_US.wdb");
set(WindgenInterpolationBoundaryFile, "${weps.databases}/db/windgen/interpolation_boundary.pol");
set(CliExe, "");
set(CliCmd, "");
set(CliData, "${weps.databases}/db/cligen/US_cligen_stations.par");
set(WepsExe, "");
set(WepsCmd, "");
set(CalWepsCmd, "");
set(EmailSender, "");
set(MailHost, "");
set(CommentAddr, "");
set(BugsAddr, "");
set(ManTemp, "");
set(ManTempSaveAs, "");
set(ManSkel, "");
set(CropDB, "");
set(ManDB, "");
set(SoilDB, "");
set(SoilOrganicFile,"${weps.databases}/db/soil/NRCS Generic Soils/Organic Soil.ifc");
set(SoilMaxOrganicDepth, "101.6");
set(SoilTestOrganic, "1");
set(ProjDir, "");
set(MCREW, "mcrew_cfg");
set(McrewDataConfigFile, "dataconfig.xml");
set(TimeSteps, "24");
set(WindFlag, "0");
set(ClimateFlag, "0");
set(SubDailyFlag, "0");
set(DefaultRunMode, ConfigData.Cycle);
set(TTInit, "2000"); // set to more reasonable defaults if not
set(TTDismiss, "2000"); // set in cfg file (or cfg file is missing)
set(ReadonlySlope, "1");
set(ReadonlyRockFragments, "1");
//Formats
set(FormatOperationDate, "MMM dd, y");
//Purge run files
set(PurgeRunFilesFlg, "0");
set(PurgeRunFiles, "win_gen.win:cli_gen.cli");
//Default runs location template
set(DefaultRunsLocationTemplate, "${PROJECT_DIRECTORY}");
//Mcrew's skel translastion file
set(SkelTranslationFile, "${weps.databases}/db/RUSLE2_Translation.txt");
set(DoNotWarnAboutSystemLocale, "0");
set(DoNotEstimateMissingSurgoValues, "0");
set(UseDefaultMailClient, "0");
set(DoNotReviewWarningsWhenRestoringRun, "0");
set(SoilEstimate, "1");
set(SoilAverageStratifiedLayers, "0");
set(OMFractionThreshold, "0.20");
set(DetailTableFilterFile, "tables/detail_filters.xml");
set(HideProjectFileButtons, "0");
set(HideTemplatetFileButtons, "0");
set(DaysToKeepLogs, "2");
//reports
set(ReportsView, "run");
set(ReportsGeneratePDF, "run,management,crop,stir");
set(ReportsDirectory, "reports/");
set(ReportsCustomized, null);
set(ReportsConfidenceIntervalEnabled, "1");
//bash script
set(AllowScriptCreation, "1");
//nrcs install
set(CompatibilityNRCS, "0");
//default barriers
set(BarriersFile, "${weps.databases}/db/barriers/barrier.dat");
///barriers readonly, false
set(BarriersReadonly, "0");
//show the checkboxes that allow switching between weather files or station lists on a per project basis
set(ShowWeatheFilerCheckboxes, "1");
//LocationPanel rewrite
set(WindgenAllowedModes, "choice,file,interpolated,gis,nearest,nrcs");
set(CligenAllowedModes, "choice,nearest,gis,file,nrcs");
setData(SoilAverageStratifiedLayers, "0");
setData(SoilSkipOrganicSurfaceLayers, "0");
setData(SiteChooserShowCountry, "0");
set(GISData, "db/gis");
set(SoilReadonly, "0");
//default to not allowing xml format
set(FormatsXML, "0");
//fuels
set(FuelDatabase, "${weps.databases}/db/fuels/fuels.xml");
set(FuelDefault, "diesel");
}
// @Override
protected void save() {
//do nothing
}
}
private static boolean areStringsEqual(String a, String b) {
if (a == null && b == null) {
return true;
} else if (a != null && b != null) {
return a.equals(b);
} else {
return false;
}
}
public boolean getSoilTestOrganic(){
return "1".equals(getData(SoilTestOrganic));
}
// public Measurable<Length> getSoilMaxOrganicDepth(){
// String valueString = getData(SoilMaxOrganicDepth);
// try{
// double depthMiliMeters = Double.valueOf(valueString);
// return Measure.valueOf(depthMiliMeters, SI.MILLIMETER);
// }
// catch(Exception e){
// LOGGER.warning("Unable to parse the soil max organic depth. Defaulting to 4 inches." + valueString);
// return Measure.valueOf(4, NonSI.INCH);
// }
// }
//
public boolean isAverageStratifiedSoilLayers(){
String value = getData(SoilAverageStratifiedLayers);
return value != null ? value.trim().equals("1") : false;
}
public boolean isSkipOrganicSoilSurfaceLayers(){
String value = getData(SoilSkipOrganicSurfaceLayers);
return value != null ? value.trim().equals("1") : false;
}
// //TODO: fire changes when the underlying data changes
// public static final String PROP_ALLOWED_CLIGEN_STATION_MODES = "allowedCligenStationModes";
// public StationMode[] getAllowedCligenStationModes(){
// return parseAllowedStationModes(getData(CligenAllowedModes));
// }
//
// public static final String PROP_ALLOWED_WINDGEN_STATION_MODES = "allowedWindgenStationModes";
// public StationMode[] getAllowedWindgenStationModes(){
// return parseAllowedStationModes(getData(WindgenAllowedModes));
// }
//
// public static final String PROP_CLIGEN_SEARCH_RADIUS= "cligenSearchRadius";
// public Measurable<Length> getCligenSearchRadius(){
// String valueString = getData(ClimateRadius);
// try {
// double distanceMeters = Double.parseDouble(valueString.trim());
// return Measure.valueOf(distanceMeters, SI.KILOMETER);
// } catch (Exception e) {
// LOGGER.warning("Unable to parse the cligen radius limit. " + valueString);
// return null;
// }
// }
//
public static final String PROP_CLIGEN_SEARCH_LIMIT= "cligenSearchLimit";
public int getCligenSearchLimit(){
return 50;
}
public static final String PROP_WINDGEN_SEARCH_RADIUS= "windgenSearchRadius";
// public Measurable<Length> getWindgenSearchRadius(){
// String valueString = getData(WindRadius);
// try {
// double distanceMeters = Double.parseDouble(valueString.trim());
// return Measure.valueOf(distanceMeters, SI.KILOMETER);
// } catch (Exception e) {
// LOGGER.warning("Unable to parse the windgen radius limit. " + valueString);
// return null;
// }
// }
//
public static final String PROP_WINDGEN_SEARCH_LIMIT= "windgenSearchLimit";
public int getWindgenSearchLimit(){
return 50;
}
// private static final StationMode[] parseAllowedStationModes(String modes){
// if(modes == null || modes.trim().length()==0){
// return new StationMode[0];
// }
// EnumSet <StationMode> c_allowedModes = null;
// String[] parts = modes.split(",");
// for(String part : parts){
// StationMode mode = StationMode.parse(part.trim());
// if(mode != null){
// if(c_allowedModes == null){
// c_allowedModes = EnumSet.of(mode);
// }
// else{
// c_allowedModes.add(mode);
// }
// }
// }
//
// return c_allowedModes.toArray(new StationMode[c_allowedModes.size()]);
// }
//
public void logConfiguration(){
try{
StringBuffer buffer = new StringBuffer();
List<String> sortedKeys = new LinkedList<String> (keys());
Collections.sort(sortedKeys);
for(String key : sortedKeys){
//USER
String value = c_userConfig.get(key);
String type = "user";
//MAIN
if(value == null){
value = c_mainConfig.get(key);
type = "main";
}
//DEFAULT
if(value == null){
value = c_defaultConfig.get(key);
type = "default";
}
if(value == null){
value = "null";
type = null;
}
buffer.append("\t" + key + (type != null ? "(" + type + ")" : "")+ "= " + value + "\n");
String valueParsed = Util.parse(value);
if(!value.equals(valueParsed)){
buffer.append("\t" + key + "(parsed) = " + valueParsed + "\n");
}
}
LOGGER.fine("Current Configuration:\n" + buffer.toString());
}
catch(Exception e){
LOGGER.warning("Unable to log configuration.\n" + e.getMessage());
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface MeasureableConfigurationOption{
String units();
String alternativeUnits();
boolean isDouble() default true;
}
private Map<String, MeasureableConfigurationOption> c_measureableConfigurationOptions;
private synchronized Map<String, MeasureableConfigurationOption> measureableOptions(){
if(c_measureableConfigurationOptions == null){
c_measureableConfigurationOptions = new HashMap<String, MeasureableConfigurationOption>();
//loop over all the fields in the configdata and record all those with the FileConfigurationOption annotation
for (Field field : ConfigData.class.getFields()) {
try {
//if final static and annotated
if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && field.isAnnotationPresent(MeasureableConfigurationOption.class)) {
MeasureableConfigurationOption annotation = field.getAnnotation(MeasureableConfigurationOption.class);
String propertyName = field.get(null).toString();
c_measureableConfigurationOptions.put(propertyName, annotation);
}
} catch (Exception e) {
LOGGER.severe("Initilizing" + e.getMessage());
}
}
}
return c_measureableConfigurationOptions;
}
public MeasureableConfigurationOption getMeasureableConfigurationOption(String propertyName){
return measureableOptions().get(propertyName);
}
// public Unit getMeasureableUnit(String propertyName){
// MeasureableConfigurationOption option = getMeasureableConfigurationOption(propertyName);
//
// if(option != null){
// Unit units = Unit.valueOf(option.units());
// return units;
// }
// return null;
// }
//
// public Unit getMeasureableAlternativeUnit(String propertyName){
// MeasureableConfigurationOption option = getMeasureableConfigurationOption(propertyName);
//
// if(option != null){
// Unit units = Unit.valueOf(option.alternativeUnits());
// return units;
// }
// return null;
// }
//
//
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface FileConfigurationOption{
boolean required() default true;
String parentOption() default "";
String defaultLocation() default "";
}
private Map<String, FileConfigurationOption> c_fileConfigurationOptions;
private synchronized Map<String, FileConfigurationOption> fileOptions(){
if(c_fileConfigurationOptions == null){
c_fileConfigurationOptions = new HashMap<String, FileConfigurationOption>();
//loop over all the fields in the configdata and record all those with the FileConfigurationOption annotation
for (Field field : ConfigData.class.getFields()) {
try {
//if final static and annotated
if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && field.isAnnotationPresent(FileConfigurationOption.class)) {
FileConfigurationOption annotation = field.getAnnotation(FileConfigurationOption.class);
String propertyName = field.get(null).toString();
c_fileConfigurationOptions.put(propertyName, annotation);
}
} catch (Exception e) {
LOGGER.severe("Initilizing" + e.getMessage());
}
}
}
return c_fileConfigurationOptions;
}
public boolean isFileConfigurationOption(String propertyName){
return fileOptions().containsKey(propertyName);
}
public FileConfigurationOption getFileConfigurationOption(String propertyName){
return fileOptions().get(propertyName);
}
public String[] getFileConfigurationOptions(){
Collection<String> temp = fileOptions().keySet();
return temp.toArray(new String[temp.size()]);
}
public boolean isFileReferenceErrorInConfigData(){
boolean failed = false;
for(Map.Entry<String, FileConfigurationOption> entry : fileOptions().entrySet()){
//exit on the first error to be as fast as possible
String propertyName = entry.getKey();
FileConfigurationOption meta = entry.getValue();
if(getAccessLevel(propertyName) != AccessLevel.Hidden){
if(meta.required()){
//test if the value exists as a file
File parentFile = null;
String parentPropertyName = meta.parentOption();
if(parentPropertyName != null && parentPropertyName.trim().length() > 0){
String parentPath = getDataParsed(parentPropertyName);
if(parentPath != null){
parentFile = new File(Util.parse(parentPath));
}
}
String path = getDataParsed(propertyName);
boolean error = false;
if(path != null){
File file = new File(path);
if(!file.isAbsolute() && parentFile != null){
file = new File(parentFile, Util.parse(path));
}
error = !file.exists();
}
if(error){
failed = true;
LOGGER.warning("Unable to resolve file reference for : " + propertyName + "=" + getData(propertyName));
}
}
}
}
return failed;
}
public boolean isSiteChooserShowCountries(){
return "1".equals(getData(SiteChooserShowCountry));
}
public boolean isPurgeFlag(){
return "1".equals(getData(PurgeRunFilesFlg));
}
public boolean isSoilReadonly(){
return "1".equals(getData(SoilReadonly));
}
public boolean isFormatXMLAllowed(){
return "1".equals(getData(FormatsXML));
}
public boolean isReportConfidenceIntervalEnabled(){
return "1".equals(getData(ReportsConfidenceIntervalEnabled));
}
public String[] getPurgeFilenames(){
String filter = getData(PurgeRunFiles);
filter = filter != null ? filter.trim() : null;
if(filter == null || filter.length() == 0){
return new String[0];
}
String[] parts = filter.split(":");
for (int i = 0; i < parts.length; i++){
parts[i] = parts[i].trim();
}
return parts;
}
// /**
// * Always returns USD. Placeholder for future potential support of other
// * currencies.
// * @return USD
// */
// public Currency getCurrency(){
// return Currency.USD;
// }
//
public boolean isCompatibilityNRCS(){
return "1".equals(getData(CompatibilityNRCS));
}
}