Commit 817a204d authored by Alexandre Boeglin's avatar Alexandre Boeglin

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