From 817a204d9e616a4255ed4477767dd1c75503fd32 Mon Sep 17 00:00:00 2001
From: Alexandre Boeglin <alex@nexedi.com>
Date: Thu, 16 Jun 2005 15:33:38 +0000
Subject: [PATCH] Fixed initializePortalTypeDynamicProperties.

When the function was called on a new Portal Type (not present in aq_portal_type)
with recursive = 1, no Accessor was generated, and the Portal Type was added to aq_portal_type,
thus preventing a future call of initializePortalTypeDynamicProperties to generate anything.

I just removed the recursive argument, and ajusted the recursive call to use parent_object instead of self,
which should allow to recursively create Workflows Accessors.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@3269 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Type/Base.py | 236 +++++++++++++++++++--------------------
 1 file changed, 118 insertions(+), 118 deletions(-)

diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py
index 3419f8cccb..a21d68f419 100755
--- a/product/ERP5Type/Base.py
+++ b/product/ERP5Type/Base.py
@@ -117,13 +117,13 @@ def getClassPropertyList(klass):
                                                          getClassPropertyList(super_klass)))
   return ps_list
 
-def initializeClassDynamicProperties(self, klass, recursive=0):
+def initializeClassDynamicProperties(self, klass):
   id = ''
   #LOG('before aq_method_generated %s' % id, 0, str(klass.__name__))
   if not Base.aq_method_generated.has_key(klass):
     # Recurse to superclasses
     for super_klass in klass.__bases__:
-      if getattr(super_klass, 'isRADContent', 0): initializeClassDynamicProperties(self, super_klass, recursive=1)
+      if getattr(super_klass, 'isRADContent', 0): initializeClassDynamicProperties(self, super_klass)
     # Initialize default properties
     #LOG('in aq_method_generated %s' % id, 0, str(klass.__name__))
     from Utils import initializeDefaultProperties
@@ -132,7 +132,7 @@ def initializeClassDynamicProperties(self, klass, recursive=0):
       # Mark as generated
       Base.aq_method_generated[klass] = 1
 
-def initializePortalTypeDynamicProperties(self, klass, ptype, recursive=0):
+def initializePortalTypeDynamicProperties(self, klass, ptype):
   id = ''
   #LOG('before aq_portal_type %s' % id, 0, str(ptype))
   if not Base.aq_portal_type.has_key(ptype):
@@ -143,123 +143,123 @@ def initializePortalTypeDynamicProperties(self, klass, ptype, recursive=0):
     parent_object = self.aq_parent
     parent_klass = parent_object.__class__
     parent_type = parent_object.portal_type
