Commit 08a60a2d authored by Arnaud Fontaine's avatar Arnaud Fontaine

ExpressionMixin: Allow to specify the property storing the TALES Expression.

Until now it was only used in ERP5Catalog where the expression property is
`expression` for both Python Script and SQL Method but this is a common pattern
and will also needed for ERP5Workflow.
parent e8b41f91
...@@ -64,7 +64,7 @@ class PythonScriptThroughZMI(XMLObject): ...@@ -64,7 +64,7 @@ class PythonScriptThroughZMI(XMLObject):
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
assert False assert False
class PythonScript(XMLObject, ZopePythonScript, ExpressionMixin): class PythonScript(XMLObject, ZopePythonScript, ExpressionMixin('expression')):
""" Script python for ERP5 """ Script python for ERP5
""" """
......
...@@ -60,7 +60,7 @@ def manage_addSQLMethod(self, id, title='', ...@@ -60,7 +60,7 @@ def manage_addSQLMethod(self, id, title='',
REQUEST['RESPONSE'].redirect( 'manage_main' ) REQUEST['RESPONSE'].redirect( 'manage_main' )
return c return c
class SQLMethod(XMLObject, ZSQL, ExpressionMixin): class SQLMethod(XMLObject, ZSQL, ExpressionMixin('expression')):
"""SQLMethod for ERP5. """SQLMethod for ERP5.
""" """
......
...@@ -29,30 +29,62 @@ from AccessControl import ClassSecurityInfo ...@@ -29,30 +29,62 @@ from AccessControl import ClassSecurityInfo
from Products.CMFCore.Expression import Expression from Products.CMFCore.Expression import Expression
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Globals import InitializeClass from Products.ERP5Type.Globals import InitializeClass
from Products.ERP5Type.Utils import convertToUpperCase
class ExpressionMixin: def ExpressionMixin(property_reference='expression'):
security = ClassSecurityInfo() """
Mixin for a common pattern where ERP5 objects stores a TALES Expression as text.
def _setExpression(self, value): Usage examples:
Python Script/SQL Method: expression_property (reference=expression)
GuardableMixin: guard_expression_property (reference=guard_expression)
CMFCore.Expression already stores the Expression text as 'text' property and
create a volatile for the instance, so this may seem redundant and we may
have stored an Expression instance directly on the object. However this
would make exported objects depend on CMFCore.Expression and not storing
"directly" user input.
"""
property_reference_uppercase = convertToUpperCase(property_reference)
volatile_attribute_name = '_v_' + property_reference + '_instance'
def _setter(self, value):
"""
_set<PropertyReference>()
"""
try: try:
del self._v_expression_instance delattr(self, volatile_attribute_name)
except AttributeError: except AttributeError:
pass pass
self._baseSetExpression(value) getattr(self, '_baseSet' + property_reference_uppercase)(value)
security.declareProtected(Permissions.AccessContentsInformation, 'getExpressionInstance') def getter(self, default=None):
def getExpressionInstance(self, default=None): """
get<PropertyReference>Instance()
"""
try: try:
return self._v_expression_instance return getattr(self, volatile_attribute_name)
except AttributeError: except AttributeError:
expression = self.getExpression() expression = getattr(self, 'get' + property_reference_uppercase)()
# Check if the expression is not None, because Expression(<expression>) # Check if the expression is not None, because Expression(<expression>)
# raises an error in case `expression` is empty or None. # raises an error in case `expression` is empty or None.
if expression: if expression:
result = Expression(expression) result = Expression(expression)
else: else:
result = None result = None
self._v_expression_instance = result setattr(self, volatile_attribute_name, result)
return result return result
InitializeClass(ExpressionMixin) class ExpressionMixin:
security = ClassSecurityInfo()
_setter.__name__ = '_set' + property_reference_uppercase
setattr(ExpressionMixin, _setter.__name__, _setter)
getter.__name__ = 'get' + property_reference_uppercase + 'Instance'
setattr(ExpressionMixin, getter.__name__, getter)
ExpressionMixin.security.declareProtected(Permissions.AccessContentsInformation,
getter.__name__)
InitializeClass(ExpressionMixin)
return ExpressionMixin
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