[Zope3-dev] What are zope.generic, z3c, ldapauth, et.al.?

Dominik Huber dominik.huber at perse.ch
Fri Jul 7 06:14:10 EDT 2006


Excuse my abscence. I'm a little busy and cannot find the time to track 
the list daily.

Small summary of zope.generic:
it's a not-yet-fully-implemented, experimental prototype trying to find 
a high-level-usage pattern or framework for zope 3.

During the easter-sprint I decided to put the code into the zope 
repository. We came up with the name
zope.generic and Stephan told us it would be ok to put the stuff into a 
dotted-named top level package.

We are using this code within two customer projects. We like the main 
direction, but there is a lot stuff that has to be refactored (as usual)
and a lot of missing stuff that has to be implemented before we would 
announce anything. We plan the first alpha-release in december.

Regards,
Dominik

Target
------
The zope.generic package should provide a higher level abstraction or 
usage of the ca.
It should empower people with a analytical and technical background 
(none- or fun-programmer) use the zope infrastructure.
Therefore the abstraction should allow to configurate components using a 
generic logical pattern, to reuse features and a way to extend the 
functionality with simple python function without knowing a lot about 
the whole ca.
The behavior of those components (logical pattern) should be abstract, 
but highly derived from object-orientation too, because the target 
audience is pretty comfortable with that model (-> comparable 
abstraction would be ZClasses or object-oriented Requirement Analysis).
The application domain should be composed individually, that means 
people should declare their own domain types rather than using a fix 
domain types (-> cms application -> document, news, event, etc.)
The domain types itself should be composed using generic sub-component 
and features.
Those features should be developed and implemented orthogonal and 
generic manner. Such a feature implements technical functionalitiy. For 
example there might be a document feature. You can enable the document 
feature for a certain domain type. Afterward this domain type should 
provide the feature. A feature requires some configuration of the 
underlying domain type or an instance and it provides a certain api by 
adaption. This configuration aspect should be solved generically using a 
memento pattern.
Simplify by automation (-> provide a complementary option to phillips 
simplification-direction).

Design Goals
-------------
After the experiences with tiks. We decided to base the implementation 
heavily on a marker interface pattern. That means there are only a few 
generic base implementation (such as Object, Contained, Container, 
Folder,...) that can be decorated by domain-specific 
marker-interfaces.We decided to provide a mechanism that declares the 
most important interface (key interface -> keyface). This keyface is an 
equivalent to class. The keyface can be used to look up the 
corresponding configurations of a marked component. Those configurations 
can be annotated directly to the object itself or might be provided by a 
corresponding information providers (utilities) globally. We introduced 
a new memento-implemenation called configuration. This is similar to 
annotation but it is using configuration interfaces as keys instead of 
id-string. Those configuration interfaces allows us to introspect 
annonations more efficiently and to implement any configuration with a 
generic base implementation.

Example
---------

Step 1: Define your Key Interfaces: interfaces.py

class IMeasuringSystem(IWebApplication):
    """Mark the measuring system application."""

    contains('bopp.ms.measuringsystem.IProductionOrder')
    containers(IWebPlatform)

class IOrder(Interface):
    """Mark an abstract order of the measuring-system."""

class IProductionOrder(IOrder):
    """Mark a production order of the measuring-system."""

    contains('bopp.ms.measuringsystem.IProductionBatch')
    containers(IMeasuringSystem)

class IProductionBatch(IOrder):
    """Mark a production batch of production order."""

    containers(IProductionOrder)

Step 2: Define dedicated configuration interfaces if necessary: 
interfaces.py

class IMeasuringSystemConfiguration(Interface):
    """Input configuration of a messuringsystem."""

    data = TextLine(title=_(u'Data Directory'),
        description=_(u'Main data directory.'),
        required=True,
        constraint=os.path.isdir,
        max_length=255)

class IOrderConfiguration(Interface):
    """Abstract order."""

    aufnr = OrderID(title=_(u'Auftrag-Nr. (FAUF)'),
        description=_(u'Fertigungs-Auftrag-Nummer der Charge'))

class AnyBatchEvent(ObjectEvent):
    """Notify any batch event"""

Step 3: Implement dedicated handlers in python if necessary: app.py

