Commit 915a2451 authored by iv's avatar iv

ERP5Workflow: PERF improve for loops

parent 08d28458
...@@ -95,9 +95,12 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow): ...@@ -95,9 +95,12 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow):
chained_ptype_list = [] chained_ptype_list = []
wf_tool = getToolByName(self, 'portal_workflow') wf_tool = getToolByName(self, 'portal_workflow')
types_tool = getToolByName(self, 'portal_types') types_tool = getToolByName(self, 'portal_types')
for ptype in types_tool.objectValues():
if self.getId() in ptype.getTypeWorkflowList(): interaction_workflow_id = self.getId()
chained_ptype_list.append(ptype.getId()) append = chained_ptype_list.append
for portal_type in types_tool.objectValues():
if interaction_workflow_id in portal_type.getTypeWorkflowList():
append(portal_type.getId())
return chained_ptype_list return chained_ptype_list
security.declarePrivate('listObjectActions') security.declarePrivate('listObjectActions')
...@@ -208,8 +211,9 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow): ...@@ -208,8 +211,9 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow):
security.declarePrivate('getTransitionIdList') security.declarePrivate('getTransitionIdList')
def getTransitionIdList(self): def getTransitionIdList(self):
id_list = [] id_list = []
append = id_list.append
for ob in self.objectValues(portal_type="Interaction"): for ob in self.objectValues(portal_type="Interaction"):
id_list.append(ob.getReference()) append(ob.getReference())
return id_list return id_list
security.declarePrivate('notifyWorkflowMethod') security.declarePrivate('notifyWorkflowMethod')
...@@ -229,11 +233,11 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow): ...@@ -229,11 +233,11 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow):
kw = kw.copy() kw = kw.copy()
kw['workflow_method_args'] = args kw['workflow_method_args'] = args
filtered_transition_list = [] filtered_transition_list = []
append = filtered_transition_list.append
for t_id in transition_list: for t_id in transition_list:
tdef = self._getOb('interaction_' + t_id ) tdef = self._getOb('interaction_' + t_id )
assert tdef.getTriggerType() == TRIGGER_WORKFLOW_METHOD assert tdef.getTriggerType() == TRIGGER_WORKFLOW_METHOD
filtered_transition_list.append(tdef.getId()) append(tdef.getId())
former_status = {} former_status = {}
sci = StateChangeInfo( sci = StateChangeInfo(
...@@ -259,6 +263,7 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow): ...@@ -259,6 +263,7 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow):
kw['workflow_method_args'] = args kw['workflow_method_args'] = args
kw['workflow_method_result'] = result kw['workflow_method_result'] = result
workflow_variable_list = self.objectValues(portal_type='Workflow Variable')
for t_id in transition_list: for t_id in transition_list:
tdef = self._getOb('interaction_' + t_id ) tdef = self._getOb('interaction_' + t_id )
assert tdef.getTriggerType() == TRIGGER_WORKFLOW_METHOD assert tdef.getTriggerType() == TRIGGER_WORKFLOW_METHOD
...@@ -271,7 +276,7 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow): ...@@ -271,7 +276,7 @@ class InteractionWorkflow(IdAsReferenceMixin("", "prefix"), Workflow):
if tdef_exprs is None: tdef_exprs = {} if tdef_exprs is None: tdef_exprs = {}
status = {} status = {}
for vdef in self.objectValues(portal_type='Workflow Variable'): for vdef in workflow_variable_list:
id = vdef.getId() id = vdef.getId()
if not vdef.getStatusIncluded(): if not vdef.getStatusIncluded():
continue continue
......
...@@ -124,10 +124,8 @@ class State(IdAsReferenceMixin("state_", "prefix"), XMLObject, CustomStorageMatr ...@@ -124,10 +124,8 @@ class State(IdAsReferenceMixin("state_", "prefix"), XMLObject, CustomStorageMatr
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getDestinationReferenceList') 'getDestinationReferenceList')
def getDestinationReferenceList(self): def getDestinationReferenceList(self):
ref_list = [] return [transition.getReference() for transition
for tr in self.getDestinationValueList(): in self.getDestinationValueList()]
ref_list.append(tr.getReference())
return ref_list
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getAvailableTypeList') 'getAvailableTypeList')
......
...@@ -209,32 +209,34 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -209,32 +209,34 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
def _checkTransitionGuard(self, transition, document, **kw): def _checkTransitionGuard(self, transition, document, **kw):
return transition.checkGuard(getSecurityManager(), self, document, **kw) return transition.checkGuard(getSecurityManager(), self, document, **kw)
def _findAutomaticTransition(self, document, sdef): def _findAutomaticTransition(self, document, state):
tdef = None transition = None
for t in sdef.getDestinationValueList(): checkTransitionGuard = self._checkTransitionGuard
if t.getTriggerType() == TRIGGER_AUTOMATIC: for possible_transition in state.getDestinationValueList():
if self._checkTransitionGuard(t, document): if possible_transition.getTriggerType() == TRIGGER_AUTOMATIC:
tdef = t if checkTransitionGuard(possible_transition, document):
transition = possible_transition
break break
return tdef return transition
security.declarePrivate('updateRoleMappingsFor') security.declarePrivate('updateRoleMappingsFor')
def updateRoleMappingsFor(self, document): def updateRoleMappingsFor(self, document):
""" """
Changes the object permissions according to the current state. Changes the object permissions according to the current state.
""" """
changed = 0 changed = False
state = self._getWorkflowStateOf(document, id_only=False) state = self._getWorkflowStateOf(document, id_only=False)
if state is not None: if state is not None:
state_permission_list = state.getAcquirePermissionList()
for permission, role_list in state.getStatePermissionRolesDict().items(): for permission, role_list in state.getStatePermissionRolesDict().items():
# tuple means "don't acquire" in zope internal security and list # tuple means "don't acquire" in zope internal security and list
# is used when acquisition should be done # is used when acquisition should be done
if permission in state.getAcquirePermissionList(): if permission in state_permission_list:
role_list = list(role_list) role_list = list(role_list)
else: else:
role_list = tuple(role_list) role_list = tuple(role_list)
if modifyRolesForPermission(document, permission, role_list): if modifyRolesForPermission(document, permission, role_list):
changed = 1 changed = True
return changed return changed
# This method allows to update all objects using one workflow, for example # This method allows to update all objects using one workflow, for example
...@@ -251,20 +253,20 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -251,20 +253,20 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
type_info_list = workflow_tool._listTypeInfo() type_info_list = workflow_tool._listTypeInfo()
workflow_id = self.id workflow_id = self.id
portal_type_id_list = [] portal_type_id_list = []
append = portal_type_id_list.append
# look into old chain_by_type (for compatibility) ### Compatibility DC Workflow: look into old chain_by_type
for type_info in type_info_list: for type_info in type_info_list:
type_info_id = type_info.getId() type_info_id = type_info.getId()
if chain_by_type.has_key(type_info_id) and \ if chain_by_type.has_key(type_info_id) and \
workflow_id in chain_by_type[type_info_id]: workflow_id in chain_by_type[type_info_id]:
portal_type_id_list.append(type_info_id) append(type_info_id)
elif workflow_id in workflow_tool._default_chain: elif workflow_id in workflow_tool._default_chain:
portal_type_id_list.append(type_info_id) append(type_info_id)
# check the workflow defined on the portal type objects # check the workflow defined on the portal type objects
for portal_type in self.getPortalObject().portal_types.objectValues(portal_type='Base Type'): for portal_type in self.portal_types.objectValues(portal_type='Base Type'):
if workflow_id in portal_type.getTypeWorkflowList(): if workflow_id in portal_type.getTypeWorkflowList():
portal_type_id_list.append(portal_type.getId()) append(portal_type.getId())
if portal_type_id_list: if portal_type_id_list:
object_list = self.portal_catalog(portal_type=portal_type_id_list, limit=None) object_list = self.portal_catalog(portal_type=portal_type_id_list, limit=None)
...@@ -350,7 +352,8 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -350,7 +352,8 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
sdef = self._getWorkflowStateOf(document, id_only=0) sdef = self._getWorkflowStateOf(document, id_only=0)
if sdef is None: if sdef is None:
return None return None
res = [] object_action_list = []
append = object_action_list.append
for tid in sdef.getDestinationIdList(): for tid in sdef.getDestinationIdList():
tdef = self._getOb(id=tid) tdef = self._getOb(id=tid)
...@@ -360,7 +363,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -360,7 +363,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
fmt_data = TemplateDict() fmt_data = TemplateDict()
fmt_data._push(info) fmt_data._push(info)
fmt_data._push({'transition_id': tdef.getReference()}) fmt_data._push({'transition_id': tdef.getReference()})
res.append((tid, { append((tid, {
'id': tdef.getReference(), 'id': tdef.getReference(),
'name': tdef.getActionName() % fmt_data, 'name': tdef.getActionName() % fmt_data,
'url': str(tdef.getAction()) % fmt_data, 'url': str(tdef.getAction()) % fmt_data,
...@@ -369,9 +372,9 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -369,9 +372,9 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
'category': tdef.getActionType(), 'category': tdef.getActionType(),
'transition': tdef})) 'transition': tdef}))
fmt_data._pop() fmt_data._pop()
res.sort() object_action_list.sort()
return [ result[1] for result in res ] return [ result[1] for result in object_action_list ]
def getWorklistVariableMatchDict(self, info, check_guard=True): def getWorklistVariableMatchDict(self, info, check_guard=True):
""" """
...@@ -384,12 +387,10 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -384,12 +387,10 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
portal = self.getPortalObject() portal = self.getPortalObject()
def getPortalTypeListForWorkflow(workflow_id): def getPortalTypeListForWorkflow(workflow_id):
portal_type_list = [] return [type_info.id
for type_info in portal.portal_types.objectValues(): for type_info in portal.portal_types.objectValues()
portal_type = type_info.id if workflow_id in type_info.getTypeWorkflowList()]
if workflow_id in type_info.getTypeWorkflowList():
portal_type_list.append(portal_type)
return portal_type_list
_getPortalTypeListForWorkflow = CachingMethod(getPortalTypeListForWorkflow, _getPortalTypeListForWorkflow = CachingMethod(getPortalTypeListForWorkflow,
id='_getPortalTypeListForWorkflow', cache_factory = 'erp5_ui_long') id='_getPortalTypeListForWorkflow', cache_factory = 'erp5_ui_long')
...@@ -525,16 +526,12 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -525,16 +526,12 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
return state return state
def getVariableValueDict(self): def getVariableValueDict(self):
variable_dict = {} return {variable.getReference(): variable
for vdef in self.objectValues(portal_type="Workflow Variable"): for variable in self.objectValues(portal_type="Workflow Variable")}
variable_dict[vdef.getReference()] = vdef
return variable_dict
def getVariableIdList(self): def getVariableIdList(self):
id_list = [] return [variable.getReference()
for ob in self.objectValues(portal_type="Workflow Variable"): for variable in self.objectValues(portal_type="Workflow Variable")]
id_list.append(ob.getReference())
return id_list
def getStateValueById(self, stated_id): def getStateValueById(self, stated_id):
return self._getOb('state_' + stated_id, default=None) return self._getOb('state_' + stated_id, default=None)
...@@ -543,19 +540,15 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -543,19 +540,15 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
return self.objectValues(portal_type="State") return self.objectValues(portal_type="State")
def getStateIdList(self): def getStateIdList(self):
id_list = [] return [state.getReference()
for ob in self.objectValues(portal_type="State"): for state in self.objectValues(portal_type="State")]
id_list.append(ob.getReference())
return id_list
def getWorklistValueList(self): def getWorklistValueList(self):
return self.objectValues(portal_type="Worklist") return self.objectValues(portal_type="Worklist")
def getWorklistIdList(): def getWorklistIdList():
id_list = [] return [worklist.getReference()
for ob in self.objectValues(portal_type="Worklist"): for worklist in self.objectValues(portal_type="Worklist")]
id_list.append(ob.getReference())
return id_list
def getWorklistValueById(self, worklist_reference): def getWorklistValueById(self, worklist_reference):
return self._getOb('worklist_' + worklist_reference, None) return self._getOb('worklist_' + worklist_reference, None)
...@@ -567,7 +560,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -567,7 +560,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
return self.objectValues(portal_type="Transition") return self.objectValues(portal_type="Transition")
def getTransitionIdList(self): def getTransitionIdList(self):
return [ob.getReference() for ob return [transition.getReference() for transition
in self.objectValues(portal_type="Transition")] in self.objectValues(portal_type="Transition")]
def getScriptValueList(self): def getScriptValueList(self):
...@@ -664,7 +657,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -664,7 +657,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
for script in script_value_list: for script in script_value_list:
# Pass lots of info to the script in a single parameter. # Pass lots of info to the script in a single parameter.
if script.getPortalType() != 'Workflow Script': if script.getPortalType() != 'Workflow Script':
raise NotImplementedError ('Unsupported Script %s for state %s' % raise NotImplementedError ('Unsupported Script %s for state %s' %
(script.id, old_sdef.getReference())) (script.id, old_sdef.getReference()))
try: try:
script(sci) # May throw an exception. script(sci) # May throw an exception.
...@@ -697,6 +690,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -697,6 +690,7 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
object.REQUEST.other.update(form_kw) object.REQUEST.other.update(form_kw)
kwargs = form_kw kwargs = form_kw
# XXX(WORKFLOW) check this for loop
for vdef in self.objectValues(portal_type='Workflow Variable'): for vdef in self.objectValues(portal_type='Workflow Variable'):
id = vdef.getId() id = vdef.getId()
variable_reference = vdef.getReference() variable_reference = vdef.getReference()
...@@ -756,9 +750,10 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -756,9 +750,10 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
kwargs = form_kw kwargs = form_kw
sci = StateChangeInfo( sci = StateChangeInfo(
document, self, former_status, tdef, old_sdef, new_sdef, kwargs) document, self, former_status, tdef, old_sdef, new_sdef, kwargs)
old_state_destination_list = old_sdef.getDestinationValueList()
for script in script_value_list: for script in script_value_list:
# Script can be either script or workflow method # Script can be either script or workflow method
if script in old_sdef.getDestinationValueList() and \ if script in old_state_destination_list and \
self._getOb(script.id).getTriggerType() == TRIGGER_WORKFLOW_METHOD: self._getOb(script.id).getTriggerType() == TRIGGER_WORKFLOW_METHOD:
getattr(document, convertToMixedCase(self._getOb(script.id).getReference()))() getattr(document, convertToMixedCase(self._getOb(script.id).getReference()))()
else: else:
...@@ -1072,12 +1067,9 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -1072,12 +1067,9 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
""" """
Get list of portal types for workflow. Get list of portal types for workflow.
""" """
result = []
workflow_id = self.getId() workflow_id = self.getId()
for portal_type in self.getPortalObject().portal_types.objectValues(): return [portal_type.getId() for portal_type in self.portal_types.objectValues()
if workflow_id in portal_type.getTypeWorkflowList(): if workflow_id in portal_type.getTypeWorkflowList()]
result.append(portal_type.getId())
return result
def _executeMetaTransition(self, ob, new_state_id): def _executeMetaTransition(self, ob, new_state_id):
""" """
...@@ -1176,19 +1168,19 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject): ...@@ -1176,19 +1168,19 @@ class Workflow(IdAsReferenceMixin("", "prefix"), XMLObject):
# Always provide the state variable. # Always provide the state variable.
state_var = self.getStateVariable() state_var = self.getStateVariable()
status = self.getCurrentStatusDict(ob) status = self.getCurrentStatusDict(ob)
for vdef_ref, vdef in self.getVariableValueDict().iteritems(): for variable_id, variable in self.getVariableValueDict().iteritems():
if vdef.getForCatalog(): if variable.getForCatalog():
variable_expression = vdef.getVariableExpression() variable_expression = variable.getVariableExpression()
if status.has_key(vdef_ref): if status.has_key(variable_id):
value = status[vdef_ref] value = status[variable_id]
# Not set yet. Use a default. # Not set yet. Use a default.
elif variable_expression is not None: elif variable_expression is not None:
ec = createExprContext(StateChangeInfo(ob, self, status)) ec = createExprContext(StateChangeInfo(ob, self, status))
# convert string to expression before execute it. # convert string to expression before execute it.
value = Expression(variable_expression)(ec) value = Expression(variable_expression)(ec)
else: else:
value = vdef.getVariableValue() value = variable.getVariableValue()
if hasattr(self, 'getSourceValue'): if hasattr(self, 'getSourceValue'):
if self.getSourceValue() is not None: if self.getSourceValue() is not None:
initial_state = self.getSourceValue().getReference() initial_state = self.getSourceValue().getReference()
......
...@@ -75,21 +75,20 @@ class Worklist(IdAsReferenceMixin("worklist_", "prefix"), XMLObject, ...@@ -75,21 +75,20 @@ class Worklist(IdAsReferenceMixin("worklist_", "prefix"), XMLObject,
) )
def getAvailableCatalogVars(self): def getAvailableCatalogVars(self):
res = [] parent = self.getParentValue()
res.append(self.getParentValue().getStateVariable()) res = [parent.getStateVariable()]
for vdef in self.getParentValue().contentValues(portal_type="Workflow Variable"): res += [variable.getId() for variable in self.objectValues()]
if vdef.getForCatalog(): res += [variable for variable in
res.append(vdef.getId()) parent.contentValues(portal_type="Workflow Variable")
for vdef in self.objectValues(): if variable.getForCatalog()]
res.append(vdef.getId()) res.sort()
res.sort() return res
return res
def updateDynamicVariable(self): def updateDynamicVariable(self):
# Keep worklist variables updating, correspond to workflow variables. # Keep worklist variables updating, correspond to workflow variables.
# In the new workflow, we may not need this function for the moment. # In the new workflow, we may not need this function for the moment.
res = [] res = []
# XXX(WORKFLOW): is there a reason not to return self.objectValues() here?
for worklist_variable_value in self.objectValues(): for worklist_variable_value in self.objectValues():
res.append(worklist_variable_value) res.append(worklist_variable_value)
return res return res
...@@ -107,16 +106,20 @@ class Worklist(IdAsReferenceMixin("worklist_", "prefix"), XMLObject, ...@@ -107,16 +106,20 @@ class Worklist(IdAsReferenceMixin("worklist_", "prefix"), XMLObject,
variable_id = variable_value.getId() variable_id = variable_value.getId()
workflow_variable_id_list.append(variable_id) workflow_variable_id_list.append(variable_id)
worklist_variable_value = self._getOb(variable_id, None) worklist_variable_value = self._getOb(variable_id, None)
if worklist_variable_value is None and variable_value.getForCatalog() == 1 and variable_id not in default_variable_id_list: if (worklist_variable_value is None
and variable_value.getForCatalog() == 1
and variable_id not in default_variable_id_list):
variable_value_ref = variable_value.getReference() variable_value_ref = variable_value.getReference()
worklist_variable_value = self.newContent(portal_type='Worklist Variable') worklist_variable_value = self.newContent(portal_type='Worklist Variable')
worklist_variable_value.setReference(variable_value_ref) worklist_variable_value.setReference(variable_value_ref)
worklist_variable_value.setVariableExpression(variable_value.getVariableExpression()) worklist_variable_value.setVariableExpression(variable_value.getVariableExpression())
worklist_variable_value.setVariableValue(variable_value.getVariableValue()) worklist_variable_value.setVariableValue(variable_value.getVariableValue())
res.append(worklist_variable_value) res.append(worklist_variable_value)
if worklist_variable_value and worklist_variable_value not in res and variable_value.getForCatalog() == 1: if (worklist_variable_value and worklist_variable_value not in res
and variable_value.getForCatalog() == 1):
res.append(worklist_variable_value) res.append(worklist_variable_value)
if worklist_variable_value in res and variable_value.getForCatalog() == 0: if (worklist_variable_value in res
and variable_value.getForCatalog() == 0):
self._delObject(variable_id) self._delObject(variable_id)
res.remove(worklist_variable_value) res.remove(worklist_variable_value)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment