[Zope3-dev] simplifying ZCML by adding properties plus other ideas

Sam Stainsby sam at stainsby.id.au
Sat Apr 22 23:37:55 EDT 2006


Hi all,

I have read the "Reducing the amount of ZCML directives" proposal
with some interest and general agreement, although as a relative Zope 3
newbie I haven't used the full range of directives yet. The
deprecation of this confusing markup:

<vocabulary
    name="SD6 Agents"
    factory="zope.app.component.vocabulary.UtilityVocabulary"
    interface="alias.interfaces.ISD6Agent"
/>

with this clearer approach:

<utility
   component="alias.SD6AgentsVocabulary"
   provides="zope.app.schema.vocabulary.IVocabularyFactory"
   name="alias.SD6Agents"
/>

class SD6AgentsVocabulary(UtilityVocabulary?):
    classImplements(IVocabularyFactory?)
    interface = alias.interfaces.ISD6Agent

led me to think of a possibly better solution. The ability to pass
configuration to utilities in ZCML would be very useful and would avoid
lots of extra code if it could be generalised. Coincidentally, a
couple of years ago, I wrote a component framework in Java called JChassis
that is in many respects similar to Zope 3, although it targeted much
smaller non-web applications (and could in fact run on Java 2 Micro
Edition!). In it, 'services' could be configured thus:

<instance>
  <interface>MyService</interface>
  <implementation>MyServiceImpl</implementation>
  <property>
    <name>myProperty</name><value>ABC123</value>
  </property>
</instance>

for a simple string-valued 'myProperty' property. This would call a
setMyProperty method with the value (a classic JavaBeans pattern). There
is also markup to add properties of other basic types such as integers,
booleans, floats, arrays of basic types, etc. .. e.g. type="boolean". The
XML style used in JChassis is a bit different from what Zope 3 uses, but I
would envisage something like this:

<utility
    component="zope.app.component.vocabulary.UtilityVocabulary"
    provides="zope.app.schema.vocabulary.IVocabularyFactory"
    name="alias.SD6Agents">
  <property
      name="interface"
      type="class"
      value="alias.interfaces.ISD6Agent"/>
</utility>

resulting in the ISD6Agent class being resolved (because of its 'type')
and set as the 'interface' property on the UtilityVocabulary instance (I
assume it has such a property). This notation leaves no confusion about
the role of 'interface' here.

Such a general approach would have many other applications as a very
clear and quick way to get configuration into utilities, without having to
do custom extensions to the DTD. Of course if the properties expect values
other than the allowed basic types, then this type of configuration is not
usable.

There is a lot more info on what JChassis can do here:
http://jchassis.sourceforge.net/doc/user_guide/user_guide.html
which might be a source of ideas. Note that the project hasn't been
worked on for quite a while, and the ideas haven't really been tested out
in a serious application. The DTD for service configuration is truly
microscopic:
http://cvs.sourceforge.net/viewcvs.py/jchassis/v1/modules/jc_basic/src/org/jchassis/services/xml/0.1/

There is also a lot of functionality in JChassis for packaging "modules"
which might be of interest to those involved in eggification - there is an
XML DTD for defining complex dependencies and versioning, and the ability
to declare module dependencies on other modules, and even dependencies on
interfaces:
http://cvs.sourceforge.net/viewcvs.py/jchassis/v1/modules/jc_module/src/org/jchassis/module/xml/0.1/
I might do a separate post on that at some stage.

And yes, JChassis even has contexts an acquisition too! No concept like
Zope 3 multi-adapators though. I like those ...

--Sam.








More information about the Zope3-dev mailing list