Zope Component Architecture
ZCA is one of the most important systems on which GroupServer is built. ZCA is involved in defining classes that can be used by other code in GroupServer (i.e. components) by declaring a component name and corresponding class in through registration (usually configure.zcml). ZCA also has an events framework.
A couple of comprehensive references are mentioned/linked to below. It is worthwhile to skim them, especially parts that describe how the component architecture works. Below the References section you will find info on specific parts of the component architecture that serves as a quick reference.
Comprehensive online reference about ZCA - Recommend sections for reading:
- 1.1 - Introduction to ZCA
- 2 - Example of using ZCA (if unfamaliar with OO and/or the adapter pattern)
- 3 - Interfaces (keeping in mind that zope.schema is used in place of Attribute and invariants in GroupServer)
- 4 - Adapters
- 5 - Utilities
- 7.1 - ZCML
Other useful sections:
- 6 - Issuing and handling events (haven’t yet seen this come up in GroupServer, but its probably in there somewhere)
- 9 - API of ZCA.
There is also lengthy documentation in the EGG-INFO/PKG-INFO of each of the three packages that make up ZCA:
In addition, zope.schema augments zope.interface (specifically attribute declaration), and its EGG-INFO/PKG-INFO is also worth a read.
Adapters can be registered. They can be registered as global components via Python using zope.component.globalSiteManager (or getGlobalSiteManager()). They can be registered via configure.zcml. They can also be registered as local components via ZMI’s adapter element. Older ways to register these start with provide and can be seen in some parts of GroupServer. Once an adapter is registered, it can be retrieved using the getAdapter(<adaptee>, <interface>, <name>) or queryAdapter(<adaptee>, <interface>, <name>) functions of zope.component. If the adapter is registered without a name, it can also be invoked by calling the desired interface with the assignee as an argument, i.e. IPet(dog).
Utilities can be registered and retrieved in a similar manner to Adapters. In this case, you are registering an instance that provides a specified interface, making that instance (and all of its attributes/methods) available to the rest of the site.
These are a special case of Utilities. zope.component.factory.Factory(<class-name>, ‘<title>’) creates a Factory object (which is an implementation of the IFactory interface) that creates instances of class-name and has a title. This can be registered using zope.component.globalsitemanager.registerUtility(<instance>, IFactory, <‘factory-name’>, args), and can be retrieved either by zope.component.get/queryUtility(IFactory, <’factory-name’>) or zope.component.createObject(<’factory-name’>, args)
Schemas add a bit of control to the declaration of interface attributes. Namely, by using a schema, an interface author can mark an attribute as required, set a default value, and create a validator.