Widening.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4812 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2007-08-16 18:25:46 +00:00
parent 59086147e6
commit f80495f906
3 changed files with 48 additions and 73 deletions
@@ -52,41 +52,33 @@ import com.threerings.presents.dobj.SetListener;
import com.threerings.admin.Log; import com.threerings.admin.Log;
/** /**
* Provides a registry of configuration distributed objects. Using distributed * Provides a registry of configuration distributed objects. Using distributed object to store
* object to store runtime configuration data can be exceptionally useful in * runtime configuration data can be exceptionally useful in that clients (with admin privileges)
* that clients (with admin privileges) can view and update the running * can view and update the running server's configuration parameters on the fly.
* server's configuration parameters on the fly.
* *
* <p> Users of the service are responsible for creating their own * <p> Users of the service are responsible for creating their own configuration objects which are
* configuration objects which are then registered via this class. The config * then registered via this class. The config object registry then performs a few functions:
* object registry then performs a few functions:
* *
* <ul> * <ul>
* <li> It populates the config object with values from the persistent configuration information.
* <li> It populates the config object with values from the persistent * <li> It mirrors object updates out to the persistent configuration repository.
* configuration information. * <li> It makes the set of registered objects available for inspection and modification via the
* <li> It mirrors object updates out to the persistent configuration * admin client interface.
* repository.
* <li> It makes the set of registered objects available for inspection and
* modification via the admin client interface.
* </ul> * </ul>
* *
* <p> Users of this service will want to use {@link AccessController}s on * <p> Users of this service will want to use {@link AccessController}s on their configuration
* their configuration distributed objects to prevent non-administrators from * distributed objects to prevent non-administrators from subscribing to or modifying the objects.
* subscribing to or modifying the objects.
*/ */
public abstract class ConfigRegistry public abstract class ConfigRegistry
{ {
/** /**
* Registers the supplied configuration object with the system. * Registers the supplied configuration object with the system.
* *
* @param key a string that identifies this object. These are generally * @param key a string that identifies this object. These are generally hierarchical in nature
* hierarchical in nature (of the form <code>system.subsystem</code>), for * (of the form <code>system.subsystem</code>), for example: <code>yohoho.crew</code>.
* example: <code>yohoho.crew</code>. * @param path The the path in the persistent configuration repository. This may mean
* @param path The the path in the persistent configuration repository. * something to the underlying persistent store, for example in the preferences backed
* This may mean something to the underlying persistent store, for example * implementation it defines the path to the preferences node in the package hierarchy.
* in the preferences backed implementation it defines the path to the
* preferences node in the package hierarchy.
* @param object the object to be registered. * @param object the object to be registered.
*/ */
public void registerObject (String key, String path, DObject object) public void registerObject (String key, String path, DObject object)
@@ -97,8 +89,7 @@ public abstract class ConfigRegistry
} }
/** /**
* Returns the config object mapped to the specified key, or null if none * Returns the config object mapped to the specified key, or null if none exists for that key.
* exists for that key.
*/ */
public DObject getObject (String key) public DObject getObject (String key)
{ {
@@ -107,8 +98,7 @@ public abstract class ConfigRegistry
} }
/** /**
* Returns an array containing the keys of all registered configuration * Returns an array containing the keys of all registered configuration objects.
* objects.
*/ */
public String[] getKeys () public String[] getKeys ()
{ {
@@ -116,11 +106,9 @@ public abstract class ConfigRegistry
} }
/** /**
* Creates an object record derivation that will handle the management of * Creates an object record derivation that will handle the management of the specified object.
* the specified object.
*/ */
protected abstract ObjectRecord createObjectRecord ( protected abstract ObjectRecord createObjectRecord (String path, DObject object);
String path, DObject object);
/** /**
* Contains all necessary info for a configuration object registration. * Contains all necessary info for a configuration object registration.
@@ -137,15 +125,13 @@ public abstract class ConfigRegistry
public void init () public void init ()
{ {
// read in the initial configuration settings from the persistent // read in the initial configuration settings from the persistent config repository
// configuration repository
Class cclass = object.getClass(); Class cclass = object.getClass();
try { try {
Field[] fields = cclass.getFields(); Field[] fields = cclass.getFields();
for (int ii = 0; ii < fields.length; ii++) { for (int ii = 0; ii < fields.length; ii++) {
int mods = fields[ii].getModifiers(); int mods = fields[ii].getModifiers();
if ((mods & Modifier.STATIC) != 0 || if ((mods & Modifier.STATIC) != 0 || (mods & Modifier.PUBLIC) == 0 ||
(mods & Modifier.PUBLIC) == 0 ||
(mods & Modifier.TRANSIENT) != 0) { (mods & Modifier.TRANSIENT) != 0) {
continue; continue;
} }
@@ -156,8 +142,8 @@ public abstract class ConfigRegistry
object.addListener(this); object.addListener(this);
} catch (SecurityException se) { } catch (SecurityException se) {
Log.warning("Unable to reflect on " + cclass.getName() + ": " + Log.warning("Unable to reflect on " + cclass.getName() + ": " + se + ". " +
se + ". Refusing to monitor object."); "Refusing to monitor object.");
} }
} }
@@ -182,8 +168,8 @@ public abstract class ConfigRegistry
try { try {
value = object.getAttribute(event.getName()); value = object.getAttribute(event.getName());
} catch (ObjectAccessException oae) { } catch (ObjectAccessException oae) {
Log.warning("Exception getting field [name=" + event.getName() + "exception=" + Log.warning("Exception getting field [name=" + event.getName() +
oae + "]."); ", exception=" + oae + "].");
return; return;
} }
updateValue(event.getName(), value); updateValue(event.getName(), value);
@@ -224,16 +210,14 @@ public abstract class ConfigRegistry
} else if (value instanceof long[]) { } else if (value instanceof long[]) {
setValue(key, (long[]) value); setValue(key, (long[]) value);
} else { } else {
Log.info("Unable to flush config object change " + Log.info("Unable to flush config obj change [cobj=" + object.getClass().getName() +
"[cobj=" + object.getClass().getName() + ", key=" + key + ", type=" + value.getClass().getName() +
", key=" + key +
", type=" + value.getClass().getName() +
", value=" + value + "]."); ", value=" + value + "].");
} }
} }
/** Initializes a single field of a config distributed object from /** Initializes a single field of a config distributed object from its corresponding value
* its corresponding value in the associated config repository. */ * in the associated config repository. */
protected void initField (Field field) protected void initField (Field field)
{ {
String key = nameToKey(field.getName()); String key = nameToKey(field.getName());
@@ -288,33 +272,30 @@ public abstract class ConfigRegistry
} }
try { try {
ByteArrayInputStream bin = new ByteArrayInputStream( ByteArrayInputStream bin =
StringUtil.unhexlate(value)); new ByteArrayInputStream(StringUtil.unhexlate(value));
ObjectInputStream oin = new ObjectInputStream(bin); ObjectInputStream oin = new ObjectInputStream(bin);
field.set(object, oin.readObject()); field.set(object, oin.readObject());
} catch (Exception e) { } catch (Exception e) {
Log.warning("Failure decoding config value [type=" + Log.warning("Failure decoding config value [type=" + type +
type + ", field=" + field + ", exception=" + ", field=" + field + ", exception=" + e + "].");
e + "].");
} }
} else { } else {
Log.warning("Can't init field of unknown type " + Log.warning("Can't init field of unknown type " +
"[cobj=" + object.getClass().getName() + "[cobj=" + object.getClass().getName() + ", key=" + key +
", key=" + key +
", type=" + type.getName() + "]."); ", type=" + type.getName() + "].");
} }
} catch (IllegalAccessException iae) { } catch (IllegalAccessException iae) {
Log.warning("Can't set field " + Log.warning("Can't set field [cobj=" + object.getClass().getName() +
"[cobj=" + object.getClass().getName() +
", key=" + key + ", error=" + iae + "]."); ", key=" + key + ", error=" + iae + "].");
} }
} }
/** /**
* Converts a config object field name (someConfigMember) to a * Converts a config object field name (someConfigMember) to a configuration key
* configuration key (some_config_member). * (some_config_member).
*/ */
protected String nameToKey (String attributeName) protected String nameToKey (String attributeName)
{ {
@@ -322,8 +303,7 @@ public abstract class ConfigRegistry
} }
/** /**
* Get the specified attribute from the configuration object, and * Get the specified attribute from the configuration object, and serialize it.
* serialize it.
*/ */
protected void serializeAttribute (String attributeName) protected void serializeAttribute (String attributeName)
{ {
@@ -333,24 +313,21 @@ public abstract class ConfigRegistry
value = object.getAttribute(attributeName); value = object.getAttribute(attributeName);
} catch (ObjectAccessException oae) { } catch (ObjectAccessException oae) {
Log.warning("Exception getting field [name=" + attributeName + Log.warning("Exception getting field [name=" + attributeName +
"exception=" + oae + "]."); ", error=" + oae + "].");
return; return;
} }
if (value instanceof Streamable) { if (value instanceof Streamable) {
serialize(key, value); serialize(key, value);
} else { } else {
Log.info("Unable to flush config object change " + Log.info("Unable to flush config obj change [cobj=" + object.getClass().getName() +
"[cobj=" + object.getClass().getName() + ", key=" + key + ", type=" + value.getClass().getName() +
", key=" + key +
", type=" + value.getClass().getName() +
", value=" + value + "]."); ", value=" + value + "].");
} }
} }
/** /**
* Save the specified object as serialized data associated with * Save the specified object as serialized data associated with the specified key.
* the specified key.
*/ */
protected void serialize (String key, Object value) protected void serialize (String key, Object value)
{ {
@@ -389,6 +366,5 @@ public abstract class ConfigRegistry
} }
/** A mapping from identifying key to config object. */ /** A mapping from identifying key to config object. */
protected HashMap<String,ObjectRecord> _configs = protected HashMap<String,ObjectRecord> _configs = new HashMap<String,ObjectRecord>();
new HashMap<String,ObjectRecord>();
} }
@@ -72,7 +72,7 @@ public class DatabaseConfigRegistry extends ConfigRegistry
_node = StringUtil.isBlank(node) ? "" : node; _node = StringUtil.isBlank(node) ? "" : node;
} }
// documentation inherited @Override // from ConfigRegistry
protected ObjectRecord createObjectRecord (String path, DObject object) protected ObjectRecord createObjectRecord (String path, DObject object)
{ {
return new DatabaseObjectRecord(path, object); return new DatabaseObjectRecord(path, object);
@@ -25,13 +25,12 @@ import com.samskivert.util.PrefsConfig;
import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.DObject;
/** /**
* Implements the {@link ConfigRegistry} using the Java preferences system as a * Implements the {@link ConfigRegistry} using the Java preferences system as a persistent store
* persistent store for the configuration information (see {@link Config} for * for the configuration information (see {@link Config} for more information on how that works).
* more information on how that works).
*/ */
public class PrefsConfigRegistry extends ConfigRegistry public class PrefsConfigRegistry extends ConfigRegistry
{ {
// documentation inherited @Override // from ConfigRegistry
protected ObjectRecord createObjectRecord (String path, DObject object) protected ObjectRecord createObjectRecord (String path, DObject object)
{ {
return new PrefsObjectRecord(path, object); return new PrefsObjectRecord(path, object);