From 35bc83380dc26bcf2fef9be3e60eff48d34de044 Mon Sep 17 00:00:00 2001 From: Wenjie Zheng <wenjie.zheng@tiolive.com> Date: Tue, 5 May 2015 16:12:25 +0000 Subject: [PATCH] Base.py: MERGE ALL TOGETHER. --- product/ERP5Type/Base.py | 331 ++------------------------------------- 1 file changed, 16 insertions(+), 315 deletions(-) diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py index 87051cfb6f..7af0a5edc2 100644 --- a/product/ERP5Type/Base.py +++ b/product/ERP5Type/Base.py @@ -123,119 +123,6 @@ def resetRegisteredERP5WorkflowMethod(portal_type=None): for method in erp5workflow_method_registry: method.reset(portal_type=portal_type) -class ERP5WorkflowMethod(Method): - ### to get the name of the class - def __init__(self, method, id=None, reindex=1): - self._m = method - if id is None: - self._transition_id = method.__name__ - else: - self._transition_id = id - LOG("134 initializing method '%s'"%self._transition_id, WARNING, " in Base.py") - if not method.__name__.startswith('_'): - self.__name__ = method.__name__ - for func_id in ['func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']: - setattr(self, func_id, getattr(method, func_id, None)) - self._invoke_once = {} - self._invoke_always = {} # Store in a dict all workflow IDs which require to - # invoke wrapWorkflowMethod at every call - # during the same transaction - - def getTransitionId(self): - return self._transition_id - - def __call__(self, instance, *args, **kw): - LOG("148 Calling method '%s' by '%s'"%(self._transition_id, instance.getId()), WARNING, " in Base.py") - if getattr(self, '__name__', None) in ('getPhysicalPath', 'getId',): - return self._m(instance, *args, **kw) - - # Build a list of transitions which may need to be invoked - instance_path = instance.getPhysicalPath() - portal_type = instance.portal_type - transactional_variable = getTransactionalVariable() - invoke_once_dict = self._invoke_once.get(portal_type, {}) - valid_invoke_once_item_list = [] - # Only keep those transitions which were never invoked - once_transition_dict = {} - # New implementation does not use any longer wrapWorkflowMethod - # but directly calls the workflow methods - - for wf_id, transition_list in invoke_once_dict.iteritems(): - valid_transition_list = [] - for transition_id in transition_list: - once_transition_key = ('Products.ERP5Type.Base.ERP5WorkflowMethod.__call__', - wf_id, transition_id, instance_path) - once_transition_dict[(wf_id, transition_id)] = once_transition_key - if once_transition_key not in transactional_variable: - valid_transition_list.append(transition_id) - if valid_transition_list: - valid_invoke_once_item_list.append((wf_id, valid_transition_list)) - LOG("173 _invoke_always list contains: '%s'"%self._invoke_always,WARNING," in Base.py") - candidate_transition_item_list = valid_invoke_once_item_list + \ - self._invoke_always.get(portal_type, {}).items() - - # Try to return immediately if there are no transition to invoke - if not candidate_transition_item_list: - return apply(self.__dict__['_m'], (instance,) + args, kw) - - try: - wf_module = instance.getPortalObject().portal_workflow - except AttributeError: - return self._m(instance, *arge, **kw) - - valid_transition_item_list = [] - for wf_id, transition_list in candidate_transition_item_list: - valid_list = [] - workflow = wf_module._getOb(wf_id) - for transition_id in transition_list: - LOG("191 Type '%s' is checking transition '%s' of workflow '%s'" %(instance.getPortalType(), transition_id, wf_id), WARNING, " in Base.py") - if workflow.isERP5WorkflowMethodSupported(instance, workflow._getOb(transition_id)): - valid_list.append(transition_id) - once_transition_key = once_transition_dict.get((wf_id, transition_id)) - transactional_variable[once_transition_key] = 1 - else: - raise UnsupportedWorkflowMethod(instance, wf_id, transition_id) - if valid_list: - valid_transition_item_list.append((wf_id, valid_list)) - - result = apply(self.__dict__['_m'], (instance,) + args, kw) - - ### zwj: Execute method - for wf_id, transition_list in valid_transition_item_list: - try: - for tr_id in transition_list: - method = wf_module._getOb(wf_id)._getOb(tr_id) - LOG(" 208 executing method '%s' of workflow '%s'"%(tr_id, wf_id), WARNING, " in Base.py") - method.execute(instance) - except ObjectDeleted: - raise ObjectDeleted(result) - except ObjectMoved, ex: - raise ObjectMoved(ex.getNewObject(), result) - - def registerERP5TransitionAlways(self, portal_type, workflow_id, transition_id): - LOG(" 216 register transition-always '%s' of workflow '%s'"%(transition_id, workflow_id), WARNING, " in Base.py") - transition_list = self._invoke_always.setdefault(portal_type, {}).setdefault(workflow_id, []) - if transition_id not in transition_list: transition_list.append(transition_id) - self.registerERP5() - - def registerERP5TransitionOncePerTransaction(self, portal_type, workflow_id, transition_id): - LOG(" 222 register transition-once '%s' of workflow '%s'"%(transition_id, worfklow_id), WARNING, " in Base.py") - transition_list = self._invoke_once.setdefault(portal_type, {}).setdefault(workflow_id, []) - if transition_id not in transition_list: transition_list.append(transition_id) - self.registerERP5() - - def registerERP5(self): - erp5workflow_method_registry.append(self) - - def reset(self, portal_type=None): - if portal_type: - self._invoke_once[portal_type] = {} - self._invoke_always[portal_type] = {} - else: - self._invoke_once = {} - self._invoke_always = {} - ### ========================================================================== - class WorkflowMethod(Method): def __init__(self, method, id=None, reindex=1): @@ -342,7 +229,8 @@ class WorkflowMethod(Method): # a run-once transition, prevent it from running again in # the same transaction transactional_variable[once_transition_key] = 1 - elif candidate_workflow.__class__.__name__ == 'DCWorkflowDefinition': + elif candidate_workflow.__class__.__name__ == 'DCWorkflowDefinition' or \ + candidate_workflow.__class__.__name__ == 'Workflow': raise UnsupportedWorkflowMethod(instance, wf_id, transition_id) # XXX Keep the log for projects that needs to comment out # the previous line. @@ -642,195 +530,7 @@ def getClassPropertyList(klass): if p not in ps_list]) return ps_list -def initializePortalTypeERP5WorkflowMethod(ptype_klass, portal_workflow): - portal_type = ptype_klass.__name__ - workflow_dict = {} - interaction_workflow_dict = {} - portal_workflow = aq_inner(portal_workflow) - portal_type_module = portal_workflow.getPortalObject().getDefaultModule(portal_type="portal_types") - portal_type_value = portal_type_module._getOb(portal_type, None) - - for ERP5Workflow in portal_workflow.getWorkflowValueListFor(portal_type_value): - ERP5Workflow_id = ERP5Workflow.getId() - workflow_type = ERP5Workflow.__class__.__name__ - LOG(" 661 initializing portal type '%s' "%ptype_klass.__name__, WARNING, " in Base.py") - LOG(" 664 Found Workflow type = %s"%workflow_type, WARNING, " in Base.py.") - if workflow_type == 'Workflow' or workflow_type == 'DCWorkflowDefinition': - state_var = ERP5Workflow.getStateVariable() - LOG(" 666 Found Workflow '%s' with state_var '%s'"%(ERP5Workflow_id, state_var), WARNING, " in Base.py.") - for method_id, getter in ( - ('get%s' % UpperCase(state_var), WorkflowState.Getter), - ('get%sTitle' % UpperCase(state_var), WorkflowState.TitleGetter), - ('getTranslated%s' % UpperCase(state_var), - WorkflowState.TranslatedGetter), - ('getTranslated%sTitle' % UpperCase(state_var), - WorkflowState.TranslatedTitleGetter), - ('serialize%s' % UpperCase(state_var), WorkflowState.SerializeGetter), - ): - method = getter(method_id, ERP5Workflow_id) - ptype_klass.registerAccessor(method, - Permissions.AccessContentsInformation) - if workflow_type == 'Workflow': - LOG(" 681 Generating methods of Workflow type workflow '%s'"%ERP5Workflow_id, WARNING, " in Base.py") - transition_id_list = [] #ERP5Workflow.objectIds(portal_type='Transition') - transition_list = ERP5Workflow.objectValues(portal_type='Transition') - for tr in transition_list: - transition_id_list.append(tr.getReference())### getRef, this id list is actually a reference list - LOG(" 686 transition_id_list = '%s'"%transition_id_list, WARNING, " in Base.py") - elif workflow_type == 'DCWorkflowDefinition': - LOG(" 688 Generating methods of DCWorkflow '%s'"%ERP5Workflow_id, WARNING, " in Base.py") - transition_id_list = ERP5Workflow.transitions - transition_list = [] - for transition_id in transition_id_list: - LOG(" 692 register transition '%s' to transition_list"%transition_id, WARNING, " in Base.py") - transition = ERP5Workflow.transitions.get(transition_id) - transition_list.append(transition) - storage = workflow_dict - elif workflow_type == 'Interaction Workflow' or workflow_type == 'InteractionWorkflowDefinition': - if workflow_type == 'Interaction Workflow': - LOG(" 698 Generating methods of Interaction Workflow '%s'"%ERP5Workflow_id, WARNING, ' in Base.py') - transition_id_list = [] - transition_list = ERP5Workflow.objectValues(portal_type='Interaction') - for tr in transition_list: - transition_id_list.append(tr.getReference()) # remove suffinx - LOG(" 703 transition_id_list = '%s'"%transition_id_list, WARNING, ' in Base.py') - elif workflow_type == 'InteractionWorkflowDefinition': - LOG(" 705 Generating methods of DC Interaction Workflow '%s'"%ERP5Workflow_id, WARNING, ' in Base.py') - transition_id_list = ERP5Workflow.interactions - transition_list = [] - for interaction_id in transition_id_list: - interaction = ERP5Workflow.interactions.get(interaction_id) - transition_list.append(interaction) - storage = interaction_workflow_dict - else: - LOG("Please check workflow list definded. '%s' '%s' is ignored "%(workflow_type, ERP5Workflow_id),WARNING,"in Base.py/initializePortalTypeWorkflowMethod.") - continue - - ### zwj: compatibility for Interaction Workflow and Workflow =============== - transition_id_set = set(transition_id_list) - trigger_dict = {} - - for transition in transition_list: - transition_id = transition.getReference() - LOG("722 Found transition '%s'"%transition_id,WARNING, " in Base.py") - if transition.trigger_type == TRIGGER_WORKFLOW_METHOD: - LOG("723 Register Trigger by workflow method transition %s"%transition_id,WARNING, " in Base.py") - trigger_dict[transition_id] = transition - storage[ERP5Workflow_id] = (transition_id_set, trigger_dict) - ### zwj: generate Workflow methods - for ERP5Workflow_id, v in workflow_dict.iteritems(): - LOG("730 Generating methods of Workflow '%s'"%ERP5Workflow_id, WARNING, " in Base.py") - transition_id_set, trigger_dict = v - for tr_id, tdef in trigger_dict.iteritems(): - LOG("733 processing transition '%s' of '%s'"%(tr_id,ERP5Workflow_id), WARNING, "in Base.py") - method_id = convertToMixedCase(tr_id) - LOG(" 731 register transition '%s' as method '%s'"%(tr_id, method_id), WARNING, " in Base.py") - try: - method = getattr(ptype_klass, method_id) - except AttributeError: - LOG("738 processing new method '%s'"%method_id, WARNING, " in Base.py.") - ptype_klass.security.declareProtected(Permissions.AccessContentsInformation, - method_id) - ptype_klass.registerERP5WorkflowMethod(method_id, ERP5Workflow_id, tr_id, 0) - continue - LOG("743 check if method '%s' is callable"%method_id, WARNING, " in Base.py") - # Wrap method - if not callable(method): - LOG('initializePortalTypeDynamicWorkflowMethods', 100, - 'WARNING! Can not initialize %s on %s' % \ - (method_id, portal_type)) - continue - LOG("751 check if workflow method '%s' is an ERP5 WorkflowMethod"%method_id, WARNING, " in Base.py") - if not isinstance(method, ERP5WorkflowMethod): - method = ERP5WorkflowMethod(method, method_id) - setattr(ptype_klass, method_id, method) - else: - transition_id = method.getTransitionId() - if transition_id in transition_id_set: - method.registerERP5TransitionAlways(portal_type, ERP5Workflow_id, transition_id) - method.registerERP5TransitionAlways(portal_type, ERP5Workflow_id, tr_id) - - ### zwj: generate interaction workflow methods - if not interaction_workflow_dict: - return - class_method_id_list = ptype_klass.getClassMethodIdList(ptype_klass) - interaction_queue = [] - LOG(" 767 Initializing Interaction Workflow methods",WARNING," in Base.py") - for wf_id, v in interaction_workflow_dict.iteritems(): - transition_id_set, trigger_dict = v - for tr_id, tdef in trigger_dict.iteritems(): - # check portal type filter - LOG(" 772 processing transition '%s' of workflow '%s'"%(tdef.getId(), wf_id), WARNING, " in Base.py.") - type_filter = list(tdef.portal_type_filter) - if (type_filter != [] and portal_type not in type_filter): - continue - # check portal type group filter - group_filter = list(tdef.portal_type_group_filter) ### not use property sheet accessor - if group_filter != []: - getPortalGroupedTypeSet = portal_workflow.getPortalObject()._getPortalGroupedTypeSet - if not any(portal_type in getPortalGroupedTypeSet(portal_type_group) for - portal_type_group in group_filter): - continue - # gather trigger method id - if list(tdef.method_id) == []: - raise NotImplementedError ("Please give a trigger method for interaction: %s in interaction workflow: %s."%(tr_id, wf_id)) - - for imethod_id in list(tdef.method_id): - if wildcard_interaction_method_id_match(imethod_id): - method_id_matcher = re.compile(imethod_id).match - # queue transitions using regexps for later examination - interaction_queue.append((wf_id, - tr_id, - transition_id_set, - tdef.once_per_transaction, - method_id_matcher)) - method_id_list = filter(method_id_matcher, class_method_id_list) - else: - method_id_list = [imethod_id] - for method_id in method_id_list: - method = getattr(ptype_klass, method_id, _MARKER) - - if method is _MARKER: - if method_id not in ptype_klass.security.names: - ptype_klass.security.declareProtected( - Permissions.AccessContentsInformation, method_id) - ptype_klass.registerERP5WorkflowMethod(method_id, wf_id, tr_id, tdef.once_per_transaction) - continue - # wrap method - if not callable(method): - LOG('initializePortalTypeDynamicWorkflowMethods', 100, - 'WARNING! Can not initialize %s on %s' % \ - (method_id, portal_type)) - continue - if not isinstance(method, ERP5WorkflowMethod): - method = ERP5WorkflowMethod(method, method_id) - setattr(ptype_klass, method_id, method) - else: - transition_id = method.getTransitionId() - if transition_id in transition_id_set: - method.registerERP5TransitionAlways(portal_type, wf_id, transition_id) - if tdef.once_per_transaction: - method.registerERP5TransitionOncePerTransaction(portal_type, wf_id, tr_id) - else: - method.registerERP5TransitionAlways(portal_type, wf_id, tr_id) - if not interaction_queue: - return - - new_method_set = set(ptype_klass.getWorkflowMethodIdList()) - added_method_set = new_method_set.difference(class_method_id_list) - for wf_id, tr_id, transition_id_set, once, method_id_matcher in interaction_queue: - for method_id in filter(method_id_matcher, added_method_set): - # method must already exist and be a workflow method - method = getattr(ptype_klass, method_id) - transition_id = method.getTransitionId() - if transition_id in transition_id_set: - method.registerERP5TransitionAlways(portal_type, wf_id, transition_id) - if once: - method.registerERP5TransitionOncePerTransaction(portal_type, wf_id, tr_id) - else: - method.registerERP5TransitionAlways(portal_type, wf_id, tr_id) - -def initializePortalTypeDynamicWorkflowMethods(ptype_klass, portal_workflow): +def initializePortalTypeWorkflowMethods(ptype_klass, portal_workflow): """We should now make sure workflow methods are defined and also make sure simulation state is defined.""" # aq_inner is required to prevent extra name lookups from happening @@ -841,15 +541,15 @@ def initializePortalTypeDynamicWorkflowMethods(ptype_klass, portal_workflow): portal_workflow = aq_inner(portal_workflow) portal_type = ptype_klass.__name__ - dc_workflow_dict = {} + workflow_dict = {} interaction_workflow_dict = {} - for wf in portal_workflow.getWorkflowsFor(portal_type): - wf_id = wf.id + for wf in portal_workflow.getWorkflowValueListFor(portal_type): + wf_id = wf.getId() wf_type = wf.__class__.__name__ - if wf_type == "DCWorkflowDefinition": + if wf_type == "DCWorkflowDefinition" or wf_type == "Workflow": # Create state var accessor # and generate methods that support the translation of workflow states - state_var = wf.variables.getStateVar() + state_var = wf.getStateVariable() for method_id, getter in ( ('get%s' % UpperCase(state_var), WorkflowState.Getter), ('get%sTitle' % UpperCase(state_var), WorkflowState.TitleGetter), @@ -865,16 +565,17 @@ def initializePortalTypeDynamicWorkflowMethods(ptype_klass, portal_workflow): ptype_klass.registerAccessor(method, Permissions.AccessContentsInformation) - storage = dc_workflow_dict - transitions = wf.transitions - elif wf_type == "InteractionWorkflowDefinition": + storage = workflow_dict + transitions = wf.getTransitionValueList() + elif wf_type == "InteractionWorkflowDefinition" or wf_type == "InteractionWorkflow": storage = interaction_workflow_dict - transitions = wf.interactions + transitions = wf.getTransitionValueList() else: continue # extract Trigger transitions from workflow definitions for later - transition_id_set = set(transitions.objectIds()) + transition_id_set = set(wf.getTransitionIdList()) + trigger_dict = {} for tr_id in transition_id_set: tdef = transitions[tr_id] @@ -883,8 +584,8 @@ def initializePortalTypeDynamicWorkflowMethods(ptype_klass, portal_workflow): storage[wf_id] = (transition_id_set, trigger_dict) -# Generate Workflow method: - for wf_id, v in dc_workflow_dict.iteritems(): + # Generate Workflow method + for wf_id, v in workflow_dict.iteritems(): transition_id_set, trigger_dict = v for tr_id, tdef in trigger_dict.iteritems(): method_id = convertToMixedCase(tr_id) -- 2.30.9