[Erp5-report] r30010 - in /erp5/trunk/products: ERP5/ ERP5Type/ ERP5Type/dtml/ ERP5Type/pat...
nobody at svn.erp5.org
nobody at svn.erp5.org
Mon Oct 26 17:34:03 CET 2009
Author: leonardo
Date: Mon Oct 26 17:34:00 2009
New Revision: 30010
URL: http://svn.erp5.org?rev=30010&view=rev
Log:
Create a new ERP5Type/Workflow.py file to house all changes needed as we progressively remove DCWorkflow dependencies. For now it contains the non-patches part of patches/DCWorkflow.py and a conditional replacement for addWorkflowFactory() function that disappeared on CMF 2. Adjust other import locations to point to this function. Adjust ERP5Type product initialization to register Zope2-style factories for workflows registered with the substitute addWorkflowFactory when on CMF2 (approved by jm and jerome)
Added:
erp5/trunk/products/ERP5Type/Workflow.py
erp5/trunk/products/ERP5Type/dtml/addWorkflow.dtml
Modified:
erp5/trunk/products/ERP5/InteractionWorkflow.py
erp5/trunk/products/ERP5Type/__init__.py
erp5/trunk/products/ERP5Type/patches/DCWorkflow.py
Modified: erp5/trunk/products/ERP5/InteractionWorkflow.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/InteractionWorkflow.py?rev=30010&r1=30009&r2=30010&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/InteractionWorkflow.py [utf8] (original)
+++ erp5/trunk/products/ERP5/InteractionWorkflow.py [utf8] Mon Oct 26 17:34:00 2009
@@ -26,7 +26,7 @@
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
from Products.DCWorkflow.Transitions import TRIGGER_WORKFLOW_METHOD
from Products.DCWorkflow.Expression import StateChangeInfo, createExprContext
-from Products.ERP5Type.patches.DCWorkflow import addWorkflowFactory
+from Products.ERP5Type.Workflow import addWorkflowFactory
from Products.CMFActivity.ActiveObject import ActiveObject
from Products.ERP5Type import Permissions
Added: erp5/trunk/products/ERP5Type/Workflow.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Workflow.py?rev=30010&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Type/Workflow.py (added)
+++ erp5/trunk/products/ERP5Type/Workflow.py [utf8] Mon Oct 26 17:34:00 2009
@@ -1,0 +1,205 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2002 Nexedi SA and Contributors. All Rights Reserved.
+# Jean-Paul Smets-Solanes <jp at nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import zLOG
+from Products.ERP5Type import Permissions
+from App.special_dtml import HTMLFile
+from Acquisition import aq_inner
+from AccessControl.requestmethod import postonly
+from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
+
+# ERP5 workflow factory definitions
+_workflow_factories = {}
+
+try:
+ from Products.CMFCore.WorkflowTool import addWorkflowFactory
+ # We're on CMF 1.5
+except ImportError:
+ # We're on CMF 2
+ zLOG.LOG('Products.ERP5Type.Workflow.addWorkflowFactory',
+ zLOG.INFO,
+ summary='Registering Workflow Factories Directly',
+ detail='Products.CMFCore.WorkflowTool.addWorkflowFactory has '
+ 'been removed from CMFCore. Workflows will be registered as '
+ 'Zope 2 style factories instead.')
+ def addWorkflowFactory(factory, id, title):
+ """addWorkflowFactory replacement
+
+ addWorkflowFactory has been removed from CMFCore 2.x.
+ DCWorkflow, which now handles this job, consults the GenericSetup tool,
+ at runtime, to determine all valid workflows.
+
+ Instead of providing xml files in GenericSetup profiles for our,
+ workflows we prepare our own Zope2 style factories for registration
+ in the Workflow Tool.
+ """
+ assert not _workflow_factories.get(id), (
+ 'Workflow with id %r already exists.' % id)
+
+ factory_info = dict(factory=factory,
+ id=id,
+ title=title)
+ _workflow_factories[id] = factory_info
+
+# Workflow Creation DTML
+manage_addWorkflowFormDtml = HTMLFile('dtml/addWorkflow', globals())
+
+def _generateWorkflowConstructors(factory_info):
+ """ Generate a "manage_addWorkflow_?" and "manage_addWorkflowForm_?" methods
+ specific for each workflow factory. """
+
+ FACTORY_FORM_PREFIX = 'addWorkflowForm_'
+ FACTORY_ACTION_PREFIX = 'addWorkflow_'
+
+ workflow_factory_id = factory_info['id']
+ workflow_factory_title = factory_info['title']
+ # the method names (last url segments)
+ constructor_form_name=FACTORY_FORM_PREFIX + workflow_factory_id
+ constructor_action_name=FACTORY_ACTION_PREFIX + workflow_factory_id
+
+ # The form
+ def manage_addWorkflowForm(dispatcher, REQUEST, RESPONSE):
+ """Form to add a type-specific workflow to portal_workflow"""
+ kw = dict(workflow_factory_title=workflow_factory_title,
+ form_action=constructor_action_name)
+ return manage_addWorkflowFormDtml(None, dispatcher, REQUEST, **kw)
+
+ # The action of the form
+ @postonly
+ def manage_addWorkflow(dispatcher, workflow_id, REQUEST=None):
+ """Add a type specific workflow with object-id as 'workflow_id'
+ """
+ # we could have just used the factory from factory_info here, but we use
+ # addWorkflowByType to exercise it.
+ addWorkflowByType(dispatcher, workflow_factory_id, workflow_id)
+ if REQUEST is not None:
+ return REQUEST.response.redirect(dispatcher.DestinationURL() +
+ "/manage_main")
+ return workflow
+
+ # The constructors
+ constructors = [(constructor_form_name, manage_addWorkflowForm),
+ (constructor_action_name, manage_addWorkflow)]
+ return constructors
+
+def addWorkflowByType(container, workflow_factory_id, workflow_id):
+ """ Add a workflow with name 'workflow_id' from factory identified by
+ 'workflow_factory_id'
+ """
+ # This functionality could be inside the generated manage_addWorkflow above,
+ # but is placed here to be easily used directly from Python code.
+ workflow_factory = _workflow_factories[workflow_factory_id]['factory']
+ workflow = workflow_factory(workflow_id)
+ container._setObject(workflow_id, workflow)
+ return aq_inner(container.restrictedTraverse(workflow_id))
+
+def registerWorkflowFactory(context, factory_info):
+ """ Register a workflow factory as a Zope2 style object factory that is only
+ addable to portal_workflow"""
+ constructors = _generateWorkflowConstructors(factory_info)
+ permission = Permissions.ManagePortal
+ context.registerClass(DCWorkflowDefinition, # this class is only used here for its interfaces
+ meta_type=factory_info['title'],
+ constructors=constructors,
+ permission=permission,
+ visibility=None)
+
+def registerAllWorkflowFactories(context):
+ """register workflow factories during product initialization
+ """
+ # the loop below will be empty on CMF 1.5, as the original addworkflowFactory
+ # from CMF will not populate this WORKFLOW_FACTORIES dictionary.
+ for factory_info in _workflow_factories.itervalues():
+ registerWorkflowFactory(context, factory_info)
+
+# Add a workflow factory for ERP5 style workflow, because some variables
+# are needed for History tab.
+def setupERP5Workflow(wf):
+ """Sets up an DC Workflow with defaults variables needed by ERP5.
+ """
+ wf.setProperties(title='ERP5 default workflow')
+ for s in ('draft',):
+ wf.states.addState(s)
+ for v in ('action', 'actor', 'comment', 'history', 'time',
+ 'error_message', 'portal_type'):
+ wf.variables.addVariable(v)
+ for perm in (Permissions.AccessContentsInformation,
+ Permissions.View,
+ Permissions.AddPortalContent,
+ Permissions.ModifyPortalContent,
+ Permissions.DeleteObjects):
+ wf.addManagedPermission(perm)
+
+ wf.states.setInitialState('draft')
+ # set by default the state variable to simulation_state.
+ # anyway, a default workflow needs to be configured.
+ wf.variables.setStateVar('simulation_state')
+
+ vdef = wf.variables['action']
+ vdef.setProperties(description='The last transition',
+ default_expr='transition/getId|nothing',
+ for_status=1, update_always=1)
+
+ vdef = wf.variables['actor']
+ vdef.setProperties(description='The name of the user who performed '
+ 'the last transition',
+ default_expr='user/getUserName',
+ for_status=1, update_always=1)
+
+ vdef = wf.variables['comment']
+ vdef.setProperties(description='Comments about the last transition',
+ default_expr="python:state_change.kwargs.get('comment', '')",
+ for_status=1, update_always=1)
+
+ vdef = wf.variables['history']
+ vdef.setProperties(description='Provides access to workflow history',
+ default_expr="state_change/getHistory")
+
+ vdef = wf.variables['time']
+ vdef.setProperties(description='Time of the last transition',
+ default_expr="state_change/getDateTime",
+ for_status=1, update_always=1)
+
+ vdef = wf.variables['error_message']
+ vdef.setProperties(description='Error message if validation failed',
+ for_status=1, update_always=1)
+
+ vdef = wf.variables['portal_type']
+ vdef.setProperties(description='portal type (use as filter for worklists)',
+ for_catalog=1)
+
+def createERP5Workflow(id):
+ """Creates an ERP5 Workflow """
+ ob = DCWorkflowDefinition(id)
+ setupERP5Workflow(ob)
+ return ob
+
+addWorkflowFactory(createERP5Workflow,
+ id='erp5_workflow',
+ title='ERP5-style empty workflow')
Modified: erp5/trunk/products/ERP5Type/__init__.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/__init__.py?rev=30010&r1=30009&r2=30010&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/__init__.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/__init__.py [utf8] Mon Oct 26 17:34:00 2009
@@ -55,6 +55,9 @@
# production environment
class_tool_security_path = '%s%s%s' % (product_path, os.sep, 'ALLOW_CLASS_TOOL')
+# allow our workflow definitions to be registered
+import Products.ERP5Type.Workflow
+
def allowClassTool():
return os.access(class_tool_security_path, os.F_OK)
@@ -84,6 +87,8 @@
portal_tools = portal_tools,
content_constructors = content_constructors,
content_classes = content_classes)
+ # Register our Workflow factories directly (if on CMF 2)
+ Products.ERP5Type.Workflow.registerAllWorkflowFactories(context)
# We should register local constraints at some point
from Products.ERP5Type.Utils import initializeLocalConstraintRegistry
initializeLocalConstraintRegistry()
Added: erp5/trunk/products/ERP5Type/dtml/addWorkflow.dtml
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/dtml/addWorkflow.dtml?rev=30010&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Type/dtml/addWorkflow.dtml (added)
+++ erp5/trunk/products/ERP5Type/dtml/addWorkflow.dtml [utf8] Mon Oct 26 17:34:00 2009
@@ -1,0 +1,31 @@
+<dtml-let form_title="'Add ' + workflow_factory_title" BASEPATH1="BASE1">
+<dtml-var manage_page_header>
+<dtml-var manage_form_title>
+</dtml-let>
+
+<form action="&dtml-form_action;" method="POST">
+<table cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="workflow_id" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ </td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <input class="form-element" type="submit" name="submit"
+ value=" Add " />
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+
+<dtml-var manage_page_footer>
Modified: erp5/trunk/products/ERP5Type/patches/DCWorkflow.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/patches/DCWorkflow.py?rev=30010&r1=30009&r2=30010&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/patches/DCWorkflow.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/patches/DCWorkflow.py [utf8] Mon Oct 26 17:34:00 2009
@@ -608,94 +608,3 @@
TransitionDefinition.getAvailableScriptIds = getAvailableScriptIds
-# Add a workflow factory for ERP5 style workflow, because some variables
-# are needed for History tab.
-
-try:
- from Products.CMFCore.WorkflowTool import addWorkflowFactory
-except ImportError:
- def addWorkflowFactory(factory, id, title):
- """addWorkflowFactory replacement
-
- addWorkflowFactory has been removed from CMF 2.x.
- DCWorkflow, which actually handled the workflows added by this function
- now consults the GenericSetup tool, at runtime to determine all valid
- workflows.
-
- Instead of providing GenericSetup profiles for our workflows, we
- install our own Zope2 style factories for the Workflow Tool
- """
- import zLOG
- zLOG.LOG('Products.ERP5Type.patches.DCWorkflow.addWorkflowFactory',
- zLOG.ERROR,
- summary='Workflow Factory not registered',
- detail='Products.CMFCore.WorkflowTool.addWorkflowFactory has '
- 'been removed from CMFCore, and a replacement has not been '
- 'written yet. ERP5 Workflow factory for '
- '%s (%s) not installed.' % (id, title))
-
-from Products.ERP5Type import Permissions
-
-def setupERP5Workflow(wf):
- """Sets up an DC Workflow with defaults variables needed by ERP5.
- """
- wf.setProperties(title='ERP5 default workflow')
- for s in ('draft',):
- wf.states.addState(s)
- for v in ('action', 'actor', 'comment', 'history', 'time',
- 'error_message', 'portal_type'):
- wf.variables.addVariable(v)
- for perm in (Permissions.AccessContentsInformation,
- Permissions.View,
- Permissions.AddPortalContent,
- Permissions.ModifyPortalContent,
- Permissions.DeleteObjects):
- wf.addManagedPermission(perm)
-
- wf.states.setInitialState('draft')
- # set by default the state variable to simulation_state.
- # anyway, a default workflow needs to be configured.
- wf.variables.setStateVar('simulation_state')
-
- vdef = wf.variables['action']
- vdef.setProperties(description='The last transition',
- default_expr='transition/getId|nothing',
- for_status=1, update_always=1)
-
- vdef = wf.variables['actor']
- vdef.setProperties(description='The name of the user who performed '
- 'the last transition',
- default_expr='user/getUserName',
- for_status=1, update_always=1)
-
- vdef = wf.variables['comment']
- vdef.setProperties(description='Comments about the last transition',
- default_expr="python:state_change.kwargs.get('comment', '')",
- for_status=1, update_always=1)
-
- vdef = wf.variables['history']
- vdef.setProperties(description='Provides access to workflow history',
- default_expr="state_change/getHistory")
-
- vdef = wf.variables['time']
- vdef.setProperties(description='Time of the last transition',
- default_expr="state_change/getDateTime",
- for_status=1, update_always=1)
-
- vdef = wf.variables['error_message']
- vdef.setProperties(description='Error message if validation failed',
- for_status=1, update_always=1)
-
- vdef = wf.variables['portal_type']
- vdef.setProperties(description='portal type (use as filter for worklists)',
- for_catalog=1)
-
-def createERP5Workflow(id):
- """Creates an ERP5 Workflow """
- ob = DCWorkflowDefinition(id)
- setupERP5Workflow(ob)
- return ob
-
-addWorkflowFactory(createERP5Workflow,
- id='erp5_workflow',
- title='ERP5-style empty workflow')
More information about the Erp5-report
mailing list