Commit 522126a3 authored by Arnaud Fontaine's avatar Arnaud Fontaine

WIP: ZODB Components: providesIFoo() getters were only created for FS Interfaces.

Add them to BaseAccessorHolder (like `Base Category` accessors) instead of
Base class so they can be regenerated on reset while not having to remove
ZODB Components from Base class on reset.

TODO: CachingMethod(provides)? (de965679)
parent 5a7d6652
Pipeline #8906 failed with stage
in 0 seconds
...@@ -800,17 +800,21 @@ class Base( ...@@ -800,17 +800,21 @@ class Base(
self.reindexObject() self.reindexObject()
security.declarePublic('provides') security.declarePublic('provides')
@classmethod
def provides(cls, interface_name): def provides(cls, interface_name):
""" """
Check if the current class provides a particular interface from ERP5Type's Check if the current class provides a particular interface from ERP5Type's
interfaces registry interfaces registry
""" """
from Products.ERP5Type.dynamic.portal_type_class import _importComponentClass
import erp5.component.interface
interface = _importComponentClass(erp5.component.interface, interface_name)
if interface is None:
interface = getattr(interfaces, interface_name, None) interface = getattr(interfaces, interface_name, None)
if interface is not None: if interface is not None:
return interface.implementedBy(cls) return interface.implementedBy(cls)
return False return False
provides = classmethod(CachingMethod(provides, 'Base.provides',
cache_factory='erp5_ui_long'))
def _aq_key(self): def _aq_key(self):
return (self.portal_type, self.__class__) return (self.portal_type, self.__class__)
......
...@@ -721,15 +721,15 @@ def registerBaseCategories(property_sheet): ...@@ -721,15 +721,15 @@ def registerBaseCategories(property_sheet):
base_category_dict[bc] = 1 base_category_dict[bc] = 1
def importLocalInterface(module_id, path = None, is_erp5_type=False): def importLocalInterface(module_id, path = None, is_erp5_type=False):
def provides(class_id): """
# Create interface getter Import filesystem Interface and add it to Products.ERP5Type.interfaces,
accessor_name = 'provides' + class_id only meaningful for filesystem Interface as they can all be loaded at
setattr(BaseClass, accessor_name, lambda self: self.provides(class_id)) ERP5 startup.
BaseClass.security.declarePublic(accessor_name)
Corresponding providesI<class_id> accessor is added to BaseAccessorHolder.
"""
class_id = "I" + convertToUpperCase(module_id) class_id = "I" + convertToUpperCase(module_id)
if is_erp5_type: if not is_erp5_type:
provides(class_id)
else:
if path is None: if path is None:
instance_home = getConfiguration().instancehome instance_home = getConfiguration().instancehome
path = os.path.join(instance_home, "interfaces") path = os.path.join(instance_home, "interfaces")
...@@ -742,7 +742,6 @@ def importLocalInterface(module_id, path = None, is_erp5_type=False): ...@@ -742,7 +742,6 @@ def importLocalInterface(module_id, path = None, is_erp5_type=False):
for k, v in module.__dict__.iteritems(): for k, v in module.__dict__.iteritems():
if type(v) is InterfaceClass and v is not Interface: if type(v) is InterfaceClass and v is not Interface:
setattr(interfaces, k, v) setattr(interfaces, k, v)
provides(class_id)
def importLocalConstraint(class_id, path = None): def importLocalConstraint(class_id, path = None):
import Products.ERP5Type.Constraint import Products.ERP5Type.Constraint
......
...@@ -151,6 +151,14 @@ def _generateBaseAccessorHolder(portal): ...@@ -151,6 +151,14 @@ def _generateBaseAccessorHolder(portal):
base_category_id, base_category_id,
category_tool) category_tool)
# Create providesIFoo() getters of ZODB/FS Interface classes
def provides(class_id):
accessor_name = 'provides' + class_id
setattr(accessor_holder, accessor_name, lambda self: self.provides(class_id))
accessor_holder.security.declarePublic(accessor_name)
for class_id in portal.portal_types.getInterfaceTypeList():
provides(class_id)
erp5.accessor_holder.registerAccessorHolder(accessor_holder) erp5.accessor_holder.registerAccessorHolder(accessor_holder)
return accessor_holder return accessor_holder
......
...@@ -3036,6 +3036,7 @@ class %s(Interface): ...@@ -3036,6 +3036,7 @@ class %s(Interface):
methods from Person Document methods from Person Document
""" """
import erp5.portal_type import erp5.portal_type
import erp5.accessor_holder
person_type = self.portal.portal_types.Person person_type = self.portal.portal_types.Person
person_type_class = erp5.portal_type.Person person_type_class = erp5.portal_type.Person
...@@ -3043,6 +3044,8 @@ class %s(Interface): ...@@ -3043,6 +3044,8 @@ class %s(Interface):
self.tic() self.tic()
self.failIfModuleImportable('ITestPortalType') self.failIfModuleImportable('ITestPortalType')
self.assertFalse('ITestPortalType' in person_type.getInterfaceTypeList()) self.assertFalse('ITestPortalType' in person_type.getInterfaceTypeList())
self.failIfHasAttribute(erp5.accessor_holder.BaseAccessorHolder,
'providesITestPortalType')
component.validate() component.validate()
self.assertModuleImportable('ITestPortalType') self.assertModuleImportable('ITestPortalType')
...@@ -3053,6 +3056,11 @@ class %s(Interface): ...@@ -3053,6 +3056,11 @@ class %s(Interface):
person_type_class.loadClass() person_type_class.loadClass()
implemented_by_list = list(implementedBy(person_type_class)) implemented_by_list = list(implementedBy(person_type_class))
self.assertFalse(ITestPortalType in implemented_by_list) self.assertFalse(ITestPortalType in implemented_by_list)
self.assertHasAttribute(erp5.accessor_holder.BaseAccessorHolder,
'providesITestPortalType')
self.assertHasAttribute(person_type_class, 'providesITestPortalType')
new_person = self.portal.person_module.newContent(portal_type='Person')
self.assertFalse(new_person.providesITestPortalType())
person_original_interface_type_list = list(person_type.getTypeInterfaceList()) person_original_interface_type_list = list(person_type.getTypeInterfaceList())
try: try:
person_type.setTypeInterfaceList(person_original_interface_type_list + person_type.setTypeInterfaceList(person_original_interface_type_list +
...@@ -3063,10 +3071,12 @@ class %s(Interface): ...@@ -3063,10 +3071,12 @@ class %s(Interface):
person_type_class.loadClass() person_type_class.loadClass()
implemented_by_list = list(implementedBy(person_type_class)) implemented_by_list = list(implementedBy(person_type_class))
self.assertTrue(ITestPortalType in implemented_by_list) self.assertTrue(ITestPortalType in implemented_by_list)
self.assertTrue(new_person.providesITestPortalType())
finally: finally:
person_type.setTypeInterfaceList(person_original_interface_type_list) person_type.setTypeInterfaceList(person_original_interface_type_list)
self.commit() self.commit()
self.assertFalse(new_person.providesITestPortalType())
from Products.ERP5Type.Core.MixinComponent import MixinComponent from Products.ERP5Type.Core.MixinComponent import MixinComponent
class TestZodbMixinComponent(TestZodbInterfaceComponent): class TestZodbMixinComponent(TestZodbInterfaceComponent):
......
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