-    if getattr(parent_klass, 'isRADContent', 0) and (ptype != parent_type or klass != parent_klass):
-      initializePortalTypeDynamicProperties(self, parent_klass, parent_type, recursive=1)
-    if not recursive:
-      # Initiatise portal_type properties (XXX)
-      ptype_object = getattr(aq_base(self.portal_types), ptype, None)
-      cat_list = []
-      prop_list = []
-      constraint_list = []
-      if ptype_object is not None and ptype_object.meta_type == 'ERP5 Type Information':
-        # Make sure this is an ERP5Type object
-        ps_list = map(lambda p: getattr(PropertySheet, p, None), ptype_object.property_sheet_list)
-        ps_list = filter(lambda p: p is not None, ps_list)
-        # Always append the klass.property_sheets to this list (for compatibility)
-        # Because of the order we generate accessors, it is still possible
-        # to overload data access for some accessors
-        ps_list = tuple(ps_list) + getClassPropertyList(klass)
-        #LOG('ps_list',0, str(ps_list))
-      else:
-        ps_list = getClassPropertyList(klass)
-      for base in ps_list:
-          if hasattr(base, '_properties'):
-            prop_list += base._properties
-          if hasattr(base, '_categories'):
-            if type(base._categories) in (type(()), type([])):
-              cat_list += base._categories
+    if getattr(parent_klass, 'isRADContent', 0) and (ptype != parent_type or klass != parent_klass) \
+        and not Base.aq_portal_type.has_key(parent_type):
+      initializePortalTypeDynamicProperties(parent_object, parent_klass, parent_type)
+    # Initiatise portal_type properties (XXX)
+    ptype_object = getattr(aq_base(self.portal_types), ptype, None)
+    cat_list = []
+    prop_list = []
+    constraint_list = []
+    if ptype_object is not None and ptype_object.meta_type == 'ERP5 Type Information':
+      # Make sure this is an ERP5Type object
+      ps_list = map(lambda p: getattr(PropertySheet, p, None), ptype_object.property_sheet_list)
+      ps_list = filter(lambda p: p is not None, ps_list)
+      # Always append the klass.property_sheets to this list (for compatibility)
+      # Because of the order we generate accessors, it is still possible
+      # to overload data access for some accessors
+      ps_list = tuple(ps_list) + getClassPropertyList(klass)
+      #LOG('ps_list',0, str(ps_list))
+    else:
+      ps_list = getClassPropertyList(klass)
+    for base in ps_list:
+        if hasattr(base, '_properties'):
+          prop_list += base._properties
+        if hasattr(base, '_categories'):
+          if type(base._categories) in (type(()), type([])):
+            cat_list += base._categories
+          else:
+            cat_list += [base._categories]
+        if hasattr(base, '_constraints'):
+          constraint_list += base._constraints
+    if ptype_object is not None and ptype_object.meta_type == 'ERP5 Type Information':
+      cat_list += ptype_object.base_category_list
+    prop_holder._properties = prop_list
+    prop_holder._categories = cat_list
+    prop_holder._constraints = constraint_list
+    if hasattr(klass, 'security'):
+      prop_holder.security = klass.security # Is this OK for security XXX ?
+    else:
+      prop_holder.security = ClassSecurityInfo() # Is this OK for security XXX ?
+    from Utils import initializeDefaultProperties
+    initializeDefaultProperties([prop_holder], object=self)
+    #LOG('initializeDefaultProperties: %s' % ptype, 0, str(prop_holder.__dict__))
+    # We should now make sure workflow methods are defined
+    # and also make sure simulation state is defined
+    portal_workflow = getToolByName(self, 'portal_workflow')
+    #LOG('getWorkflowsFor', 0, str((self, [wf.id for wf in portal_workflow.getWorkflowsFor(self)])))
+    for wf in portal_workflow.getWorkflowsFor(self):
+      wf_id = wf.id
+      #LOG('in aq_portal_type %s' % id, 0, "found state workflow %s" % wf.id)
+      if wf.__class__.__name__ in ('DCWorkflowDefinition', ):
+        # Create state var accessor
+        state_var = wf.variables.getStateVar()
+        method_id = 'get%s' % UpperCase(state_var)
+        if not hasattr(prop_holder, method_id):
+          method = WorkflowState.Getter(method_id, wf_id)
+          setattr(prop_holder, method_id, method) # Attach to portal_type
+          prop_holder.security.declareProtected( Permissions.AccessContentsInformation, method_id )
+        method_id = 'get%sTitle' % UpperCase(state_var)
+        if not hasattr(prop_holder, method_id):
+          method = WorkflowState.TitleGetter(method_id, wf_id)
+          setattr(prop_holder, method_id, method) # Attach to portal_type
+          prop_holder.security.declareProtected( Permissions.AccessContentsInformation, method_id )
+          #LOG('in aq_portal_type %s' % id, 0, "added state method %s" % method_id)
+      #LOG('in aq_portal_type %s' % id, 0, "found transition workflow %s" % wf.id)
+      if wf.__class__.__name__ in ('DCWorkflowDefinition', ):
+        for tr_id in wf.transitions.objectIds():
+          tdef = wf.transitions.get(tr_id, None)
+          if tdef.trigger_type == TRIGGER_WORKFLOW_METHOD:
+            method_id = convertToMixedCase(tr_id)
+            # We have to make a difference between a method which is on
+            # the prop_holder or on the klass, if the method is on the
+            # klass, then the WorkflowMethod created also need to be on the klass
+            if not hasattr(prop_holder, method_id) and not hasattr(klass,method_id):
+              method = WorkflowMethod(klass._doNothing, tr_id)
+              setattr(prop_holder, method_id, method) # Attach to portal_type
+              prop_holder.security.declareProtected( Permissions.AccessContentsInformation, method_id )
+              #LOG('in aq_portal_type %s' % id, 0, "added transition method %s" % method_id)
             else:
