[Erp5-report] r40763 arnaud.fontaine - in /erp5/trunk/products/ERP5Type: Core/ PropertyShee...
nobody at svn.erp5.org
nobody at svn.erp5.org
Fri Nov 26 11:35:00 CET 2010
Author: arnaud.fontaine
Date: Fri Nov 26 11:34:51 2010
New Revision: 40763
URL: http://svn.erp5.org?rev=40763&view=rev
Log:
Add Category Membership Arity Constraint for ZODB Property Sheets
Added:
erp5/trunk/products/ERP5Type/Core/CategoryMembershipArityConstraint.py
- copied, changed from r40596, erp5/trunk/products/ERP5Type/Constraint/CategoryMembershipArity.py
erp5/trunk/products/ERP5Type/PropertySheet/CategoryMembershipArityConstraint.py
Modified:
erp5/trunk/products/ERP5Type/PropertySheet/__init__.py
erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py
Copied: erp5/trunk/products/ERP5Type/Core/CategoryMembershipArityConstraint.py (from r40596, erp5/trunk/products/ERP5Type/Constraint/CategoryMembershipArity.py)
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Core/CategoryMembershipArityConstraint.py?p2=erp5/trunk/products/ERP5Type/Core/CategoryMembershipArityConstraint.py&p1=erp5/trunk/products/ERP5Type/Constraint/CategoryMembershipArity.py&r1=40596&r2=40763&rev=40763&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Constraint/CategoryMembershipArity.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Core/CategoryMembershipArityConstraint.py [utf8] Fri Nov 26 11:34:51 2010
@@ -1,8 +1,9 @@
##############################################################################
#
-# Copyright (c) 2002, 2005 Nexedi SARL and Contributors. All Rights Reserved.
-# Sebastien Robin <seb at nexedi.com>
-# Romain Courteaud <romain at nexedi.com>
+# Copyright (c) 2002-2010 Nexedi SARL and Contributors. All Rights Reserved.
+# Sebastien Robin <seb at nexedi.com>
+# Romain Courteaud <romain at nexedi.com>
+# Arnaud Fontaine <arnaud.fontaine at nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
@@ -27,90 +28,82 @@
#
##############################################################################
-from Constraint import Constraint
+from Products.ERP5Type.mixin.constraint import ConstraintMixin
+from AccessControl import ClassSecurityInfo
+from Products.ERP5Type import Permissions, PropertySheet
-class CategoryMembershipArity(Constraint):
+class CategoryMembershipArityConstraint(ConstraintMixin):
"""
- This constraint checks if an object respects the arity.
+ This constraint checks if an object respects the arity.
- For example we can check if every Order has at least one source.
- Configuration example:
- { 'id' : 'source',
- 'description' : '',
- 'type' : 'CategoryMembershipArity',
- 'min_arity' : '1',
- 'max_arity' : '1',
- 'portal_type' : ('Organisation', ),
- 'base_category' : ('source',)
- 'condition' : 'python: object.getPortalType() == 'Foo',
- },
+ This is only relevant for ZODB Property Sheets (filesystem Property
+ Sheets rely on Products.ERP5Type.Constraint.CategoryMembershipArity
+ instead).
+
+ For example, if we would like to check whether the object respects a
+ minimum arity of '1' and a maximum arity of '1 for the Portal Type
+ 'Organisation' and the Base Category 'source', then we would create
+ a 'Category Membership Arity Constraint' within that Property Sheet
+ and set 'Minimum arity' to '1', 'Maximum Arity' to '1', 'Portal
+ Types' to 'Organisation', 'Base Categories' to 'source', then set
+ the 'Predicate' if necessary (known as 'condition' for filesystem
+ Property Sheets).
"""
+ meta_type = 'ERP5 Category Membership Arity Constraint'
+ portal_type = 'Category Membership Arity Constraint'
- _message_id_list = ['message_arity_too_small',
- 'message_arity_not_in_range',
- 'message_arity_with_portal_type_to_small',
- 'message_arity_with_portal_type_not_in_range']
-
- message_arity_too_small = "Arity Error for Relation ${base_category}"\
- ", arity is equal to ${current_arity} but "\
- "should be at least ${min_arity}"
- message_arity_not_in_range = "Arity Error for Relation ${base_category}"\
- ", arity is equal to ${current_arity} but "\
- "should be between ${min_arity} and ${max_arity}"
- message_arity_with_portal_type_to_small = "Arity Error for Relation"\
- " ${base_category} and Type ${portal_type}"\
- ", arity is equal to ${current_arity} but "\
- "should be at least ${min_arity}"
-
- message_arity_with_portal_type_not_in_range = "Arity Error for Relation"\
- " ${base_category} and Type ${portal_type}"\
- ", arity is equal to ${current_arity} but "\
- "should be between ${min_arity} and ${max_arity}"
-
- def _calculateArity(self, obj):
- base_category = self.constraint_definition['base_category']
- portal_type = self.constraint_definition['portal_type']
- return len(obj.getCategoryMembershipList(base_category,
- portal_type=portal_type))
+ # Declarative security
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+ property_sheets = (PropertySheet.SimpleItem,
+ PropertySheet.Predicate,
+ PropertySheet.Reference,
+ PropertySheet.CategoryMembershipArityConstraint)
+
+ def _calculateArity(self, obj, base_category_list, portal_type_list):
+ return len(obj.getCategoryMembershipList(base_category_list,
+ portal_type=portal_type_list))
def checkConsistency(self, obj, fixit=0):
- """Check the object's consistency.
- We are looking the definition of the constraing where
- are defined the minimum and the maximum arity, and the
- list of objects we wants to check the arity.
"""
- if not self._checkConstraintCondition(obj):
+ Check the object's consistency. We are looking at the definition
+ of the constraint where the minimum and the maximum arities are
+ defined, and the list of objects we wants to check the arity for
+ """
+ if not self.test(obj):
return []
- error_list = []
- # Retrieve configuration values from PropertySheet (_constraints)
- base_category = self.constraint_definition['base_category']
- min_arity = int(self.constraint_definition['min_arity'])
- max_arity = None
- if 'max_arity' in self.constraint_definition:
- max_arity = int(self.constraint_definition['max_arity'])
- portal_type = self.constraint_definition['portal_type']
+
+ # Retrieve configuration values from PropertySheet
+ base_category_list = self.getConstraintBaseCategoryList()
+ min_arity = self.getMinArity()
+ max_arity = self.getMaxArity()
+ portal_type_list = self.getConstraintPortalTypeList()
+
# Check arity and compare it with the min and max
- arity = self._calculateArity(obj)
- if not (max_arity is None and (min_arity <= arity)
- or (min_arity <= arity <= max_arity)):
- mapping = dict(base_category=base_category,
- portal_type=str(portal_type),
- current_arity=arity,
- min_arity=min_arity,
- max_arity=max_arity,)
- # Generate error message
- if portal_type is not ():
- if max_arity is None:
- message_id = 'message_arity_with_portal_type_to_small'
- else:
- message_id = 'message_arity_with_portal_type_not_in_range'
+ arity = self._calculateArity(obj, base_category_list, portal_type_list)
+ if (max_arity is None and min_arity <= arity) or \
+ min_arity <= arity <= max_arity:
+ return []
+
+ mapping = dict(base_category=base_category_list,
+ portal_type=str(portal_type_list),
+ current_arity=arity,
+ min_arity=min_arity,
+ max_arity=max_arity)
+
+ # Generate an error message
+ if len(portal_type_list) == 0:
+ if max_arity is None:
+ message_id = 'message_arity_with_portal_type_too_small'
+ else:
+ message_id = 'message_arity_with_portal_type_not_in_range'
+ else:
+ if max_arity is None:
+ message_id = 'message_arity_too_small'
else:
- if max_arity is None:
- message_id = 'message_arity_too_small'
- else:
- message_id = 'message_arity_not_in_range'
-
- # Add error
- error_list.append(self._generateError(obj,
- self._getMessage(message_id), mapping))
- return error_list
+ message_id = 'message_arity_not_in_range'
+
+ return [self._generateError(obj,
+ self._getMessage(message_id),
+ mapping)]
Added: erp5/trunk/products/ERP5Type/PropertySheet/CategoryMembershipArityConstraint.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/PropertySheet/CategoryMembershipArityConstraint.py?rev=40763&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Type/PropertySheet/CategoryMembershipArityConstraint.py (added)
+++ erp5/trunk/products/ERP5Type/PropertySheet/CategoryMembershipArityConstraint.py [utf8] Fri Nov 26 11:34:51 2010
@@ -0,0 +1,76 @@
+##############################################################################
+#
+# Copyright (c) 2010 Nexedi SARL and Contributors. All Rights Reserved.
+# Arnaud Fontaine <arnaud.fontaine at nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+class CategoryMembershipArityConstraint:
+ """
+ Define a Category Membership Arity Constraint for ZODB Property Sheets
+ """
+ _properties = (
+ { 'id': 'min_arity',
+ 'type': 'int',
+ 'description' : 'Minimum arity' },
+ { 'id': 'max_arity',
+ 'type': 'int',
+ 'description' : 'Maximum arity' },
+ { 'id': 'constraint_portal_type',
+ 'type': 'lines',
+ 'description' : 'Portal types',
+ 'default': () },
+ { 'id': 'constraint_base_category',
+ 'type': 'lines',
+ 'description' : 'Base categories',
+ 'default': () },
+ { 'id': 'message_arity_too_small',
+ 'type': 'string',
+ 'description' : 'Error message when the arity for the relation '\
+ 'is too small',
+ 'default': 'Arity Error for Relation ${base_category}, arity is '\
+ 'equal to ${current_arity} but should be at least '\
+ '${min_arity}' },
+ { 'id': 'message_arity_not_in_range',
+ 'type': 'string',
+ 'description' : 'Error message when the arity for the relation '\
+ 'is out of bounds',
+ 'default': 'Arity Error for Relation ${base_category}, arity is '\
+ 'equal to ${current_arity} but should be between '\
+ '${min_arity} and ${max_arity}' },
+ { 'id': 'message_arity_with_portal_type_too_small',
+ 'type': 'string',
+ 'description' : 'Error message when the arity for the relation '\
+ 'and portal type is too small',
+ 'default': 'Arity Error for Relation ${base_category} and Type '\
+ '${portal_type}, arity is equal to ${current_arity} '\
+ 'but should be at least ${min_arity}' },
+ { 'id': 'message_arity_with_portal_type_not_in_range',
+ 'type': 'string',
+ 'description' : 'Error message when the arity for the relation '\
+ 'and portal type is out of bounds',
+ 'default': 'Arity Error for Relation ${base_category} and Type '\
+ '${portal_type}, arity is equal to ${current_arity} '\
+ 'but should be between ${min_arity} and ${max_arity}' },
+ )
Modified: erp5/trunk/products/ERP5Type/PropertySheet/__init__.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/PropertySheet/__init__.py?rev=40763&r1=40762&r2=40763&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/PropertySheet/__init__.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/PropertySheet/__init__.py [utf8] Fri Nov 26 11:34:51 2010
@@ -21,3 +21,4 @@ from CategoryExistenceConstraint import
from PropertyExistenceConstraint import PropertyExistenceConstraint
from AttributeEqualityConstraint import AttributeEqualityConstraint
from ContentExistenceConstraint import ContentExistenceConstraint
+from CategoryMembershipArityConstraint import CategoryMembershipArityConstraint
Modified: erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py?rev=40763&r1=40762&r2=40763&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] Fri Nov 26 11:34:51 2010
@@ -366,10 +366,32 @@ class TestZodbPropertySheet(ERP5TypeTest
constraint_attribute_value='python: ("sub_category1", "sub_category2")')
def _newContentExistenceConstraint(self):
+ """
+ Create a new Content Existence Constraint within test Property
+ Sheet
+ """
self.test_property_sheet.newContent(
reference='test_content_existence_constraint',
portal_type='Content Existence Constraint',
- constraint_portal_type='python: ("Folder")')
+ constraint_portal_type='python: ("Content Existence Constraint")')
+
+ def _newCategoryMembershipArityConstraint(self):
+ """
+ Create a new Category Membership Arity Constraint within test
+ Property Sheet
+ """
+ reference = 'test_category_membership_arity_constraint'
+
+ self.getPortal().portal_categories.newContent(
+ id=reference, portal_type='Base Category')
+
+ self.test_property_sheet.newContent(
+ reference=reference,
+ portal_type='Category Membership Arity Constraint',
+ min_arity=1,
+ max_arity=1,
+ constraint_portal_type=('Test Migration',),
+ constraint_base_category=(reference,))
def afterSetUp(self):
"""
@@ -405,6 +427,10 @@ class TestZodbPropertySheet(ERP5TypeTest
# Sheet
self._newContentExistenceConstraint()
+ # Create a Category Membership Arity Constraint in the test
+ # Property Sheet
+ self._newCategoryMembershipArityConstraint()
+
# Create all the test Properties
for operation_type in ('change', 'delete', 'assign'):
self._newStandardProperty(operation_type)
@@ -430,7 +456,7 @@ class TestZodbPropertySheet(ERP5TypeTest
# the migration has been finished
type_zodb_property_sheet_list=('TestMigration',),
type_base_category_list=('test_category_existence_constraint',),
- type_allowed_content_type_list=('Folder',))
+ type_allowed_content_type_list=('Content Existence Constraint',))
# Create a test module, meaningful to force generation of
# TestMigration accessor holders and check the constraints
@@ -836,7 +862,18 @@ class TestZodbPropertySheet(ERP5TypeTest
self._checkConstraint('test_content_existence_constraint',
self.test_module.newContent,
id='Test Content Existence Constraint',
- portal_type='Folder')
+ portal_type='Content Existence Constraint')
+
+ def testCategoryMembershipArityConstraint(self):
+ """
+ Take the test module and check whether the Category Membership
+ Arity Constraint is there. Until a Base Category is set on the
+ Test Module, the constraint should fail
+ """
+ self._checkConstraint('test_category_membership_arity_constraint',
+ self.test_module.setCategoryList,
+ ('test_category_membership_arity_constraint/'\
+ 'Test Migration',))
TestZodbPropertySheet = skip("ZODB Property Sheets code is not enabled yet")(
TestZodbPropertySheet)
More information about the Erp5-report
mailing list