orderConfiguration = {'aufnr': u'999999999'}

def setup(context, *pos, **kws):
    # make the folder to a site
    ensureSite(context)
    # add an int id utility
    ensureIntIds(context)
    ensureCatalog(context, IOrderConfiguration, 
name=toDottedName(IMeasuringSystem), key=u'Catalog')

def anyBatchEventHandler(context, *pos, **kws):
    # get a configuraiton
    config = IMeasuringSystemConfiguration(context)
    # do something

Step 4: Wire up the application domain:

  <generic:configuration
      keyface=".interfaces.IOrderConfiguration"
      />

 <! -- default value -->
  <generic:informationProvider
      keyface="interfaces.IMeasuringSystem"
      >
    <information
        keyface="binterfaces.IOrderConfiguration"
        configuration=".app.orderConfiguration"
        />
  </generic:informationProvider>

  <generic:content
      keyface=".interfaces. IProductionOrder"
      label=" Production Order" hint="n/a"
      >
    <factory
        class="zope.generic.content.api.Container"
        input=".app.IMeasuringSystemConfiguration"
        storeInput="True"
        />
    <adapter
        provides=".interfaces.IMeasuringSystemConfiguration"
        readPermission="zope.View"
        writePermission="zope.ManageContent"
        acquire="True"
        />
    <adapter
        provides=".interfaces.IOrderConfiguration"
        readPermission="zope.View"
        writePermission="zope.ManageContent"
        acquire="True"
        />
    <handler
        event="zope.app.container.interfaces.IObjectAddedEvent"
        operations=".app.setup"
        />
    <handler
        event=".interfaces.AnyBatchEvent"
        operations=".app.anyBatchHandler"
        />
  </generic:content>

  <generic:content
      keyface=".interfaces.IProductionOrder"
      label="Production Order" hint="n/a"
      >
    <factory
        class="zope.generic.content.api.Container"
        />
    <adapter
        provides="bopp.ms.measuringsystem.IOrderConfiguration"
        readPermission="zope.View"
        writePermission="zope.ManageContent"
        />
  </generic:content>

  <generic:content
      keyface=".interfaces.IProductionBatch"
      label="Production Batch" hint="n/a"
      >
    <factory
        class="zope.generic.content.api.Contained"
        />
    <adapter
        provides="bopp.ms.measuringsystem.IOrderConfiguration"
        readPermission="zope.View"
        writePermission="zope.ManageContent"
        />
  </generic:content>

Step 5: Use other zope 3 frame works for example the generic forms

  <browser:addform
      content_factory_id="example.interfaces.IMeasuringSystem"
      schema=".interfaces.IMeasuringSystemConfiguration"
      keyword_arguments="data"
      label="Add MeasuringSystem"
      permission="zope.ManageContent"
      name="addMeasuringSystem.html"
      />

  <browser:addMenuItem
      factory=".interfaces.IMeasuringSystem"
      title="Measuring System"
      permission="zope.ManageContent"
      view="addMeasuringSystem.html"
      />

  <browser:containerViews
      for=".interfaces.IMeasuringSystem"
      index="zope.ManageContent"
      add="zope.ManageContent"
      contents="zope.ManageContent"
      />

  <browser:editform
      name="edit.html"
      schema=".interfaces.IMeasuringSystemConfiguration"
      for=".interfaces.IMeasuringSystem"
      label="Configure the Measuring System"
      permission="zope.ManageContent"
      menu="zmi_views" title="Configuration"
      />

  <browser:addMenuItem
      factory="example.measuringsystem.IProductionOrder"
      title="Production Order"
      permission="zope.ManageContent"
      />

  <browser:containerViews
      for=".interfaces.IProductionOrder"
      index="zope.View"
      add="zope.ManageContent"
      contents="zope.ManageContent"
      />
   
  <browser:addMenuItem
      factory="example.interfaces.IProductionBatch"
      title="Production Batch"
      permission="zope.ManageContent"
      />

  <browser:editform
      name="order.html"
      schema="example.interfaces.IOrderConfiguration"
      for="example.interfaces.IOrder"
      label="Auftrags-Daten editieren"
      permission="zope.ManageContent"
      menu="zmi_views" title="Auftrag"
      />




More information about the Zope3-dev mailing list