-              cat_list += [base._categories]
-          if hasattr(base, '_constraints'):
-            constraint_list += base._constraints
-      if ptype_object is not None and ptype_object.meta_type == 'ERP5 Type Information':
-        cat_list += ptype_object.base_category_list
-      prop_holder._properties = prop_list
-      prop_holder._categories = cat_list
-      prop_holder._constraints = constraint_list
-      if hasattr(klass, 'security'):
-        prop_holder.security = klass.security # Is this OK for security XXX ?
-      else:
-        prop_holder.security = ClassSecurityInfo() # Is this OK for security XXX ?
-      from Utils import initializeDefaultProperties
-      initializeDefaultProperties([prop_holder], object=self)
-      #LOG('initializeDefaultProperties: %s' % ptype, 0, str(prop_holder.__dict__))
-      # We should now make sure workflow methods are defined
-      # and also make sure simulation state is defined
-      portal_workflow = getToolByName(self, 'portal_workflow')
-      #LOG('getWorkflowsFor', 0, str((self, [wf.id for wf in portal_workflow.getWorkflowsFor(self)])))
-      for wf in portal_workflow.getWorkflowsFor(self):
-        wf_id = wf.id
-        #LOG('in aq_portal_type %s' % id, 0, "found state workflow %s" % wf.id)
-        if wf.__class__.__name__ in ('DCWorkflowDefinition', ):
-          # Create state var accessor
-          state_var = wf.variables.getStateVar()
-          method_id = 'get%s' % UpperCase(state_var)
-          if not hasattr(prop_holder, method_id):
-            method = WorkflowState.Getter(method_id, wf_id)
-            setattr(prop_holder, method_id, method) # Attach to portal_type
-            prop_holder.security.declareProtected( Permissions.AccessContentsInformation, method_id )
-          method_id = 'get%sTitle' % UpperCase(state_var)
-          if not hasattr(prop_holder, method_id):
-            method = WorkflowState.TitleGetter(method_id, wf_id)
-            setattr(prop_holder, method_id, method) # Attach to portal_type
-            prop_holder.security.declareProtected( Permissions.AccessContentsInformation, method_id )
-            #LOG('in aq_portal_type %s' % id, 0, "added state method %s" % method_id)
-        #LOG('in aq_portal_type %s' % id, 0, "found transition workflow %s" % wf.id)
-        if wf.__class__.__name__ in ('DCWorkflowDefinition', ):
-          for tr_id in wf.transitions.objectIds():
-            tdef = wf.transitions.get(tr_id, None)
-            if tdef.trigger_type == TRIGGER_WORKFLOW_METHOD:
-              method_id = convertToMixedCase(tr_id)
-              # We have to make a difference between a method which is on
-              # the prop_holder or on the klass, if the method is on the
-              # klass, then the WorkflowMethod created also need to be on the klass
+              # Wrap method into WorkflowMethod is needed
+              if getattr(klass,method_id,None) is not None:
+                method = getattr(klass, method_id)
+                if callable(method):
+                  if not isinstance(method, WorkflowMethod):
+                    setattr(klass, method_id, WorkflowMethod(method, method_id))
+              else:
+                method = getattr(prop_holder, method_id)
+                if callable(method):
+                  if not isinstance(method, WorkflowMethod):
+                    setattr(prop_holder, method_id, WorkflowMethod(method, method_id))
+      elif wf.__class__.__name__ in ('InteractionWorkflowDefinition', ):
+        for tr_id in wf.interactions.objectIds():
+          tdef = wf.interactions.get(tr_id, None)
+          if tdef.trigger_type == TRIGGER_WORKFLOW_METHOD:
+            for imethod_id in tdef.method_id:
+              method_id = imethod_id
               if not hasattr(prop_holder, method_id) and not hasattr(klass,method_id):
-                method = WorkflowMethod(klass._doNothing, tr_id)
+                method = WorkflowMethod(klass._doNothing, imethod_id)
                 setattr(prop_holder, method_id, method) # Attach to portal_type
                 prop_holder.security.declareProtected( Permissions.AccessContentsInformation, method_id )
-                #LOG('in aq_portal_type %s' % id, 0, "added transition method %s" % method_id)
               else:
                 # Wrap method into WorkflowMethod is needed
                 if getattr(klass,method_id,None) is not None:
                   method = getattr(klass, method_id)
                   if callable(method):
                     if not isinstance(method, WorkflowMethod):
-                      setattr(klass, method_id, WorkflowMethod(method, method_id))
+                      method = WorkflowMethod(method, method_id)
+                      setattr(klass, method_id, method)
                 else:
                   method = getattr(prop_holder, method_id)
                   if callable(method):
                     if not isinstance(method, WorkflowMethod):
