From c89481d790d9bd9cfa54e9547cefbbe136e6d65b Mon Sep 17 00:00:00 2001 From: Arnaud Fontaine <arnaud.fontaine@nexedi.com> Date: Fri, 26 Nov 2010 07:09:08 +0000 Subject: [PATCH] Clean up the code of ZODB Property Sheets Documents by setting default values in their Property Sheets git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@40753 20353a03-c40f-0410-a6d1-a30d3c3de9de --- .../Core/AttributeEqualityConstraint.py | 17 ++--------- .../Core/CategoryExistenceConstraint.py | 30 ++++++++----------- .../Core/ContentExistenceConstraint.py | 19 ++++-------- .../Core/PropertyExistenceConstraint.py | 17 ++++------- .../AttributeEqualityConstraint.py | 9 ++++-- .../CategoryExistenceConstraint.py | 14 ++++++--- .../ContentExistenceConstraint.py | 10 +++++-- .../PropertyExistenceConstraint.py | 11 +++++-- product/ERP5Type/mixin/constraint.py | 16 ++++++++-- 9 files changed, 69 insertions(+), 74 deletions(-) diff --git a/product/ERP5Type/Core/AttributeEqualityConstraint.py b/product/ERP5Type/Core/AttributeEqualityConstraint.py index 0d39be0f68..6b511a8ad8 100644 --- a/product/ERP5Type/Core/AttributeEqualityConstraint.py +++ b/product/ERP5Type/Core/AttributeEqualityConstraint.py @@ -32,8 +32,6 @@ from Products.ERP5Type.mixin.constraint import ConstraintMixin from AccessControl import ClassSecurityInfo from Products.ERP5Type import Permissions, PropertySheet -from Products.CMFCore.Expression import Expression -from Products.ERP5Type.Utils import createExpressionContext class AttributeEqualityConstraint(ConstraintMixin): """ @@ -66,14 +64,6 @@ class AttributeEqualityConstraint(ConstraintMixin): PropertySheet.Reference, PropertySheet.AttributeEqualityConstraint) - # Define by default error messages - _message_id_list = ['message_invalid_attribute_value', - 'message_invalid_attribute_value_fixed'] - message_invalid_attribute_value = "Attribute ${attribute_name} "\ - "value is ${current_value} but should be ${expected_value}" - message_invalid_attribute_value_fixed = "Attribute ${attribute_name} "\ - "value is ${current_value} but should be ${expected_value} (Fixed)" - security.declareProtected(Permissions.AccessContentsInformation, 'checkConsistency') def checkConsistency(self, obj, fixit=False): @@ -93,11 +83,8 @@ class AttributeEqualityConstraint(ConstraintMixin): identical = True # The expected value of the attribute is a TALES Expression - attribute_expected_value_expression = Expression( - self.getConstraintAttributeValue()) - - attribute_expected_value = attribute_expected_value_expression( - createExpressionContext(obj)) + attribute_expected_value = self._getExpressionValue( + obj, self.getConstraintAttributeValue()) attribute_value = obj.getProperty(attribute_name) diff --git a/product/ERP5Type/Core/CategoryExistenceConstraint.py b/product/ERP5Type/Core/CategoryExistenceConstraint.py index 461d96d17c..40bb07232a 100644 --- a/product/ERP5Type/Core/CategoryExistenceConstraint.py +++ b/product/ERP5Type/Core/CategoryExistenceConstraint.py @@ -53,17 +53,9 @@ class CategoryExistenceConstraint(ConstraintMixin): PropertySheet.Reference, PropertySheet.CategoryExistenceConstraint) - _message_id_list = [ 'message_category_not_set', - 'message_category_not_associated_with_portal_type' ] - message_category_not_set = "Category existence error for base"\ - " category ${base_category}, this category is not defined" - message_category_not_associated_with_portal_type = "Category existence"\ - " error for base category ${base_category}, this"\ - " document has no such category" - - def _calculateArity(self, obj, base_category, portal_type): + def _calculateArity(self, obj, base_category, portal_type_list): return len(obj.getCategoryMembershipList(base_category, - portal_type=portal_type)) + portal_type=portal_type_list)) security.declareProtected(Permissions.AccessContentsInformation, 'checkConsistency') @@ -71,18 +63,18 @@ class CategoryExistenceConstraint(ConstraintMixin): """ Check the object's consistency. """ - error_list = [] if not self.test(obj): return [] - portal_type = self.getConstraintPortalTypeList() or () + error_list = [] + portal_type_list = self.getConstraintPortalTypeList() # For each attribute name, we check if defined - for base_category in self.getConstraintBaseCategoryList() or (): + for base_category in self.getConstraintBaseCategoryList(): mapping = dict(base_category=base_category) # Check existence of base category if base_category not in obj.getBaseCategoryList(): error_message = 'message_category_not_associated_with_portal_type' - elif self._calculateArity(obj, base_category, portal_type) == 0: + elif self._calculateArity(obj, base_category, portal_type_list) == 0: error_message = 'message_category_not_set' else: error_message = None @@ -91,7 +83,9 @@ class CategoryExistenceConstraint(ConstraintMixin): if error_message: error_list.append( self._generateError(obj, - self._getMessage(error_message), mapping)) + self._getMessage(error_message), + mapping)) + return error_list class CategoryAcquiredExistenceConstraint(CategoryExistenceConstraint): @@ -101,6 +95,6 @@ class CategoryAcquiredExistenceConstraint(CategoryExistenceConstraint): Sheets (filesystem Property Sheets rely on Products.ERP5Type.Constraint.CategoryExistence instead). """ - def _calculateArity(self, obj, base_category, portal_type): - return len(obj.getAcquiredCategoryMembershipList(base_category, - portal_type=portal_type)) + def _calculateArity(self, obj, base_category, portal_type_list): + return len(obj.getAcquiredCategoryMembershipList( + base_category, portal_type=portal_type_list)) diff --git a/product/ERP5Type/Core/ContentExistenceConstraint.py b/product/ERP5Type/Core/ContentExistenceConstraint.py index 955563eb3b..06771b3574 100644 --- a/product/ERP5Type/Core/ContentExistenceConstraint.py +++ b/product/ERP5Type/Core/ContentExistenceConstraint.py @@ -1,7 +1,8 @@ ############################################################################## # -# Copyright (c) 2006 Nexedi SARL and Contributors. All Rights Reserved. -# Romain Courteaud <romain@nexedi.com> +# Copyright (c) 2006-2010 Nexedi SARL and Contributors. All Rights Reserved. +# Romain Courteaud <romain@nexedi.com> +# Arnaud Fontaine <arnaud.fontaine@nexedi.com> # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsability of assessing all potential @@ -29,8 +30,6 @@ from Products.ERP5Type.mixin.constraint import ConstraintMixin from AccessControl import ClassSecurityInfo from Products.ERP5Type import Permissions, PropertySheet -from Products.CMFCore.Expression import Expression -from Products.ERP5Type.Utils import createExpressionContext class ContentExistenceConstraint(ConstraintMixin): """ @@ -63,14 +62,6 @@ class ContentExistenceConstraint(ConstraintMixin): PropertySheet.Reference, PropertySheet.ContentExistenceConstraint) - # Define by default error messages - _message_id_list = [ 'message_no_subobject', - 'message_no_subobject_portal_type' ] - - message_no_subobject = "The document does not contain any subobject" - message_no_subobject_portal_type = "The document does not contain any"\ - " subobject of portal portal type ${portal_type}" - def checkConsistency(self, obj, fixit=0): """ Checks that object contains at least one subobject and, if a list @@ -79,8 +70,8 @@ class ContentExistenceConstraint(ConstraintMixin): if not self.test(obj): return [] - portal_type = Expression(self.getConstraintPortalType())( - createExpressionContext(obj)) + portal_type = self._getExpressionValue(obj, + self.getConstraintPortalType()) # If there is at least one subobject with the given Portal Type, # then return now diff --git a/product/ERP5Type/Core/PropertyExistenceConstraint.py b/product/ERP5Type/Core/PropertyExistenceConstraint.py index a5794ae65f..5791af3694 100644 --- a/product/ERP5Type/Core/PropertyExistenceConstraint.py +++ b/product/ERP5Type/Core/PropertyExistenceConstraint.py @@ -59,26 +59,18 @@ class PropertyExistenceConstraint(ConstraintMixin): PropertySheet.Reference, PropertySheet.PropertyExistenceConstraint) - # Define by default error messages - _message_id_list = ['message_no_such_property', - 'message_property_not_set'] - message_no_such_property = "Property existence error for property "\ - "${property_id}, this document has no such property" - message_property_not_set = "Property existence error for property "\ - "${property_id}, this property is not defined" - security.declareProtected(Permissions.AccessContentsInformation, 'checkConsistency') def checkConsistency(self, obj, fixit=0): """ Check the object's consistency. """ - error_list = [] if not self.test(obj): return [] + error_list = [] # For each attribute name, we check if defined - for property_id in self.getConstraintPropertyList() or (): + for property_id in self.getConstraintPropertyList(): # Check existence of property mapping = dict(property_id=property_id) if not obj.hasProperty(property_id): @@ -91,6 +83,7 @@ class PropertyExistenceConstraint(ConstraintMixin): error_message_id = None if error_message_id: - error_list.append(self._generateError(obj, - self._getMessage(error_message_id), mapping)) + error_list.append(self._generateError( + obj, self._getMessage(error_message_id), mapping)) + return error_list diff --git a/product/ERP5Type/PropertySheet/AttributeEqualityConstraint.py b/product/ERP5Type/PropertySheet/AttributeEqualityConstraint.py index 8a2b98ae9a..c846bb8790 100644 --- a/product/ERP5Type/PropertySheet/AttributeEqualityConstraint.py +++ b/product/ERP5Type/PropertySheet/AttributeEqualityConstraint.py @@ -40,8 +40,13 @@ class AttributeEqualityConstraint: 'description' : 'Valid values of the Attribute' }, { 'id': 'message_invalid_attribute_value', 'type': 'string', - 'description' : 'Error message when the attribute value is invalid' }, + 'description' : 'Error message when the attribute value is invalid', + 'default': 'Attribute ${attribute_name} value is ${current_value} '\ + 'but should be ${expected_value}' }, { 'id': 'message_invalid_attribute_value_fixed', 'type': 'string', - 'description' : 'Error message when the attribute value is invalid but has been fixed' }, + 'description' : 'Error message when the attribute value is '\ + 'invalid but has been fixed', + 'default': 'Attribute ${attribute_name} value is ${current_value} '\ + 'but should be ${expected_value} (Fixed)'}, ) diff --git a/product/ERP5Type/PropertySheet/CategoryExistenceConstraint.py b/product/ERP5Type/PropertySheet/CategoryExistenceConstraint.py index 3a42a53ccf..0e6fb79160 100644 --- a/product/ERP5Type/PropertySheet/CategoryExistenceConstraint.py +++ b/product/ERP5Type/PropertySheet/CategoryExistenceConstraint.py @@ -33,14 +33,20 @@ class CategoryExistenceConstraint: _properties = ( { 'id': 'constraint_base_category', 'type': 'lines', - 'description' : 'Categories to check the existence for' }, + 'description' : 'Categories to check the existence for', + 'default': () }, { 'id': 'constraint_portal_type', 'type': 'lines', - 'description' : 'Portal type' }, + 'description' : 'Portal types', + 'default': () }, { 'id': 'message_category_not_set', 'type': 'string', - 'description' : 'Error message when the category is not defined' }, + 'description' : 'Error message when the category is not defined', + 'default': 'Category existence error for base category '\ + '${base_category}, this category is not defined' }, { 'id': 'message_category_not_associated_with_portal_type', 'type': 'string', - 'description' : 'Error message when there is no such category' }, + 'description' : 'Error message when there is no such category', + 'default': 'Category existence error for base category '\ + '${base_category}, this document has no such category' }, ) diff --git a/product/ERP5Type/PropertySheet/ContentExistenceConstraint.py b/product/ERP5Type/PropertySheet/ContentExistenceConstraint.py index de964dc1f0..a905f5349b 100644 --- a/product/ERP5Type/PropertySheet/ContentExistenceConstraint.py +++ b/product/ERP5Type/PropertySheet/ContentExistenceConstraint.py @@ -34,12 +34,16 @@ class ContentExistenceConstraint: # TALES Expression { 'id': 'constraint_portal_type', 'type': 'string', - 'description' : 'Portal type', + 'description' : 'Portal types', 'default': 'python: ()' }, { 'id': 'message_no_subobject', 'type': 'string', - 'description' : 'Error message when there is no subobject' }, + 'description' : 'Error message when there is no subobject', + 'default': 'The document does not contain any subobject' }, { 'id': 'message_no_subobject_portal_type', 'type': 'string', - 'description' : 'Error message when there is no subobject of the given portal type' }, + 'description' : 'Error message when there is no subobject of the '\ + 'given portal type', + 'default': 'The document does not contain any subobject of portal '\ + 'portal type ${portal_type}' }, ) diff --git a/product/ERP5Type/PropertySheet/PropertyExistenceConstraint.py b/product/ERP5Type/PropertySheet/PropertyExistenceConstraint.py index 9861a73977..09023ad91f 100644 --- a/product/ERP5Type/PropertySheet/PropertyExistenceConstraint.py +++ b/product/ERP5Type/PropertySheet/PropertyExistenceConstraint.py @@ -33,11 +33,16 @@ class PropertyExistenceConstraint: _properties = ( { 'id': 'constraint_property', 'type': 'lines', - 'description' : 'Properties to check the existence for' }, + 'description' : 'Properties to check the existence for', + 'default': () }, { 'id': 'message_no_such_property', 'type': 'string', - 'description' : 'Error message when there is no such property' }, + 'description' : 'Error message when there is no such property', + 'default': 'Property existence error for property ${property_id}, '\ + 'this document has no such property' }, { 'id': 'message_property_not_set', 'type': 'string', - 'description' : 'Error message when the property is not set' }, + 'description' : 'Error message when the property is not set', + 'default': 'Property existence error for property ${property_id}, '\ + 'this property is not defined' }, ) diff --git a/product/ERP5Type/mixin/constraint.py b/product/ERP5Type/mixin/constraint.py index 2ae8ecdbe9..5dbaf52158 100644 --- a/product/ERP5Type/mixin/constraint.py +++ b/product/ERP5Type/mixin/constraint.py @@ -35,7 +35,8 @@ from zope.interface import implements from Products.ERP5Type.Core.Predicate import Predicate from AccessControl import ClassSecurityInfo from Products.ERP5Type import Permissions -from Products.ERP5Type.Utils import UpperCase +from Products.ERP5Type.Utils import UpperCase, createExpressionContext +from Products.CMFCore.Expression import Expression class ConstraintMixin(Predicate): """ @@ -54,8 +55,6 @@ class ConstraintMixin(Predicate): __allow_access_to_unprotected_subobjects__ = 1 implements( IConstraint, ) - _message_id_list = [] - def _getMessage(self, message_id): """ Get the message corresponding to this message_id. @@ -101,3 +100,14 @@ class ConstraintMixin(Predicate): XXX: remove as soon as the code is stable """ return self.asContext() + + def _getExpressionValue(self, obj, expression_string): + """ + Get the Python value from an Expression string, but check before + whether it is None as a getter may returns the default value which + could be None + """ + if expression_string is None: + return None + + return Expression(expression_string)(createExpressionContext(obj)) -- 2.30.9