[Zope-CMF] (DC)WorkflowTool / CatalogTool suggestion

Big Sebastien.Bigaret@inqual.com
23 Sep 2001 18:35:11 +0200


I wrote:
> [snip] However, wouldn't it be nice if DCWorkflow-instances automagically
> add these 'available-to-catalog-variables' to catalog indexes (and possibly
> metadatas, for state variable e.g.) ?

Since I am curious and again, despite the fact that I miss some experience and
background in CMF zen, I tried to make a few changes in a proof-of-concept
way. I'd like to share that with you, just to make myself clearer and, for
sure, hoping to get feedbacks on some of my assertions and thoughts which are
those of a newbie!

You will find those changes at the end of this mail, in the form of a
diff to apply to (CVS Head) DCWorkflow.py.

  Now I'd like to make some comments about it.

1. First, do not apply and use 'as is' on a working CMF site... You may
   encounter difficulties (haaa, disclaimers...)

2. it simply adds manage_afterAdd and manage_beforeDelete methods, which in
   turn respectively adds/removes appropriate indexes ('FieldIndex' --
   hard-coded here) in portal_catalog

3. Adds a more general getCatalogVariables() method to DCWorkflow

As I said earlier this is more a 'proof-of-concept' approach then anything
else, so I really tried hard not to make any changes anywhere but in one file,
DCWorkflow.py. However, if such an approach were to be followed, it would
imply some changes. Next are those I detected, along with some more general
questions about the tools:

CatalogTool:
------------
a. modify CatalogTool so that enumerateIndexes() and -possibly-
   enumerateColumns() do not return a hard-coded tuple anymore
   BTW: this surprises me, since portal_catalog wraps a ZCatalog whose
   properties (indexes, metadas etc.) are modifiable through the classic
   ZCatalog ZMI. What is the reason for enumerate...() to return these
   hard-coded sequences?

   To tell this an other way: if these 2 methods holds the minimal set of
   indexes/columns required by CMF tools (my guess!), why not wrap
   add/delIndex/column() too, just to make sure these minimal requirements are
   respected?

b. maybe add add/delIndex() and add/delColumn() to the CatalogTool interface?
   I fell kinda uncomfortable using the ZCatalog interface, not the
   portal_catalog one...

c. ...same for ZCatalog.manage_catalogReindex()? [BTW and OT: why does this
   method requires REQUEST, RESPONSE and URL1?]

Variables:
----------
d. a trigger in setProperties() so that portal_catalog is kept in sync
e. maybe also modify TTW-UI so that variables are named 'workflow_...' by
   default ; so, one could avoid a name collision and thus a delIndex() on some
   useful variables (or worse: if you have a CMFCore wf instance and a DCWF
   instance, both of which use 'review_state' as the state variable, you'll
   get in trouble if not careful...)
f. I guess it would also make Variables' UI change in a way that one could
   indicate whether a variable available to catalog would be a Field, Text...
   (that would also imply 'for_catalog' attribute not to be directly
    available, only through getters/setters --setters in which one would place
    a trigger similar to point d., plus method getIndexTypeFor() etc.)


  Am I completely on a wrong way? I'd really appreciate comments about this
  from you cmf-zen-aware people!

     Sincerely yours,
                        SB aka Big.


[The following was only tested w/ Zope2.3.3]
-- 
Index: DCWorkflow.py
===================================================================
RCS file: /cvs-repository/Products/DCWorkflow/DCWorkflow.py,v
retrieving revision 1.6
diff -r1.6 DCWorkflow.py
102c102
< from Acquisition import aq_inner, aq_parent
---
> from Acquisition import aq_inner, aq_parent, aq_base
605a606,673
>     security.declarePrivate('getCatalogVariables')
>     def getCatalogVariables(self):
>         '''
>         Allows this workflow to make workflow-specific variables
>         automagically available to the catalog, making it possible
>         to implement worklists in a simple way.
>         Returns a sequence containing all possible catalog variables
>         See also: getCatalogVariables(self, ob)
>         '''
>         res = []
>         for id, vdef in self.variables.items():
>             if vdef.for_catalog:
>                 res.append(id)
>         # Always provide the state variable.
>         state_var = self.state_var
>         res.append(state_var)
>         return tuple(res)
> 
>     def manage_afterAdd(self, item, container):
>         '''
>         Automatically registers new catalog-available variables to the
>         portal_catalog
>         '''
>         catalog = getToolByName(self, 'portal_catalog')
>         # Taken from CatalogTool
>         catalogbase = aq_base(catalog)
>         if hasattr(catalogbase, 'addIndex'):
>             addIndex = catalog.addIndex # Zope 2.4
>         else:
>             addIndex = catalog._catalog.addIndex # Zope 2.3 and below
>         # Add indexes (and metadatas?)
>         for cvar in self.getCatalogVariables():
>             addIndex(cvar, 'FieldIndex') # FieldIdx for testing purposes
>             # addColumn?
> 
>     def manage_beforeDelete(self, item, container):
>         '''
>         Automatically removes catalog-available variables when no DCWorkflow
>         instance needs them anymore.
>         '''
>         # get catalog variables from other workflow instances
>         workflowTool = getToolByName(self, 'portal_workflow')
>         workflows = list(workflowTool.getWorkflowIds())
>         workflows.remove(self.getId()) # all but self
>         cvars_used = ()
>         for wf in workflows:
>             wf=workflowTool.getWorkflowById(wf)
>             if hasattr(aq_base(wf), 'getCatalogVariables'):
>                 # DCWorkflow instance
>                 cvars_used=cvars_used+wf.getCatalogVariables()
>         cvars_to_remove=list(self.getCatalogVariables())
>         for _cvu in cvars_used:
>             if _cvu in cvars_to_remove:
>                 # don't remove a variable still used by an other instance
>                 cvars_to_remove.remove(_cvu)
>                 
>         # Time to get rid of those unneeded catalog variables
>         catalog = getToolByName(self, 'portal_catalog')
>         # Inspired from CatalogTool
>         catalogbase = aq_base(catalog)
>         if hasattr(catalogbase, 'delIndex'):
>             delIndex = catalog.delIndex # Zope 2.4
>         else:
>             delIndex = catalog._catalog.delIndex # Zope 2.3 and below
>         for _cv in cvars_to_remove:
>             delIndex(_cv)
>         # At last: catalog: catalogReindex if applicable ??
>         #