-                      setattr(prop_holder, method_id, WorkflowMethod(method, method_id))
-        elif wf.__class__.__name__ in ('InteractionWorkflowDefinition', ):
-          for tr_id in wf.interactions.objectIds():
-            tdef = wf.interactions.get(tr_id, None)
-            if tdef.trigger_type == TRIGGER_WORKFLOW_METHOD:
-              for imethod_id in tdef.method_id:
-                method_id = imethod_id
-                if not hasattr(prop_holder, method_id) and not hasattr(klass,method_id):
-                  method = WorkflowMethod(klass._doNothing, imethod_id)
-                  setattr(prop_holder, method_id, method) # Attach to portal_type
-                  prop_holder.security.declareProtected( Permissions.AccessContentsInformation, method_id )
-                else:
-                  # Wrap method into WorkflowMethod is needed
-                  if getattr(klass,method_id,None) is not None:
-                    method = getattr(klass, method_id)
-                    if callable(method):
-                      if not isinstance(method, WorkflowMethod):
-                        method = WorkflowMethod(method, method_id)
-                        setattr(klass, method_id, method)
-                  else:
-                    method = getattr(prop_holder, method_id)
-                    if callable(method):
-                      if not isinstance(method, WorkflowMethod):
-                        method = WorkflowMethod(method, method_id)
-                        setattr(prop_holder, method_id, method)
-    
+                      method = WorkflowMethod(method, method_id)
+                      setattr(prop_holder, method_id, method)
+
     # We can now associate it
     Base.aq_portal_type[ptype] = prop_holder
-    
-    
+
+
 class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
   """
     This is the base class for all ERP5 Zope objects.
@@ -295,8 +295,8 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
   isMovement = 0      #
   isDelivery = 0      #
   isIndexable = 1     # If set to 0, reindexing will not happen (useful for optimization)
-  isPredicate = 0     # 
-  
+  isPredicate = 0     #
+
   # Dynamic method acquisition system (code generation)
   aq_method_generated = {}
   aq_portal_type = {}
@@ -335,9 +335,9 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
 
   def _aq_dynamic(self, id):
     ptype = self.portal_type
-   
+
     #LOG("In _aq_dynamic", 0, str((id, ptype, self)))
-   
+
     # If this is a portal_type property and everything is already defined
     # for that portal_type, try to return a value ASAP
     if Base.aq_portal_type.has_key(ptype):
@@ -379,9 +379,9 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
     if generated:
       # We suppose that if we reach this point
       # then it means that all code generation has succeeded
-      # (no except should hide that). We can safely return None 
+      # (no except should hide that). We can safely return None
       # if id does not exist as a dynamic property
-      # Baseline: accessor generation failures should always 
+      # Baseline: accessor generation failures should always
       #           raise an exception up to the user
       return getattr(self, id, None)
 
@@ -958,14 +958,14 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
       Returns instance if catehory throughdocument_instance relation
     """
     return self
-    
+
   security.declareProtected( Permissions.AccessContentsInformation, 'asParentSqlExpression' )
   def getParentSqlExpression(self, table = 'catalog', strict_membership = 0):
     """
-      Builds an SQL expression to search children and subclidren      
+      Builds an SQL expression to search children and subclidren
     """
     return "%s.parent_uid = %s" % (table, self.getUid())
-    
+
   security.declareProtected( Permissions.AccessContentsInformation, 'getParentUid' )
   def getParentUid(self):
     """
@@ -1013,7 +1013,7 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
 
   security.declareProtected( Permissions.AccessContentsInformation, 'getParent' )
   getParent = getParentValue # Compatibility
-    
+
   security.declareProtected( Permissions.AccessContentsInformation, 'getUid' )
   def getUid(self):
     """
@@ -1204,7 +1204,7 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
 
   security.declareProtected( Permissions.View, '_getRelatedValueList' )
   def _getRelatedValueList(self, id, spec=(), filter=None, portal_type=(), strict=0):
-    return self._getCategoryTool().getRelatedValueList(self, id, 
+    return self._getCategoryTool().getRelatedValueList(self, id,
                           spec=spec, filter=filter, portal_type=portal_type, strict=strict)
 
   security.declareProtected( Permissions.View, 'getRelatedValueList' )
@@ -1656,7 +1656,7 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
       args / kw required since we must follow API
     """
     self.activate(**kw).immediateReindexObject(*args, **kw)
-      
+
   security.declarePublic('recursiveReindexObject')
   recursiveReindexObject = reindexObject
 
@@ -1669,7 +1669,7 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
     # In ERP5, simply reindex all objects.
     #LOG('reindexObjectSecurity', 0, 'self = %r, self.getPath() = %r' % (self, self.getPath()))
     self.reindexObject()
-            
+
   def immediateQueueCataloggedObject(self, *args, **kw):
     if self.isIndexable:
       catalog_tool = getToolByName(self, 'portal_catalog', None)
@@ -1848,7 +1848,7 @@ class Base( CopyContainer, PortalContent, ActiveObject, ERP5PropertyManager ):
     from Products.ERP5Type.Error import Error
     return Error(**kw)
 
-  
+
   _temp_isIndexable = 0
 
   def _temp_reindexObject(self, *args, **kw):
-- 
2.30.9