[PEAK] ZConfig question

Phillip J. Eby pje at telecommunity.com
Tue Jul 27 12:25:01 EDT 2004


At 01:50 PM 7/27/04 +0200, Roché Compaan wrote:
>How do I do I the following in a peak ini file:
>
>SCHEMA = "/home/roche/work/jack/schema.xml"
>config_file_name = "/home/roche/work/jack/jack.conf"
>
>schema = ZConfig.loadSchema(SCHEMA)
>cfg, nil = ZConfig.loadConfig(schema, config_file_name)
>
>In other words, how do I load the schema file, parse the config file 
>and  assign the output to a configuration root?

The recommended approach:

     #!peak runIni

     [peak.naming.factories]
     myapp.schema = naming.Reference(
         'zconfig.schema', ['file:///home/roche/work/jack/schema.xml'])

     [peak.running]
     app = naming.Reference('myapp.schema', 
['file:///home/roche/work/jack.conf'])


Then, './myapp.ini' will attempt to invoke the root object of the ZConfig file.

'naming.Reference' takes a factory name and a list of addresses.  The 
factory name refers to either an entry in 'peak.naming.factories', or if it 
doesn't exist there, an object/class to be imported.  'zconfig.schema' is a 
predefined factory that loads ZConfig schemas, which are then usable as 
factories themselves.

So what the above does is to first say, "when you have a Reference with a 
factory of 'myapp.schema', use this ZConfig schema to load it."  And then 
it says, "when somebody runs this .ini file, use this reference to a file 
with a particular schema as the application object."

If you didn't want the config file root to become the application itself, 
you can of course use the 'naming.Reference' any place you would put the 
actual object in your .ini file.  For example, if you wanted the ZConfig 
object to be a named service (accessible via property name, but only one 
copy created/loaded per service area):

     [Named Services]
     myapp.config = naming.Reference('myapp.schema', 
['file:///home/roche/work/jack.conf'])


You can also use [Named Services] to define the factory, so that the schema 
will only be loaded once:

     [Named Services]
     peak.naming.factories.myapp.schema = naming.Reference(
         'zconfig.schema', ['file:///home/roche/work/jack/schema.xml'])


Finally, it should also be noted that instead of 'naming.Reference()', you 
can use 'ref:' URLs, as in:

     [Named Services]

     peak.naming.factories.myapp.schema = naming.LinkRef(
         'ref:zconfig.schema at file:///home/roche/work/jack/schema.xml')

     myapp.config = 
naming.LinkRef('ref:myapp.schema at file:///home/roche/work/jack.conf')


As you can see, though, this gains you little in this context, since you 
still need to create a LinkRef so the URL can be looked up.  But the URL 
syntax is handy for doing things like 
'self.lookupComponent("ref:myapp.schema at somewhere")' or 
'binding.Obtain("ref:myapp.schema at somewhere")'.

Incidentally, whether you use 'naming.Reference()' or the 'ref:' URL 
scheme, you can use other URL schemes besides 'file:' as addresses.  For 
example, you can use 'pkgfile', which lets you refer to a file contained 
inside a Python package directory, and you can even use http or ftp should 
you have the need.  In fact, you can use any peak.naming address that 
resolves to an object that can be adapted to 'naming.IStreamFactory', and 
it will be usable for loading ZConfig schemas and ZConfig configuration files.

Last, but not least, in case you want to create your own kinds of factories 
that can do this sort of thing, the interface you need to implement is 
'naming.IObjectFactory'.  One example of how to do this is found in the 
peak.config.load_zconfig module, but there are others elsewhere.




More information about the PEAK mailing list