git-svn-id: https://samskivert.googlecode.com/svn/trunk@2043 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -31,32 +31,28 @@ import javax.swing.Scrollable;
|
||||
|
||||
import com.samskivert.Log;
|
||||
import com.samskivert.util.ComparableArrayList;
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.util.PrefsConfig;
|
||||
import com.samskivert.util.DebugChords;
|
||||
import com.samskivert.util.ListUtil;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Provides a service where named variables can be registered as
|
||||
* adjustable by the developer at runtime. Generally a special key is
|
||||
* configured (via {@link DebugChords}) to pop up the adjustable variables
|
||||
* interface which can then be used to toggle booleans, change integer
|
||||
* values and generally adjust debugging and tuning parameters. This is
|
||||
* not meant to be an interface for end-user configurable parameters, but
|
||||
* to allow the developer to tweak runtime parameters more easily.
|
||||
* Provides a service where named variables can be registered as adjustable by the developer at
|
||||
* runtime. Generally a special key is configured (via {@link DebugChords}) to pop up the
|
||||
* adjustable variables interface which can then be used to toggle booleans, change integer values
|
||||
* and generally adjust debugging and tuning parameters. This is not meant to be an interface for
|
||||
* end-user configurable parameters, but to allow the developer to tweak runtime parameters more
|
||||
* easily.
|
||||
*
|
||||
* <p> Adjustments are bound to a {@link Config} property which can be
|
||||
* changed through the config interface or through the bound runtime
|
||||
* adjust.
|
||||
* <p> Adjustments are bound to a {@link PrefsConfig} property which can be changed through the
|
||||
* config interface or through the bound runtime adjust.
|
||||
*
|
||||
* <p> <em>Note:</em> adjusts are meant to be arranged in a two level
|
||||
* hierarchy. An adjust's name, therefore, should be of the form:
|
||||
* <code>library.package.adjustment</code>. The <code>package</code>
|
||||
* component can consist of multiple words joined with a period, but the
|
||||
* <code>library</code> will always be the first word before the first
|
||||
* period and the <code>adjustment</code> always the last word after the
|
||||
* final period. This is mainly only important for organizing the runtime
|
||||
* adjustment editing interface.
|
||||
* <p> <em>Note:</em> adjusts are meant to be arranged in a two level hierarchy. An adjust's name,
|
||||
* therefore, should be of the form: <code>library.package.adjustment</code>. The
|
||||
* <code>package</code> component can consist of multiple words joined with a period, but the
|
||||
* <code>library</code> will always be the first word before the first period and the
|
||||
* <code>adjustment</code> always the last word after the final period. This is mainly only
|
||||
* important for organizing the runtime adjustment editing interface.
|
||||
*/
|
||||
public class RuntimeAdjust
|
||||
{
|
||||
@@ -147,8 +143,7 @@ public class RuntimeAdjust
|
||||
public static class BooleanAdjust extends Adjust
|
||||
implements ActionListener
|
||||
{
|
||||
public BooleanAdjust (String descrip, String name,
|
||||
Config config, boolean defval)
|
||||
public BooleanAdjust (String descrip, String name, PrefsConfig config, boolean defval)
|
||||
{
|
||||
super(descrip, name, config);
|
||||
_value = _config.getValue(_name, defval);
|
||||
@@ -197,8 +192,7 @@ public class RuntimeAdjust
|
||||
/** Provides runtime adjustable integer variables. */
|
||||
public static class IntAdjust extends TextFieldAdjust
|
||||
{
|
||||
public IntAdjust (String descrip, String name,
|
||||
Config config, int defval)
|
||||
public IntAdjust (String descrip, String name, PrefsConfig config, int defval)
|
||||
{
|
||||
super(descrip, name, config);
|
||||
_value = _config.getValue(_name, defval);
|
||||
@@ -251,8 +245,8 @@ public class RuntimeAdjust
|
||||
public static class EnumAdjust extends Adjust
|
||||
implements ActionListener
|
||||
{
|
||||
public EnumAdjust (String descrip, String name,
|
||||
Config config, String[] values, String defval)
|
||||
public EnumAdjust (String descrip, String name, PrefsConfig config,
|
||||
String[] values, String defval)
|
||||
{
|
||||
super(descrip, name, config);
|
||||
_values = values;
|
||||
@@ -310,9 +304,8 @@ public class RuntimeAdjust
|
||||
public static class FileAdjust extends Adjust
|
||||
implements ActionListener
|
||||
{
|
||||
public FileAdjust (String descrip, String name,
|
||||
Config config, boolean directoriesOnly,
|
||||
String defval)
|
||||
public FileAdjust (String descrip, String name, PrefsConfig config,
|
||||
boolean directoriesOnly, String defval)
|
||||
{
|
||||
super(descrip, name, config);
|
||||
_value = _config.getValue(_name, defval);
|
||||
@@ -431,7 +424,7 @@ public class RuntimeAdjust
|
||||
protected abstract static class TextFieldAdjust extends Adjust
|
||||
implements ActionListener, FocusListener
|
||||
{
|
||||
public TextFieldAdjust (String descrip, String name, Config config)
|
||||
public TextFieldAdjust (String descrip, String name, PrefsConfig config)
|
||||
{
|
||||
super(descrip, name, config);
|
||||
}
|
||||
@@ -464,7 +457,7 @@ public class RuntimeAdjust
|
||||
protected abstract static class Adjust
|
||||
implements PropertyChangeListener, Comparable<Adjust>
|
||||
{
|
||||
public Adjust (String descrip, String name, Config config)
|
||||
public Adjust (String descrip, String name, PrefsConfig config)
|
||||
{
|
||||
_name = name;
|
||||
_descrip = descrip;
|
||||
@@ -550,10 +543,9 @@ public class RuntimeAdjust
|
||||
}
|
||||
|
||||
protected String _name, _descrip;
|
||||
protected Config _config;
|
||||
protected PrefsConfig _config;
|
||||
protected JPanel _editor;
|
||||
}
|
||||
|
||||
protected static ComparableArrayList<Adjust> _adjusts =
|
||||
new ComparableArrayList<Adjust>();
|
||||
protected static ComparableArrayList<Adjust> _adjusts = new ComparableArrayList<Adjust>();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import com.samskivert.swing.RuntimeAdjust;
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.util.PrefsConfig;
|
||||
|
||||
/**
|
||||
* Does something extraordinary.
|
||||
@@ -18,7 +18,7 @@ public class AdjustTestApp
|
||||
{
|
||||
public static void main (String[] args)
|
||||
{
|
||||
Config config = new Config("test");
|
||||
PrefsConfig config = new PrefsConfig("test");
|
||||
new RuntimeAdjust.IntAdjust(
|
||||
"This is a test adjustment. It is nice.",
|
||||
"samskivert.test.int_adjust1", config, 5);
|
||||
|
||||
@@ -16,7 +16,7 @@ import javax.swing.JToggleButton;
|
||||
import javax.swing.event.AncestorEvent;
|
||||
import javax.swing.event.AncestorListener;
|
||||
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.util.PrefsConfig;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
|
||||
/**
|
||||
@@ -25,8 +25,8 @@ import com.samskivert.util.IntListUtil;
|
||||
public class ButtonUtil
|
||||
{
|
||||
/**
|
||||
* Set the specified button such that it alternates between being
|
||||
* selected and not whenever it is pushed.
|
||||
* Set the specified button such that it alternates between being selected and not whenever it
|
||||
* is pushed.
|
||||
*/
|
||||
public static synchronized void setToggling (AbstractButton b)
|
||||
{
|
||||
@@ -44,28 +44,25 @@ public class ButtonUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the supplied button to the named boolean property in the
|
||||
* supplied config repository. When the button is pressed, it will
|
||||
* update the config property and when the config property is changed
|
||||
* (by the button or by other means) it will update the selected state
|
||||
* of the button. When the button is made non-visible, it will be
|
||||
* unbound to the config's property and rebound again if it is once
|
||||
* again visible.
|
||||
* Binds the supplied button to the named boolean property in the supplied config repository.
|
||||
* When the button is pressed, it will update the config property and when the config property
|
||||
* is changed (by the button or by other means) it will update the selected state of the
|
||||
* button. When the button is made non-visible, it will be unbound to the config's property and
|
||||
* rebound again if it is once again visible.
|
||||
*/
|
||||
public static void bindToProperty (
|
||||
String property, Config config, AbstractButton button, boolean defval)
|
||||
String property, PrefsConfig config, AbstractButton button, boolean defval)
|
||||
{
|
||||
// create a config binding which will take care of everything
|
||||
new ButtonConfigBinding(property, config, button, defval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the specified button to cause the specified
|
||||
* property to cycle through the specified values whenever the button is
|
||||
* pressed.
|
||||
* Configure the specified button to cause the specified property to cycle through the
|
||||
* specified values whenever the button is pressed.
|
||||
*/
|
||||
public static ActionListener cycleToProperty (
|
||||
final String property, final Config config, AbstractButton button,
|
||||
final String property, final PrefsConfig config, AbstractButton button,
|
||||
final int[] values)
|
||||
{
|
||||
ActionListener al = new ActionListener() {
|
||||
@@ -87,7 +84,7 @@ public class ButtonUtil
|
||||
protected static class ButtonConfigBinding
|
||||
implements AncestorListener, PropertyChangeListener, ItemListener
|
||||
{
|
||||
public ButtonConfigBinding (String property, Config config,
|
||||
public ButtonConfigBinding (String property, PrefsConfig config,
|
||||
AbstractButton button, boolean defval)
|
||||
{
|
||||
_property = property;
|
||||
@@ -136,7 +133,7 @@ public class ButtonUtil
|
||||
}
|
||||
|
||||
protected String _property;
|
||||
protected Config _config;
|
||||
protected PrefsConfig _config;
|
||||
protected AbstractButton _button;
|
||||
protected boolean _defval;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2001 Michael Bayne
|
||||
//
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
@@ -20,12 +20,6 @@
|
||||
|
||||
package com.samskivert.util;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -34,22 +28,16 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import java.util.prefs.AbstractPreferences;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import com.samskivert.Log;
|
||||
|
||||
/**
|
||||
* The config class provides a unified interaface to application
|
||||
* configuration information. It takes care of loading properties files
|
||||
* (done via the classpath) and allows for overriding and inheriting of
|
||||
* properties values (see {@link ConfigUtil#loadInheritedProperties}).
|
||||
* The config class provides a unified interaface to application configuration information. It
|
||||
* takes care of loading properties files (done via the classpath) and allows for overriding and
|
||||
* inheriting of properties values (see {@link ConfigUtil#loadInheritedProperties}).
|
||||
*
|
||||
* <p> A common pattern is to create, for each package that shares
|
||||
* configuration information, a singleton class containing a config object
|
||||
* that is configured to load its data from a single configuration
|
||||
* file. For example:
|
||||
* <p> A common pattern is to create, for each package that shares configuration information, a
|
||||
* singleton class containing a config object that is configured to load its data from a single
|
||||
* configuration file. For example:
|
||||
*
|
||||
* <pre>
|
||||
* public class FooConfig
|
||||
@@ -60,9 +48,8 @@ import com.samskivert.Log;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* which would look for <code>com/fribitz/foo.properties</code> in the
|
||||
* classpath and serve up those configuration values when requests were
|
||||
* made from <code>FooConfig.config</code>. For example:
|
||||
* which would look for <code>com/fribitz/foo.properties</code> in the classpath and serve up those
|
||||
* configuration values when requests were made from <code>FooConfig.config</code>. For example:
|
||||
*
|
||||
* <pre>
|
||||
* int fiddles = FooConfig.config.getValue(FooConfig.FIDDLES, 0);
|
||||
@@ -71,8 +58,7 @@ import com.samskivert.Log;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* An even better approach involves creating accessors for all defined
|
||||
* configuration properties:
|
||||
* An even better approach involves creating accessors for all defined configuration properties:
|
||||
*
|
||||
* <pre>
|
||||
* public class FooConfig
|
||||
@@ -90,23 +76,16 @@ import com.samskivert.Log;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* This allows the default value for <code>fiddles</code> to be specified
|
||||
* in one place and simplifies life for the caller who can now simply
|
||||
* request <code>FooConfig.getFiddles()</code>.
|
||||
* This allows the default value for <code>fiddles</code> to be specified in one place and
|
||||
* simplifies life for the caller who can now simply request <code>FooConfig.getFiddles()</code>.
|
||||
*
|
||||
* <p> The config class allows one to override configuration values
|
||||
* persistently, using the standard Java {@link Preferences} facilities to
|
||||
* maintain the overridden values. If a property is {@link #setValue}d in
|
||||
* a configuration object, it will remain overridden in between
|
||||
* invocations of the application (leveraging the benefits of the
|
||||
* pluggable preferences backends provided by the standard Java
|
||||
* preferences facilities).
|
||||
* @see PrefsConfig
|
||||
*/
|
||||
public class Config
|
||||
{
|
||||
/**
|
||||
* Constructs a new config object which will obtain configuration
|
||||
* information from the specified properties bundle.
|
||||
* Constructs a new config object which will obtain configuration information from the
|
||||
* specified properties bundle.
|
||||
*/
|
||||
public Config (String path)
|
||||
{
|
||||
@@ -121,119 +100,59 @@ public class Config
|
||||
ConfigUtil.loadInheritedProperties(ppath, _props);
|
||||
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
Log.debug("No properties file found to back config " +
|
||||
"[path=" + path + "].");
|
||||
Log.debug("No properties file found to back config [path=" + path + "].");
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Unable to load configuration [path=" + path +
|
||||
", ioe=" + ioe + "].");
|
||||
}
|
||||
|
||||
// get a handle on the preferences instance that we'll use to
|
||||
// override values in the properties file
|
||||
try {
|
||||
_prefs = Preferences.userRoot().node(path);
|
||||
} catch (AccessControlException ace) {
|
||||
// security manager won't let us access prefs, no problem!
|
||||
Log.info("Can't access preferences [path=" + path + "].");
|
||||
_prefs = new NullPreferences();
|
||||
Log.warning("Unable to load configuration [path=" + path + ", ioe=" + ioe + "].");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a config object which will obtain information from the
|
||||
* supplied properties, rooted at the specified path in the
|
||||
* preferences hieriarchy.
|
||||
* Constructs a config object which will obtain information from the supplied properties.
|
||||
*/
|
||||
public Config (final String path, Properties props)
|
||||
public Config (String path, Properties props)
|
||||
{
|
||||
_props = props;
|
||||
try {
|
||||
_prefs = Preferences.userRoot().node(path);
|
||||
} catch (AccessControlException ace) {
|
||||
// security manager won't let us access prefs, no problem!
|
||||
Log.info("Can't access preferences [path=" + path + "].");
|
||||
_prefs = new NullPreferences();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead. If
|
||||
* the property specified in the file is poorly formatted (not and
|
||||
* integer, not in proper array specification), a warning message will
|
||||
* be logged and the default value will be returned.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* If the property specified in the file is poorly formatted (not and integer, not in proper
|
||||
* array specification), a warning message will be logged and the default value will be
|
||||
* returned.
|
||||
*
|
||||
* @param name name of the property.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public int getValue (String name, int defval)
|
||||
{
|
||||
return _prefs.getInt(name, getDefValue(name, defval));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value specified in the properties override file.
|
||||
*/
|
||||
protected int getDefValue (String name, int defval)
|
||||
{
|
||||
String val = _props.getProperty(name);
|
||||
if (val != null) {
|
||||
try {
|
||||
// handles base 10, hex values, etc.
|
||||
return Integer.decode(val).intValue();
|
||||
return Integer.decode(val).intValue(); // handles base 10, hex values, etc.
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log.warning("Malformed integer property [name=" + name +
|
||||
", value=" + val + "].");
|
||||
Log.warning("Malformed integer property [name=" + name + ", value=" + val + "].");
|
||||
}
|
||||
}
|
||||
return defval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, int value)
|
||||
{
|
||||
Integer oldValue = null;
|
||||
if (_prefs.get(name, null) != null ||
|
||||
_props.getProperty(name) != null) {
|
||||
oldValue = Integer.valueOf(
|
||||
_prefs.getInt(name, getDefValue(name, 0)));
|
||||
}
|
||||
|
||||
_prefs.putInt(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Integer.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead. If
|
||||
* the property specified in the file is poorly formatted (not and
|
||||
* integer, not in proper array specification), a warning message will
|
||||
* be logged and the default value will be returned.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* If the property specified in the file is poorly formatted (not and integer, not in proper
|
||||
* array specification), a warning message will be logged and the default value will be
|
||||
* returned.
|
||||
*
|
||||
* @param name name of the property.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public long getValue (String name, long defval)
|
||||
{
|
||||
return _prefs.getLong(name, getDefValue(name, defval));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value specified in the properties override file.
|
||||
*/
|
||||
protected long getDefValue (String name, long defval)
|
||||
{
|
||||
String val = _props.getProperty(name);
|
||||
if (val != null) {
|
||||
@@ -248,45 +167,18 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, long value)
|
||||
{
|
||||
Long oldValue = null;
|
||||
if (_prefs.get(name, null) != null ||
|
||||
_props.getProperty(name) != null) {
|
||||
oldValue = Long.valueOf(
|
||||
_prefs.getLong(name, getDefValue(name, 0L)));
|
||||
}
|
||||
|
||||
_prefs.putLong(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Long.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead. If
|
||||
* the property specified in the file is poorly formatted (not and
|
||||
* integer, not in proper array specification), a warning message will
|
||||
* be logged and the default value will be returned.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* If the property specified in the file is poorly formatted (not and integer, not in proper
|
||||
* array specification), a warning message will be logged and the default value will be
|
||||
* returned.
|
||||
*
|
||||
* @param name name of the property.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public float getValue (String name, float defval)
|
||||
{
|
||||
return _prefs.getFloat(name, getDefValue(name, defval));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value specified in the properties override file.
|
||||
*/
|
||||
protected float getDefValue (String name, float defval)
|
||||
{
|
||||
String val = _props.getProperty(name);
|
||||
if (val != null) {
|
||||
@@ -301,79 +193,17 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, float value)
|
||||
{
|
||||
Float oldValue = null;
|
||||
if (_prefs.get(name, null) != null ||
|
||||
_props.getProperty(name) != null) {
|
||||
oldValue = Float.valueOf(
|
||||
_prefs.getFloat(name, getDefValue(name, 0f)));
|
||||
}
|
||||
|
||||
_prefs.putFloat(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Float.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* The returned value will be <code>false</code> if the config value is <code>"false"</code>
|
||||
* (case-insensitive), else the return value will be true.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public String getValue (String name, String defval)
|
||||
{
|
||||
// if there is a value, parse it into an integer
|
||||
String val = _props.getProperty(name);
|
||||
if (val != null) {
|
||||
defval = val;
|
||||
}
|
||||
|
||||
// finally look for an overridden value
|
||||
return _prefs.get(name, defval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, String value)
|
||||
{
|
||||
String oldValue = getValue(name, (String)null);
|
||||
_prefs.put(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned
|
||||
* instead. The returned value will be <code>false</code> if the
|
||||
* config value is <code>"false"</code> (case-insensitive), else
|
||||
* the return value will be true.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public boolean getValue (String name, boolean defval)
|
||||
{
|
||||
return _prefs.getBoolean(name, getDefValue(name, defval));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value specified in the properties override file.
|
||||
*/
|
||||
protected boolean getDefValue (String name, boolean defval)
|
||||
{
|
||||
String val = _props.getProperty(name);
|
||||
if (val != null) {
|
||||
@@ -383,41 +213,35 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public void setValue (String name, boolean value)
|
||||
public String getValue (String name, String defval)
|
||||
{
|
||||
Boolean oldValue = null;
|
||||
if (_prefs.get(name, null) != null ||
|
||||
_props.getProperty(name) != null) {
|
||||
oldValue = Boolean.valueOf(
|
||||
_prefs.getBoolean(name, getDefValue(name, false)));
|
||||
}
|
||||
|
||||
_prefs.putBoolean(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Boolean.valueOf(value));
|
||||
return _props.getProperty(name, defval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead. If
|
||||
* the property specified in the file is poorly formatted (not and
|
||||
* integer, not in proper array specification), a warning message will
|
||||
* be logged and the default value will be returned.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* If the property specified in the file is poorly formatted (not and integer, not in proper
|
||||
* array specification), a warning message will be logged and the default value will be
|
||||
* returned.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public int[] getValue (String name, int[] defval)
|
||||
{
|
||||
// look up the value in the configuration file and use that to
|
||||
// look up any overridden value
|
||||
String val = _prefs.get(name, _props.getProperty(name));
|
||||
// look up the value in the configuration file and use that to look up any overridden value
|
||||
String val = getValue(name, (String)null);
|
||||
int[] result = defval;
|
||||
|
||||
// parse it into an array of ints
|
||||
@@ -434,35 +258,21 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, int[] value)
|
||||
{
|
||||
int[] oldValue = getValue(name, (int[])null);
|
||||
_prefs.put(name, StringUtil.toString(value, "", ""));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead. If
|
||||
* the property specified in the file is poorly formatted (not and
|
||||
* integer, not in proper array specification), a warning message will
|
||||
* be logged and the default value will be returned.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* If the property specified in the file is poorly formatted (not and integer, not in proper
|
||||
* array specification), a warning message will be logged and the default value will be
|
||||
* returned.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public long[] getValue (String name, long[] defval)
|
||||
{
|
||||
// look up the value in the configuration file and use that to
|
||||
// look up any overridden value
|
||||
String val = _prefs.get(name, _props.getProperty(name));
|
||||
// look up the value in the configuration file and use that to look up any overridden value
|
||||
String val = getValue(name, (String)null);
|
||||
long[] result = defval;
|
||||
|
||||
// parse it into an array of longs
|
||||
@@ -479,35 +289,21 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, long[] value)
|
||||
{
|
||||
long[] oldValue = getValue(name, (long[])null);
|
||||
_prefs.put(name, StringUtil.toString(value, "", ""));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead. If
|
||||
* the property specified in the file is poorly formatted (not a
|
||||
* floating point value, not in proper array specification), a warning
|
||||
* message will be logged and the default value will be returned.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* If the property specified in the file is poorly formatted (not a floating point value, not
|
||||
* in proper array specification), a warning message will be logged and the default value will
|
||||
* be returned.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public float[] getValue (String name, float[] defval)
|
||||
{
|
||||
// look up the value in the configuration file and use that to
|
||||
// look up any overridden value
|
||||
String val = _prefs.get(name, _props.getProperty(name));
|
||||
// look up the value in the configuration file and use that to look up any overridden value
|
||||
String val = getValue(name, (String)null);
|
||||
float[] result = defval;
|
||||
|
||||
// parse it into an array of ints
|
||||
@@ -524,35 +320,21 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, float[] value)
|
||||
{
|
||||
float[] oldValue = getValue(name, (float[])null);
|
||||
_prefs.put(name, StringUtil.toString(value, "", ""));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the value for the specified configuration
|
||||
* property. If the value is not specified in the associated
|
||||
* properties file, the supplied default value is returned instead. If
|
||||
* the property specified in the file is poorly formatted (not and
|
||||
* integer, not in proper array specification), a warning message will
|
||||
* be logged and the default value will be returned.
|
||||
* Fetches and returns the value for the specified configuration property. If the value is not
|
||||
* specified in the associated properties file, the supplied default value is returned instead.
|
||||
* If the property specified in the file is poorly formatted (not and integer, not in proper
|
||||
* array specification), a warning message will be logged and the default value will be
|
||||
* returned.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defval the value to return if the property is not specified
|
||||
* in the config file.
|
||||
* @param defval the value to return if the property is not specified in the config file.
|
||||
*
|
||||
* @return the value of the requested property.
|
||||
*/
|
||||
public String[] getValue (String name, String[] defval)
|
||||
{
|
||||
// look up the value in the configuration file and use that to
|
||||
// look up any overridden value
|
||||
String val = _prefs.get(name, _props.getProperty(name));
|
||||
// look up the value in the configuration file and use that to look up any overridden value
|
||||
String val = getValue(name, (String)null);
|
||||
String[] result = defval;
|
||||
|
||||
// parse it into an array of ints
|
||||
@@ -569,78 +351,13 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value
|
||||
* defined in the configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, String[] value)
|
||||
{
|
||||
String[] oldValue = getValue(name, (String[])null);
|
||||
_prefs.put(name, StringUtil.joinEscaped(value));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any set value for the specified preference.
|
||||
*/
|
||||
public void remove (String name)
|
||||
{
|
||||
// we treat the old value as a String, I hope that's ok!
|
||||
String oldValue = getValue(name, (String) null);
|
||||
_prefs.remove(name);
|
||||
_propsup.firePropertyChange(name, oldValue, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener that will be notified whenever any configuration
|
||||
* properties are changed by a call to one of the <code>set</code>
|
||||
* methods.
|
||||
*/
|
||||
public void addPropertyChangeListener (PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a property change listener previously added via a call to
|
||||
* {@link #addPropertyChangeListener}.
|
||||
*/
|
||||
public void removePropertyChangeListener (PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener that will be notified whenever the specified
|
||||
* configuration property is changed by a call to the appropriate
|
||||
* <code>set</code> method.
|
||||
*/
|
||||
public void addPropertyChangeListener (
|
||||
String name, PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.addPropertyChangeListener(name, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a property change listener previously added via a call to
|
||||
* {@link #addPropertyChangeListener(String,PropertyChangeListener)}.
|
||||
*/
|
||||
public void removePropertyChangeListener (
|
||||
String name, PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.removePropertyChangeListener(name, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the specified string-valued configuration entry, loads the
|
||||
* class with that name and instantiates a new instance of that class,
|
||||
* which is returned.
|
||||
* Looks up the specified string-valued configuration entry, loads the class with that name and
|
||||
* instantiates a new instance of that class, which is returned.
|
||||
*
|
||||
* @param name the name of the property to be fetched.
|
||||
* @param defcname the class name to use if the property is not
|
||||
* specified in the config file.
|
||||
* @param defcname the class name to use if the property is not specified in the config file.
|
||||
*
|
||||
* @exception Exception thrown if any error occurs while loading or
|
||||
* instantiating the class.
|
||||
* @exception Exception thrown if any error occurs while loading or instantiating the class.
|
||||
*/
|
||||
public Object instantiateValue (String name, String defcname)
|
||||
throws Exception
|
||||
@@ -649,10 +366,9 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a properties object containing all configuration values
|
||||
* that start with the supplied prefix (plus a trailing "." which will
|
||||
* be added if it doesn't already exist). The keys in the
|
||||
* sub-properties will have had the prefix stripped off.
|
||||
* Returns a properties object containing all configuration values that start with the supplied
|
||||
* prefix (plus a trailing "." which will be added if it doesn't already exist). The keys in
|
||||
* the sub-properties will have had the prefix stripped off.
|
||||
*/
|
||||
public Properties getSubProperties (String prefix)
|
||||
{
|
||||
@@ -662,10 +378,9 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills into the supplied properties object all configuration values
|
||||
* that start with the supplied prefix (plus a trailing "." which will
|
||||
* be added if it doesn't already exist). The keys in the
|
||||
* sub-properties will have had the prefix stripped off.
|
||||
* Fills into the supplied properties object all configuration values that start with the
|
||||
* supplied prefix (plus a trailing "." which will be added if it doesn't already exist). The
|
||||
* keys in the sub-properties will have had the prefix stripped off.
|
||||
*/
|
||||
public void getSubProperties (String prefix, Properties target)
|
||||
{
|
||||
@@ -690,75 +405,26 @@ public class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator that returns all of the configuration keys in
|
||||
* this config object.
|
||||
* Returns an iterator that returns all of the configuration keys in this config object.
|
||||
*/
|
||||
public Iterator<String> keys ()
|
||||
{
|
||||
// what with all the complicated business, we just need to take
|
||||
// the brute force approach and enumerate everything up front
|
||||
HashSet<String> matches = new HashSet<String>();
|
||||
|
||||
// add the keys provided in the config files
|
||||
Enumeration defkeys = _props.propertyNames();
|
||||
while (defkeys.hasMoreElements()) {
|
||||
matches.add((String)defkeys.nextElement());
|
||||
}
|
||||
|
||||
// then add the overridden keys
|
||||
try {
|
||||
String[] keys = _prefs.keys();
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
matches.add(keys[i]);
|
||||
}
|
||||
} catch (BackingStoreException bse) {
|
||||
Log.warning("Unable to enumerate preferences keys " +
|
||||
"[error=" + bse + "].");
|
||||
}
|
||||
|
||||
enumerateKeys(matches);
|
||||
return matches.iterator();
|
||||
}
|
||||
|
||||
/** This is used if we don't have security access to the preferences
|
||||
* implementation that we'd like. */
|
||||
protected static class NullPreferences extends AbstractPreferences
|
||||
protected void enumerateKeys (HashSet<String> keys)
|
||||
{
|
||||
public NullPreferences () {
|
||||
super(null, "");
|
||||
}
|
||||
protected void putSpi (String key, String value) {
|
||||
}
|
||||
protected String getSpi (String key) {
|
||||
return null;
|
||||
}
|
||||
protected void removeSpi (String key) {
|
||||
}
|
||||
protected void removeNodeSpi () throws BackingStoreException {
|
||||
}
|
||||
protected String[] keysSpi () throws BackingStoreException {
|
||||
return new String[0];
|
||||
}
|
||||
protected String[] childrenNamesSpi () throws BackingStoreException {
|
||||
return new String[0];
|
||||
}
|
||||
protected AbstractPreferences childSpi (String name) {
|
||||
return null;
|
||||
}
|
||||
protected void syncSpi () throws BackingStoreException {
|
||||
}
|
||||
protected void flushSpi () throws BackingStoreException {
|
||||
Enumeration defkeys = _props.propertyNames();
|
||||
while (defkeys.hasMoreElements()) {
|
||||
keys.add((String)defkeys.nextElement());
|
||||
}
|
||||
}
|
||||
|
||||
/** Contains the default configuration information. */
|
||||
protected Properties _props;
|
||||
|
||||
/** Used to maintain configuration overrides. */
|
||||
protected Preferences _prefs;
|
||||
|
||||
/** Used to support our property change mechanism. */
|
||||
protected PropertyChangeSupport _propsup = new PropertyChangeSupport(this);
|
||||
|
||||
/** The file extension used for configuration files. */
|
||||
protected static final String PROPS_SUFFIX = ".properties";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2007 Michael Bayne
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.util;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import java.util.prefs.AbstractPreferences;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import com.samskivert.Log;
|
||||
|
||||
/**
|
||||
* Extends the {@link Config} mechanism to allow the modification of configuration values, which
|
||||
* are persisted using the Java preferences system. If a property is {@link #setValue}d, it will
|
||||
* remain overridden in between invocations of the application (leveraging the benefits of the
|
||||
* pluggable preferences backends provided by the standard Java preferences facilities).
|
||||
*/
|
||||
public class PrefsConfig extends Config
|
||||
{
|
||||
/**
|
||||
* Constructs a new config object which will obtain configuration information from the
|
||||
* specified properties bundle.
|
||||
*/
|
||||
public PrefsConfig (String path)
|
||||
{
|
||||
super(path);
|
||||
|
||||
// get a handle on the preferences instance that we'll use to override values in the
|
||||
// properties file
|
||||
try {
|
||||
_prefs = Preferences.userRoot().node(path);
|
||||
} catch (AccessControlException ace) {
|
||||
// security manager won't let us access prefs, no problem!
|
||||
Log.info("Can't access preferences [path=" + path + "].");
|
||||
_prefs = new NullPreferences();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a config object which will obtain information from the supplied properties,
|
||||
* rooted at the specified path in the preferences hieriarchy.
|
||||
*/
|
||||
public PrefsConfig (String path, Properties props)
|
||||
{
|
||||
super(path, props);
|
||||
|
||||
try {
|
||||
_prefs = Preferences.userRoot().node(path);
|
||||
} catch (AccessControlException ace) {
|
||||
// security manager won't let us access prefs, no problem!
|
||||
Log.info("Can't access preferences [path=" + path + "].");
|
||||
_prefs = new NullPreferences();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, int value)
|
||||
{
|
||||
Integer oldValue = null;
|
||||
if (_prefs.get(name, null) != null || _props.getProperty(name) != null) {
|
||||
oldValue = Integer.valueOf(_prefs.getInt(name, super.getValue(name, 0)));
|
||||
}
|
||||
|
||||
_prefs.putInt(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Integer.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, long value)
|
||||
{
|
||||
Long oldValue = null;
|
||||
if (_prefs.get(name, null) != null || _props.getProperty(name) != null) {
|
||||
oldValue = Long.valueOf(_prefs.getLong(name, super.getValue(name, 0L)));
|
||||
}
|
||||
|
||||
_prefs.putLong(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Long.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, float value)
|
||||
{
|
||||
Float oldValue = null;
|
||||
if (_prefs.get(name, null) != null || _props.getProperty(name) != null) {
|
||||
oldValue = Float.valueOf(_prefs.getFloat(name, super.getValue(name, 0f)));
|
||||
}
|
||||
|
||||
_prefs.putFloat(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Float.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, boolean value)
|
||||
{
|
||||
Boolean oldValue = null;
|
||||
if (_prefs.get(name, null) != null || _props.getProperty(name) != null) {
|
||||
oldValue = Boolean.valueOf(_prefs.getBoolean(name, super.getValue(name, false)));
|
||||
}
|
||||
|
||||
_prefs.putBoolean(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, Boolean.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, String value)
|
||||
{
|
||||
String oldValue = getValue(name, (String)null);
|
||||
_prefs.put(name, value);
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, int[] value)
|
||||
{
|
||||
int[] oldValue = getValue(name, (int[])null);
|
||||
_prefs.put(name, StringUtil.toString(value, "", ""));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, long[] value)
|
||||
{
|
||||
long[] oldValue = getValue(name, (long[])null);
|
||||
_prefs.put(name, StringUtil.toString(value, "", ""));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, float[] value)
|
||||
{
|
||||
float[] oldValue = getValue(name, (float[])null);
|
||||
_prefs.put(name, StringUtil.toString(value, "", ""));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified preference, overriding the value defined in the
|
||||
* configuration files shipped with the application.
|
||||
*/
|
||||
public void setValue (String name, String[] value)
|
||||
{
|
||||
String[] oldValue = getValue(name, (String[])null);
|
||||
_prefs.put(name, StringUtil.joinEscaped(value));
|
||||
_propsup.firePropertyChange(name, oldValue, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any set value for the specified preference.
|
||||
*/
|
||||
public void remove (String name)
|
||||
{
|
||||
// we treat the old value as a String, I hope that's ok!
|
||||
String oldValue = getValue(name, (String) null);
|
||||
_prefs.remove(name);
|
||||
_propsup.firePropertyChange(name, oldValue, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener that will be notified whenever any configuration properties are changed by a
|
||||
* call to one of the <code>set</code> methods.
|
||||
*/
|
||||
public void addPropertyChangeListener (PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a property change listener previously added via a call to {@link
|
||||
* #addPropertyChangeListener}.
|
||||
*/
|
||||
public void removePropertyChangeListener (PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener that will be notified whenever the specified configuration property is
|
||||
* changed by a call to the appropriate <code>set</code> method.
|
||||
*/
|
||||
public void addPropertyChangeListener (String name, PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.addPropertyChangeListener(name, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a property change listener previously added via a call to {@link
|
||||
* #addPropertyChangeListener(String,PropertyChangeListener)}.
|
||||
*/
|
||||
public void removePropertyChangeListener (String name, PropertyChangeListener listener)
|
||||
{
|
||||
_propsup.removePropertyChangeListener(name, listener);
|
||||
}
|
||||
|
||||
@Override // from Config
|
||||
public int getValue (String name, int defval)
|
||||
{
|
||||
return _prefs.getInt(name, super.getValue(name, defval));
|
||||
}
|
||||
|
||||
@Override // from Config
|
||||
public long getValue (String name, long defval)
|
||||
{
|
||||
return _prefs.getLong(name, super.getValue(name, defval));
|
||||
}
|
||||
|
||||
@Override // from Config
|
||||
public float getValue (String name, float defval)
|
||||
{
|
||||
return _prefs.getFloat(name, super.getValue(name, defval));
|
||||
}
|
||||
|
||||
@Override // from Config
|
||||
public boolean getValue (String name, boolean defval)
|
||||
{
|
||||
return _prefs.getBoolean(name, super.getValue(name, defval));
|
||||
}
|
||||
|
||||
@Override // from Config
|
||||
public String getValue (String name, String defval)
|
||||
{
|
||||
return _prefs.get(name, super.getValue(name, defval));
|
||||
}
|
||||
|
||||
@Override // from Config
|
||||
protected void enumerateKeys (HashSet<String> keys)
|
||||
{
|
||||
super.enumerateKeys(keys);
|
||||
|
||||
try {
|
||||
for (String key : _prefs.keys()) {
|
||||
keys.add(key);
|
||||
}
|
||||
} catch (BackingStoreException bse) {
|
||||
Log.warning("Unable to enumerate preferences keys [error=" + bse + "].");
|
||||
}
|
||||
}
|
||||
|
||||
/** This is used if we don't have security access to the preferences
|
||||
* implementation that we'd like. */
|
||||
protected static class NullPreferences extends AbstractPreferences
|
||||
{
|
||||
public NullPreferences () {
|
||||
super(null, "");
|
||||
}
|
||||
protected void putSpi (String key, String value) {
|
||||
}
|
||||
protected String getSpi (String key) {
|
||||
return null;
|
||||
}
|
||||
protected void removeSpi (String key) {
|
||||
}
|
||||
protected void removeNodeSpi () throws BackingStoreException {
|
||||
}
|
||||
protected String[] keysSpi () throws BackingStoreException {
|
||||
return new String[0];
|
||||
}
|
||||
protected String[] childrenNamesSpi () throws BackingStoreException {
|
||||
return new String[0];
|
||||
}
|
||||
protected AbstractPreferences childSpi (String name) {
|
||||
return null;
|
||||
}
|
||||
protected void syncSpi () throws BackingStoreException {
|
||||
}
|
||||
protected void flushSpi () throws BackingStoreException {
|
||||
}
|
||||
}
|
||||
|
||||
/** Used to maintain configuration overrides. */
|
||||
protected Preferences _prefs;
|
||||
|
||||
/** Used to support our property change mechanism. */
|
||||
protected PropertyChangeSupport _propsup = new PropertyChangeSupport(this);
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import java.util.Properties;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.util.PrefsConfig;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ public class ConfigTest extends TestCase
|
||||
|
||||
public void runTest ()
|
||||
{
|
||||
Config config = new Config("rsrc/util/test");
|
||||
PrefsConfig config = new PrefsConfig("rsrc/util/test");
|
||||
|
||||
System.out.println("prop1: " + config.getValue("prop1", 1));
|
||||
System.out.println("prop2: " + config.getValue("prop2", "two"));
|
||||
@@ -51,8 +51,7 @@ public class ConfigTest extends TestCase
|
||||
config.setValue("sub.sub3", "three");
|
||||
|
||||
Properties subprops = config.getSubProperties("sub");
|
||||
System.out.println("Sub: " +
|
||||
StringUtil.toString(subprops.propertyNames()));
|
||||
System.out.println("Sub: " + StringUtil.toString(subprops.propertyNames()));
|
||||
}
|
||||
|
||||
public static Test suite ()
|
||||
|
||||
Reference in New Issue
Block a user