[TransWarp] Requirements/use cases for configuration properties and files
Phillip J. Eby
pje at telecommunity.com
Fri Oct 4 14:56:01 EDT 2002
Comments and questions welcome... This is more or less the plan for
expanding the current peak.config package to support actual configuration
properties and config files.
Configuration Properties:
* Get a property for an object (e.g. config.getProperty(obj,
'dotted.property.name') )
* Bind an attribute to a property (e.g. foo =
binding.bindProperty('dotted.name'))
* Acquire properties contextually, where a property set on some component
implies that setting exists for child components unless overridden closer
to the child. (Implies the need for localizable property maps)
* Define lazy "rules" to specify the default value of a property, which
will be passed the target object and property name in order to compute a
value if no value is otherwise defined. Rules should be able to return a
special value (e.g. NOT_FOUND) to indicate that the search for a property
should continue.
* Set or override global, application-specific properties at startup
(implies a global property map; API =
config.setGlobalProperty('property.name', value) )
* Set or override global, package-specific rules for default properties at
startup (implies a global rules map; API =
config.setGlobalRule('property.name', ruleObj)
* Set application-specific rules for default properties on a LocalConfig
object (implies local rule maps; API = config.setRuleFor(obj,
'property.name', ruleObj))
* Set task-specific properties on a LocalConfig object (presumably using a
local property map; config.setPropertyFor(obj, 'property.name', value) )
Configuration Files:
* Load application-specific configuration files at end of "global" startup
* Load task/object-specific configuration files upon first use
* "Include" a configuration file from another, to provide defaults (e.g
site-wide vs. app-specific)
* Syntax checking: an error should occur for redefinition of a property
within the same configuration file
* Different types of configuration files, supplying either properties or
rules for deriving properties (e.g "style sheets")
* At least one file format should include support for Python expressions
======= Design notes ========
The above seems to imply we need some type of PropertyMap utility which
supports having both rules and values. When asked for a property, a
PropertyMap searches its values and rules, then falls through to any
subordinate (e.g. more global) PropertyMaps if a result can't be
found. Both the GlobalConfig and LocalConfig objects should supply
PropertyMaps by default; other objects could be supplied them on an
individualized basis.
Configuration files and other data sources could be parsed to set either
values or rules, according to their format.
Custom IPropertyMap implementations could use more exotic means of
computation, such as path-based or stylesheet-like rules. The basic
property map might even allow wildcard rules, e.g. "environ.*" might be
mapped to a rule that looks for an environment value. This would allow
delayed computation of certain configuration namespaces. E.g. a
configuration file might be mapped to a particular property namespace.
Ensuring immutability might be tricky, however. Presumably, rules will
have to guarantee that they will always produce the same value for a given
property name/object pair. The map can guarantee that the same rule will
always be used for a given property, however. Once a wildcard rule is
found, it can be copied to the cell for the target property, and locked
after the rule has been executed.
Locking after running the rule would allow the rule to "bootstrap" a more
specific rule after first performing a computation. For example, lazy
loading of configuration files could be done with wildcard loaders that
in-load all of their rules to the same (or more specific) configuration
map, then doing a recursive getProperty() lookup for the same property,
causing the newly loaded (more-specific) rule to be fired. Thus, the
default rule for property "*" could load the global configuration files as
soon as a property was needed for which no default existed.
Downside to that concept: most properties will have global default rules,
which means there isn't a good automatic "triggering point" to load
them. A fix is straightforward, but possibly tedious: make the default
rules check for one or more, *differently-named* properties (which will
trigger the configuration file loads) before falling back to an actual
default value. This might be as simple as prefixing the property
namespace. For example, if one has a property,
"peak.naming.urlpackageprefixes", then the *configuration* of that property
might actually be in "config.peak.naming.urlpackageprefixes". The package
that uses the variable would create a rule for the unprefixed property
name, that checks for the prefixed property name before falling back to a
default value. A "config.*" property rule which loaded the global
configuration files would then do the trick.
Note that this same namespace could work for both the local and global
configs: even if a system property lookup falls through to the global map,
the default rule begins the lookup again at the local level, so the local's
"config.*" rule kicks in, loading the local configuration files and giving
them a chance to supply the value before falling back to the global level's
config files.
If configuration files can specify a rule that points to another
configuration file or a portion thereof as a "wildcard" rule, then it's
also possible to implement configuration "inheritance" or "includes",
causing undefined items in a namespace to be "inherited" from the other
configuration file. This could be as simple as allowing the same sort of
"fallback to another namespace" rule as is needed for system->config
properties.
Also, "rewrite rules" like these could be supplied "close" to a component,
where say, a "wxpython.bgcolor" property might be mapped to come from
"myapp.widgetstyles.foo.background". Thus allowing a transformation from
properties needed by a framework, to properties defined by an application.
More information about the PEAK
mailing list