package ec.util; import java.util.Properties; import java.util.Vector; import java.util.Enumeration; import java.util.Hashtable; import java.io.*; /* * ParameterDatabase.java * Created: Sat Aug 7 12:09:19 1999 */ /** * *

This extension of the Properties class allows you to set, get, and * delete Parameters in a hierarchical tree-like database. The database consists * of a list of Parameters, plus an array of "parent databases" * which it falls back on when it can't find the Parameter you're looking * for. Parents may also have arrays of parents, and so on.. * *

The parameters are loaded from a Java property-list file, which is * basically a collection of parameter=value pairs, one per line. Empty lines * and lines beginning with # are ignored. These parameters and their values * are case-sensitive, and whitespace is trimmed I believe. * *

An optional set of parameters, "parent.n", where n are * consecutive integers starting at 0, define the filenames of the database's * parents. * *

An optional set of parameters, "print-params", specifies whether or not * parameters should be printed as they are used (through one of the get(...) methods). * If print-params is unset, or set to false or FALSE, nothing is printed. * If set to non-faslse, then the parameters are printed. * *

*

When you create a ParameterDatabase using new ParameterDatabase(), * it is created thus: *

DATABASE: database
FROM: (empty)
* *

When you create a ParameterDatabase using new ParameterDatabase(file), * it is created by loading the database file, and its parent file tree, thus:

DATABASE: database -> parent0 +-> parent0 +-> parent0 +-> ....
FROM: (empty)  (file) | (parent.0) | (parent.0)  ....
     |  +-> parent1 +-> ....
     |  | (parent.1)  
     |  ....   
     |     
     +-> parent1 +-> ....  
     | (parent.1)    
     ....     
* *

When you create a ParameterDatabase using new ParameterDatabase(file,argv), * the preferred way, it is created thus: *

DATABASE: database -> parent0 +-> parent0 +-> parent0 +-> parent0 +-> ....
FROM: (empty) (argv)  (file) | (parent.0) | (parent.0)  ....
       |  +-> parent1 +-> ....
       |  | (parent.1)  
       |  ....   
       |     
       +-> parent1 +-> ....  
       | (parent.1)    
       ....     
*

...that is, the actual top database is empty, and stores parameters * added programmatically; its parent is a database formed from arguments * passed in on the command line; its parent is the parameter database * which actually loads from foo. This allows you to * programmatically add parameters which override those in foo, then delete * them, thus bringing foo's parameters back in view. * *

Once a parameter database is loaded, you query it with the * get methods. The database, then its parents, are searched * until a match is found for your parameter. The search rules are thus: * (1) the root database is searched first. (2) If a database being searched * doesn't contain the data, it searches its parents recursively, starting with * parent 0, then moving up, until all searches are exhausted or something was * found. (3) No database is searched twice. * *

You can set a parameter * (in the topmost database only with the set command. * The remove command removes a parameter from the topmost database * only. The removeDeeply command removes that parameter from * every database. * *

The values stored in a parameter database must not contain "#", "=", * non-ascii values, or whitespace. * *

Note for JDK 1.1. Finally recovering from stupendous idiocy, * JDK 1.2 included parseDouble() and parseFloat() commands; now you can * READ A FLOAT FROM A STRING without having to create a Float object first! * Anyway, you will need to modify the getFloat() method below if you're * running on JDK 1.1, but understand that large numbers of calls to the * method may be inefficient. Sample JDK 1.1 code is given with those methods, * but is commented out. * * * @author Sean Luke * @version 1.0 */ public final class ParameterDatabase extends Properties implements Serializable { public static final String C_HERE = "$"; public static final String UNKNOWN_VALUE = ""; public static final String PRINT_PARAMS = "print-params"; public static final int PS_UNKNOWN = -1; public static final int PS_NONE = 0; public static final int PS_PRINT_GOTTEN = 1; public int printState = PS_UNKNOWN; private Vector parents; private File directory; private boolean checked; private Hashtable gotten; private Hashtable accessed; /** Searches down through databases to find a given parameter, whose value must be a full Class name, and the class must be a descendent of but not equal to mustCastTosuperclass. Loads the class and returns an instance (constructed with the default constructor), or throws a ParamClassLoadException if there is no such Class. If the parameter is not found, the defaultParameter is used. The parameter chosen is marked "used". */ public final Object getInstanceForParameter(Parameter parameter, Parameter defaultParameter, Class mustCastTosuperclass) throws ParamClassLoadException { Parameter p; if (exists(parameter)) p = parameter; else if (exists(defaultParameter)) p = defaultParameter; else throw new ParamClassLoadException("No class name provided.\nPARAMETER: " + parameter + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter)); try { Class c = Class.forName(get(p)); if (!mustCastTosuperclass.isAssignableFrom(c)) throw new ParamClassLoadException( "The class " + c.getName() + "\ndoes not cast into the superclass " + mustCastTosuperclass.getName() + "\nPARAMETER: " + parameter + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter)); if (mustCastTosuperclass==c) throw new ParamClassLoadException( "The class " + c.getName() + "\nmust not be the same as the required superclass " + mustCastTosuperclass.getName() + "\nPARAMETER: " + parameter + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter)); return c.newInstance(); } catch(ClassNotFoundException e) { throw new ParamClassLoadException( "Class not found: " + get(p) + "\nPARAMETER: " + parameter + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } catch(IllegalArgumentException e) { throw new ParamClassLoadException( "Could not load class: " + get(p) + "\nPARAMETER: " + parameter + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } catch(InstantiationException e) { throw new ParamClassLoadException( "The requested class is an interface or an abstract class: " + get(p) + "\nPARAMETER: " + parameter + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } catch(IllegalAccessException e) { throw new ParamClassLoadException( "The requested class cannot be initialized with the default initializer: " + get(p) + "\nPARAMETER: " + parameter + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } } /** Searches down through databases to find a given parameter, whose value must be a full Class name, and the class must be a descendent, or equal to, mustCastTosuperclass. Loads the class and returns an instance (constructed with the default constructor), or throws a ParamClassLoadException if there is no such Class. The parameter chosen is marked "used". */ public final Object getInstanceForParameterEq(Parameter parameter, Parameter defaultParameter, Class mustCastTosuperclass) throws ParamClassLoadException { Parameter p; if (exists(parameter)) p = parameter; else if (exists(defaultParameter)) p = defaultParameter; else throw new ParamClassLoadException("No class name provided.\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter)); try { Class c = Class.forName(get(p)); if (!mustCastTosuperclass.isAssignableFrom(c)) throw new ParamClassLoadException( "The class " + c.getName() + "\ndoes not cast into the superclass " + mustCastTosuperclass.getName() + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter)); return c.newInstance(); } catch(ClassNotFoundException e) { throw new ParamClassLoadException( "Class not found: " + get(p) + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } catch(IllegalArgumentException e) { throw new ParamClassLoadException( "Could not load class: " + get(p) + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } catch(InstantiationException e) { throw new ParamClassLoadException( "The requested class is an interface or an abstract class: " + get(p) + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } catch(IllegalAccessException e) { throw new ParamClassLoadException( "The requested class cannot be initialized with the default initializer: " + get(p) + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } } /** Searches down through databases to find a given parameter. The value associated with this parameter must be a full Class name, and the class must be a descendent of but not equal to mustCastTosuperclass. Loads and returns the associated Class, or throws a ParamClassLoadException if there is no such Class. If the parameter is not found, the defaultParameter is used. The parameter chosen is marked "used". */ public final Object getClassForParameter(Parameter parameter, Parameter defaultParameter, Class mustCastTosuperclass) throws ParamClassLoadException { Parameter p; if (exists(parameter)) p = parameter; else if (exists(defaultParameter)) p = defaultParameter; else throw new ParamClassLoadException("No class name provided.\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter)); try { Class c = Class.forName(get(p)); if (!mustCastTosuperclass.isAssignableFrom(c)) throw new ParamClassLoadException( "The class " + c.getName() + "\ndoes not cast into the superclass " + mustCastTosuperclass.getName() + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter)); return c; } catch(ClassNotFoundException e) { throw new ParamClassLoadException( "Class not found: " + get(p) + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } catch(IllegalArgumentException e) { throw new ParamClassLoadException( "Could not load class: " + get(p) + "\nPARAMETER: " + parameter + "\n ALSO: " + (defaultParameter==null ? "" : "\n ALSO: " + defaultParameter) + "\nEXCEPTION: \n\n" + e); } } /** Searches down through databases to find a given parameter; If the parameter does not exist, defaultValue is returned. If the parameter exists, and it is set to "false" (case insensitive), false is returned. Else true is returned. The parameter chosen is marked "used" if it exists. */ public final boolean getBoolean(Parameter parameter, Parameter defaultParameter, boolean defaultValue) { if (exists(parameter)) return getBoolean(parameter, defaultValue); else return getBoolean(defaultParameter, defaultValue); } /** Searches down through databases to find a given parameter; If the parameter does not exist, defaultValue is returned. If the parameter exists, and it is set to "false" (case insensitive), false is returned. Else true is returned. The parameter chosen is marked "used" if it exists. */ final boolean getBoolean(Parameter parameter, boolean defaultValue) { if (!exists(parameter)) return defaultValue; return (!get(parameter).equalsIgnoreCase("false")); } /** Parses an integer from a string, either in decimal or (if starting with an x) in hex */ // we assume that the string has been trimmed already protected final int parseInt(String string) throws NumberFormatException { char c; if (string!=null && string.length() > 0 && ((string.charAt(0)==(c='x')) || c == 'X')) { // it's a hex int, load it as hex return Integer.parseInt(string.substring(1),16); } else // it's decimal return Integer.parseInt(string); } /** Parses a long from a string, either in decimal or (if starting with an x) in hex */ // we assume that the string has been trimmed already protected final long parseLong(String string) throws NumberFormatException { char c; if (string!=null && string.length() > 0 && ((string.charAt(0)==(c='x')) || c == 'X')) { // it's a hex int, load it as hex return Long.parseLong(string.substring(1),16); } else // it's decimal return Long.parseLong(string); } /** Searches down through databases to find a given parameter, whose value must be an integer. It returns the value, else throws a NumberFormatException exception if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal. */ public final int getInt(Parameter parameter) throws NumberFormatException { if (exists(parameter)) { try { return parseInt(get(parameter)); } catch(NumberFormatException e) { throw new NumberFormatException("Bad integer (" +get(parameter) + " ) for parameter " + parameter); } } else throw new NumberFormatException("Integer does not exist for parameter " + parameter); } /** Searches down through databases to find a given parameter, whose value must be an integer. It returns the value, else throws a NumberFormatException exception if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal. */ public final int getInt(Parameter parameter, Parameter defaultParameter) throws NumberFormatException { if (exists(parameter)) return getInt(parameter); else if (exists(defaultParameter)) return getInt(defaultParameter); else throw new NumberFormatException("Integer does not exist for either parameter " + parameter + "\nor\n" + defaultParameter); } /** Searches down through databases to find a given parameter, whose value must be an integer >= minValue. It returns the value, or minValue-1 if the value is out of range or if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal.*/ public final int getInt(Parameter parameter, Parameter defaultParameter, int minValue) { if (exists(parameter)) return getInt(parameter, minValue); else return getInt(defaultParameter, minValue); } /** Searches down through databases to find a given parameter, whose value must be an integer >= minValue. It returns the value, or minValue-1 if the value is out of range or if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal.*/ final int getInt(Parameter parameter, int minValue) { if (exists(parameter)) { try { int i = parseInt(get(parameter)); if (i < minValue) return minValue-1; return i; } catch(NumberFormatException e) { return minValue-1; } } else return minValue-1; } /** Searches down through databases to find a given parameter, which must be an integer. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal.*/ public final int getIntWithDefault(Parameter parameter, Parameter defaultParameter, int defaultValue) { if (exists(parameter)) return getIntWithDefault(parameter, defaultValue); else return getIntWithDefault(defaultParameter, defaultValue); } /** Searches down through databases to find a given parameter, which must be an integer. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal.*/ final int getIntWithDefault(Parameter parameter, int defaultValue) { if (exists(parameter)) { try { return parseInt(get(parameter)); } catch(NumberFormatException e) { return defaultValue; } } else return defaultValue; } /** Searches down through databases to find a given parameter, whose value must be an integer >= minValue and <= maxValue. It returns the value, or minValue-1 if the value is out of range or if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal.*/ public final int getIntWithMax(Parameter parameter, Parameter defaultParameter, int minValue, int maxValue) { if (exists(parameter)) return getIntWithMax(parameter, minValue, maxValue); else return getIntWithMax(defaultParameter, minValue, maxValue); } /** Searches down through databases to find a given parameter, whose value must be an integer >= minValue and <= maxValue. It returns the value, or minValue-1 if the value is out of range or if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Integers may be in decimal or (if preceded with an X or x) in hexadecimal.*/ final int getIntWithMax(Parameter parameter, int minValue, int maxValue) { if (exists(parameter)) { try { int i = parseInt(get(parameter)); if (i < minValue) return minValue-1; if (i > maxValue) return minValue-1; return i; } catch(NumberFormatException e) { return minValue-1; } } else return minValue-1; } /** Searches down through databases to find a given parameter, whose value must be a float >= minValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ public final float getFloat(Parameter parameter, Parameter defaultParameter, double minValue) { if (exists(parameter)) return getFloat(parameter,minValue); else return getFloat(defaultParameter, minValue); } /** Searches down through databases to find a given parameter, whose value must be a float >= minValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ final float getFloat(Parameter parameter, double minValue) { if (exists(parameter)) { try { float i = Float.valueOf(get(parameter)).floatValue(); // what stupidity... // For JDK 1.2 and later, this is more efficient... // float i = Float.parseFloat(get(parameter)); // ...but we can't use it and still be compatible with JDK 1.1 if (i < minValue) return (float)(minValue-1); return i; } catch(NumberFormatException e) { return (float)(minValue-1); } } else return (float)(minValue-1); } /** Searches down through databases to find a given parameter, which must be a float. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. */ public final float getFloatWithDefault(Parameter parameter, Parameter defaultParameter, double defaultValue) { if (exists(parameter)) return getFloatWithDefault(parameter,defaultValue); else return getFloatWithDefault(defaultParameter, defaultValue); } /** Searches down through databases to find a given parameter, which must be a float. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. */ final float getFloatWithDefault(Parameter parameter, double defaultValue) { if (exists(parameter)) { try { // For JDK 1.2 and later, this is more efficient... // return Float.parseFloat(get(parameter)); // ...but we can't use it and still be compatible with JDK 1.1 return Float.valueOf(get(parameter)).floatValue(); // what stupidity... } catch(NumberFormatException e) { return (float)(defaultValue); } } else return (float)(defaultValue); } /** Searches down through databases to find a given parameter, whose value must be a float >= minValue and <= maxValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ public final float getFloat(Parameter parameter, Parameter defaultParameter, double minValue, double maxValue) { if (exists(parameter)) return getFloat(parameter,minValue,maxValue); else return getFloat(defaultParameter,minValue,maxValue); } /** Searches down through databases to find a given parameter, whose value must be a float >= minValue and <= maxValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ final float getFloat(Parameter parameter, double minValue, double maxValue) { if (exists(parameter)) { try { float i = Float.valueOf(get(parameter)).floatValue(); // what stupidity... // For JDK 1.2 and later, this is more efficient... // float i = Float.parseFloat(get(parameter)); // ...but we can't use it and still be compatible with JDK 1.1 if (i < minValue) return (float)(minValue-1); if (i > maxValue) return (float)(minValue-1); return i; } catch(NumberFormatException e) { return (float)(minValue-1); } } else return (float)(minValue-1); } /** Searches down through databases to find a given parameter, whose value must be a double >= minValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ public final double getDouble(Parameter parameter, Parameter defaultParameter, double minValue) { if (exists(parameter)) return getDouble(parameter,minValue); else return getDouble(defaultParameter, minValue); } /** Searches down through databases to find a given parameter, whose value must be a double >= minValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ final double getDouble(Parameter parameter, double minValue) { if (exists(parameter)) { try { double i = Double.valueOf(get(parameter)).doubleValue(); // what stupidity... // For JDK 1.2 and later, this is more efficient... // double i = Double.parseDouble(get(parameter)); // ...but we can't use it and still be compatible with JDK 1.1 if (i < minValue) return (double)(minValue-1); return i; } catch(NumberFormatException e) { return (double)(minValue-1); } } else return (double)(minValue-1); } /** Searches down through databases to find a given parameter, whose value must be a double >= minValue and <= maxValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ public final double getDouble(Parameter parameter, Parameter defaultParameter, double minValue, double maxValue) { if (exists(parameter)) return getDouble(parameter,minValue,maxValue); else return getDouble(defaultParameter,minValue,maxValue); } /** Searches down through databases to find a given parameter, whose value must be a double >= minValue and <= maxValue. If not, this method returns minvalue-1, else it returns the parameter value. The parameter chosen is marked "used" if it exists. */ final double getDouble(Parameter parameter, double minValue, double maxValue) { if (exists(parameter)) { try { double i = Double.valueOf(get(parameter)).doubleValue(); // what stupidity... // For JDK 1.2 and later, this is more efficient... // double i = Double.parseDouble(get(parameter)); // ...but we can't use it and still be compatible with JDK 1.1 if (i < minValue) return (double)(minValue-1); if (i > maxValue) return (double)(minValue-1); return i; } catch(NumberFormatException e) { return (double)(minValue-1); } } else return (double)(minValue-1); } /** Searches down through databases to find a given parameter, which must be a float. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. */ public final double getDoubleWithDefault(Parameter parameter, Parameter defaultParameter, double defaultValue) { if (exists(parameter)) return getDoubleWithDefault(parameter,defaultValue); else return getDoubleWithDefault(defaultParameter, defaultValue); } /** Searches down through databases to find a given parameter, which must be a float. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. */ final double getDoubleWithDefault(Parameter parameter, double defaultValue) { if (exists(parameter)) { try { // For JDK 1.2 and later, this is more efficient... // return Double.parseDouble(get(parameter)); // ...but we can't use it and still be compatible with JDK 1.1 return Double.valueOf(get(parameter)).doubleValue(); // what stupidity... } catch(NumberFormatException e) { return defaultValue; } } else return defaultValue; } /** Searches down through databases to find a given parameter, whose value must be a long. It returns the value, else throws a NumberFormatException exception if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal. */ public final long getLong(Parameter parameter) throws NumberFormatException { if (exists(parameter)) { try { return parseLong(get(parameter)); } catch(NumberFormatException e) { throw new NumberFormatException("Bad long (" +get(parameter) + " ) for parameter " + parameter); } } else throw new NumberFormatException("Long does not exist for parameter " + parameter); } /** Searches down through databases to find a given parameter, whose value must be a long. It returns the value, else throws a NumberFormatException exception if there is an error in parsing the parameter. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal. */ public final long getLong(Parameter parameter, Parameter defaultParameter) throws NumberFormatException { if (exists(parameter)) return getLong(parameter); else if (exists(defaultParameter)) return getLong(defaultParameter); else throw new NumberFormatException("Long does not exist for either parameter " + parameter + "\nor\n" + defaultParameter); } /** Searches down through databases to find a given parameter, whose value must be a long >= minValue. If not, this method returns errValue, else it returns the parameter value. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal.*/ public final long getLong(Parameter parameter, Parameter defaultParameter, long minValue) { if (exists(parameter)) return getLong(parameter, minValue); else return getLong(defaultParameter, minValue); } /** Searches down through databases to find a given parameter, whose value must be a long >= minValue. If not, this method returns errValue, else it returns the parameter value. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal.*/ final long getLong(Parameter parameter, long minValue) { if (exists(parameter)) { try { long i = parseLong(get(parameter)); if (i < minValue) return minValue-1; return i; } catch(NumberFormatException e) { return minValue-1; } } else return (minValue-1); } /** Searches down through databases to find a given parameter, which must be a long. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal.*/ public final long getLongWithDefault(Parameter parameter, Parameter defaultParameter, long defaultValue) { if (exists(parameter)) return getLongWithDefault(parameter, defaultValue); else return getLongWithDefault(defaultParameter, defaultValue); } /** Searches down through databases to find a given parameter, which must be a long. If there is an error in parsing the parameter, then default is returned. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal.*/ final long getLongWithDefault(Parameter parameter, long defaultValue) { if (exists(parameter)) { try { return parseLong(get(parameter)); } catch(NumberFormatException e) { return defaultValue; } } else return defaultValue; } /** Searches down through databases to find a given parameter, whose value must be a long >= minValue and =< maxValue. If not, this method returns errValue, else it returns the parameter value. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal. */ public final long getLongWithMax(Parameter parameter, Parameter defaultParameter, long minValue, long maxValue) { if (exists(parameter)) return getLong(parameter,minValue,maxValue); else return getLong(defaultParameter,minValue,maxValue); } /** Use getLongWithMax(...) instead. Searches down through databases to find a given parameter, whose value must be a long >= minValue and =< maxValue. If not, this method returns errValue, else it returns the parameter value. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal.*/ final long getLongWithMax(Parameter parameter, long minValue, long maxValue) { if (exists(parameter)) { try { long i = parseLong(get(parameter)); if (i < minValue) return minValue-1; if (i > maxValue) return minValue-1; return i; } catch(NumberFormatException e) { return minValue-1; } } else return (minValue-1); } /** Use getLongWithMax(...) instead. Searches down through databases to find a given parameter, whose value must be a long >= minValue and =< maxValue. If not, this method returns errValue, else it returns the parameter value. The parameter chosen is marked "used" if it exists. Longs may be in decimal or (if preceded with an X or x) in hexadecimal. @deprecated */ public final long getLong(Parameter parameter, Parameter defaultParameter, long minValue, long maxValue) { return getLongWithMax(parameter, defaultParameter, minValue, maxValue); } /** Use getLongWithMax(...) instead. Searches down through databases to find a given parameter, whose value must be a long >= minValue and =< maxValue. If not, this method returns errValue, else it returns the parameter value. The parameter chosen is marked "used" if it exists. @deprecated */ final long getLong(Parameter parameter, long minValue, long maxValue) { return getLongWithMax(parameter,minValue,maxValue); } /** Searches down through the databases to find a given parameter, whose value must be an absolute or relative path name. If it is absolute, a File is made based on the path name. If it is relative, a file is made by resolving the path name with respect to the directory in which the file was which defined this ParameterDatabase in the ParameterDatabase hierarchy. If the parameter is not found, this returns null. The File is not checked for validity. The parameter chosen is marked "used" if it exists. */ public final File getFile(Parameter parameter, Parameter defaultParameter) { if (exists(parameter)) return getFile(parameter); else return getFile(defaultParameter); } /** Searches down through the databases to find a given parameter, whose value must be an absolute or relative path name. If the parameter begins with a "$", a file is made based on the relative path name and returned directly. Otherwise, if it is absolute, a File is made based on the path name, or if it is relative, a file is made by resolving the path name with respect to the directory in which the file was which defined this ParameterDatabase in the ParameterDatabase hierarchy. If the parameter is not found, this returns null. The File is not checked for validity. The parameter chosen is marked "used" if it exists. */ final File getFile(Parameter parameter) { if (exists(parameter)) { String p = get(parameter); if (p==null) return null; if (p.startsWith(C_HERE)) return new File(p.substring(C_HERE.length())); else { File f = new File(p); if (f.isAbsolute()) return f; else return new File(directoryFor(parameter),p); } } else return null; } /** Searches down through databases to find a given parameter. Returns the parameter's value (trimmed) or null if not found or if the trimmed result is empty. The parameter chosen is marked "used" if it exists. */ public final synchronized String getString(Parameter parameter, Parameter defaultParameter) { if (exists(parameter)) return getString(parameter); else return getString(defaultParameter); } /** Searches down through databases to find a given parameter. Returns the parameter's value (trimmed) or null if not found or if the trimmed result is empty. The parameter chosen is marked "used" if it exists. */ public final synchronized String getString(Parameter parameter) { if (exists(parameter)) return get(parameter); else return null; } /** Searches down through databases to find a given parameter. Returns the parameter's value trimmed of whitespace, or defaultValue.trim() if the result is not found or the trimmed result is empty. */ public final String getStringWithDefault(Parameter parameter, Parameter defaultParameter, String defaultValue) { if (exists(parameter)) return getStringWithDefault(parameter, defaultValue); else return getStringWithDefault(defaultParameter, defaultValue); } /** Searches down through databases to find a given parameter. Returns the parameter's value trimmed of whitespace, or defaultValue.trim() if the result is not found or the trimmed result is empty. */ public final String getStringWithDefault(Parameter parameter, String defaultValue) { if (exists(parameter)) { String result = get(parameter); if (result==null) { if( defaultValue == null ) return null; else result = defaultValue.trim(); } else { result=result.trim(); if (result.length()==0) { if( defaultValue == null ) return null; else result = defaultValue.trim(); } } return result; } else { if( defaultValue == null ) return null; else return defaultValue.trim(); } } /** Clears the checked flag */ public final synchronized void uncheck() { if (!checked) return; // we already unchecked this path -- this is dangerous if parents are used without children checked = false; int size = parents.size(); for(int x=0;x 0; } }); */ // Uncheck and print each item for(int x=0;x 0; } }); */ // Uncheck and print each item for(int x=0;x 0; } }); */ // Uncheck and print each item for(int x=0;x 0; } }); */ // Uncheck and print each item for(int x=0;x=0;x--) ((ParameterDatabase)(parents.elementAt(x)))._list(p,listShadowed,prefix,gather); Enumeration e = keys(); while(e.hasMoreElements()) { String key = (String)(e.nextElement()); gather.put(key,get(key)); } } p.flush(); } public String toString() { String s = super.toString(); if (parents.size() > 0) { s += " : ("; for(int x=0;x 0) s += ", "; s += parents.elementAt(x); } s += ")"; } return s; } /** Test the ParameterDatabase */ public static void main(String[] args) throws FileNotFoundException,IOException { ParameterDatabase pd = new ParameterDatabase(new File(args[0]),args); pd.set(new Parameter("Hi there"), "Whatever"); pd.set(new Parameter(new String[] {"1", "2", "3"}), " Whatever "); pd.set(new Parameter(new String[] {"a", "b", "c"}).pop().push("d"), "Whatever"); System.err.println("\n\n PRINTING ALL PARAMETERS \n\n"); pd.list(new PrintWriter(System.err,true),true); System.err.println("\n\n PRINTING ONLY VALID PARAMETERS \n\n"); pd.list(new PrintWriter(System.err,true),false); } }