cwvreg.py
changeset 8666 1dd655788ece
parent 8663 4e2dc5e61599
child 8695 358d8bed9626
equal deleted inserted replaced
8665:e65af61bde7d 8666:1dd655788ece
   195 
   195 
   196 import sys
   196 import sys
   197 from os.path import join, dirname, realpath
   197 from os.path import join, dirname, realpath
   198 from warnings import warn
   198 from warnings import warn
   199 from datetime import datetime, date, time, timedelta
   199 from datetime import datetime, date, time, timedelta
       
   200 from functools import partial
   200 
   201 
   201 from logilab.common.decorators import cached, clear_cache
   202 from logilab.common.decorators import cached, clear_cache
   202 from logilab.common.deprecation import deprecated, class_deprecated
   203 from logilab.common.deprecation import deprecated, class_deprecated
   203 from logilab.common.modutils import cleanup_sys_modules
   204 from logilab.common.modutils import cleanup_sys_modules
   204 from logilab.common.registry import (
   205 from logilab.common.registry import (
   205     RegistryStore, Registry, classid,
   206     RegistryStore, Registry, obj_registries,
   206     ObjectNotFound, NoSelectableObject, RegistryNotFound)
   207     ObjectNotFound, NoSelectableObject, RegistryNotFound)
   207 
   208 
   208 from rql import RQLHelper
   209 from rql import RQLHelper
   209 from yams.constraints import BASE_CONVERTERS
   210 from yams.constraints import BASE_CONVERTERS
   210 
   211 
   211 from cubicweb import (CW_SOFTWARE_ROOT, ETYPE_NAME_MAP, CW_EVENT_MANAGER,
   212 from cubicweb import (CW_SOFTWARE_ROOT, ETYPE_NAME_MAP, CW_EVENT_MANAGER,
   212                       Binary, UnknownProperty, UnknownEid)
   213                       Binary, UnknownProperty, UnknownEid)
   213 from cubicweb.rtags import RTAGS
       
   214 from cubicweb.predicates import (implements, appobject_selectable,
   214 from cubicweb.predicates import (implements, appobject_selectable,
   215                                  _reset_is_instance_cache)
   215                                  _reset_is_instance_cache)
   216 
   216 
   217 def clear_rtag_objects():
   217 # backward compat: those modules are now refering to app objects in
   218     for rtag in RTAGS:
   218 # cw.web.views.uicfg and import * from backward compat. On registry reload, we
   219         rtag.clear()
   219 # should pop those modules from the cache so references are properly updated on
       
   220 # subsequent reload
       
   221 CW_EVENT_MANAGER.bind('before-registry-reload', partial(sys.modules.pop, 'cubicweb.web.uicfg', None))
       
   222 CW_EVENT_MANAGER.bind('before-registry-reload', partial(sys.modules.pop, 'cubicweb.web.uihelper', None))
   220 
   223 
   221 def use_interfaces(obj):
   224 def use_interfaces(obj):
   222     """return interfaces required by the given object by searching for
   225     """return interfaces required by the given object by searching for
   223     `implements` predicate
   226     `implements` predicate
   224     """
   227     """
   259 def related_appobject(obj, appobjectattr='__appobject__'):
   262 def related_appobject(obj, appobjectattr='__appobject__'):
   260     """ adapts any object to a potential appobject bound to it
   263     """ adapts any object to a potential appobject bound to it
   261     through the __appobject__ attribute
   264     through the __appobject__ attribute
   262     """
   265     """
   263     return getattr(obj, appobjectattr, obj)
   266     return getattr(obj, appobjectattr, obj)
       
   267 
       
   268 
       
   269 class InstancesRegistry(CWRegistry):
       
   270 
       
   271     def selected(self, winner, args, kwargs):
       
   272         """overriden to avoid the default 'instanciation' behaviour, ie
       
   273         winner(*args, **kwargs)
       
   274         """
       
   275         return winner
   264 
   276 
   265 
   277 
   266 class ETypeRegistry(CWRegistry):
   278 class ETypeRegistry(CWRegistry):
   267 
   279 
   268     def clear_caches(self):
   280     def clear_caches(self):
   495     REGISTRY_FACTORY = {None: CWRegistry,
   507     REGISTRY_FACTORY = {None: CWRegistry,
   496                         'etypes': ETypeRegistry,
   508                         'etypes': ETypeRegistry,
   497                         'views': ViewsRegistry,
   509                         'views': ViewsRegistry,
   498                         'actions': ActionsRegistry,
   510                         'actions': ActionsRegistry,
   499                         'ctxcomponents': CtxComponentsRegistry,
   511                         'ctxcomponents': CtxComponentsRegistry,
       
   512                         'uicfg': InstancesRegistry,
   500                         }
   513                         }
   501 
   514 
   502     def __init__(self, config, initlog=True):
   515     def __init__(self, config, initlog=True):
   503         if initlog:
   516         if initlog:
   504             # first init log service
   517             # first init log service
   515                 sys.path.remove(webdir)
   528                 sys.path.remove(webdir)
   516         if CW_SOFTWARE_ROOT in sys.path:
   529         if CW_SOFTWARE_ROOT in sys.path:
   517             sys.path.remove(CW_SOFTWARE_ROOT)
   530             sys.path.remove(CW_SOFTWARE_ROOT)
   518         self.schema = None
   531         self.schema = None
   519         self.initialized = False
   532         self.initialized = False
   520         # XXX give force_reload (or refactor [re]loading...)
       
   521         if self.config.mode != 'test':
       
   522             # don't clear rtags during test, this may cause breakage with
       
   523             # manually imported appobject modules
       
   524             CW_EVENT_MANAGER.bind('before-registry-reload', clear_rtag_objects)
       
   525         self['boxes'] = BwCompatCWRegistry(self, 'boxes', 'ctxcomponents')
   533         self['boxes'] = BwCompatCWRegistry(self, 'boxes', 'ctxcomponents')
   526         self['contentnavigation'] = BwCompatCWRegistry(self, 'contentnavigation', 'ctxcomponents')
   534         self['contentnavigation'] = BwCompatCWRegistry(self, 'contentnavigation', 'ctxcomponents')
   527 
   535 
   528     def setdefault(self, regid):
   536     def setdefault(self, regid):
   529         try:
   537         try:
   693                                    and iface in self.schema
   701                                    and iface in self.schema
   694                                    and self['etypes'].etype_class(iface)
   702                                    and self['etypes'].etype_class(iface)
   695                                    or iface
   703                                    or iface
   696                                    for iface in ifaces)
   704                                    for iface in ifaces)
   697                 if not ('Any' in ifaces or ifaces & implemented_interfaces):
   705                 if not ('Any' in ifaces or ifaces & implemented_interfaces):
       
   706                     reg = self[obj_registries(obj)[0]]
   698                     self.debug('unregister %s (no implemented '
   707                     self.debug('unregister %s (no implemented '
   699                                'interface among %s)', classid(obj), ifaces)
   708                                'interface among %s)', reg.objid(obj), ifaces)
   700                     self.unregister(obj)
   709                     self.unregister(obj)
   701             # since 3.9: remove appobjects which depending on other, unexistant
   710             # since 3.9: remove appobjects which depending on other, unexistant
   702             # appobjects
   711             # appobjects
   703             for obj, (regname, regids) in self._needs_appobject.items():
   712             for obj, (regname, regids) in self._needs_appobject.items():
   704                 try:
   713                 try:
   705                     registry = self[regname]
   714                     registry = self[regname]
   706                 except RegistryNotFound:
   715                 except RegistryNotFound:
   707                     self.debug('unregister %s (no registry %s)', classid(obj),
   716                     self.debug('unregister %s (no registry %s)', obj, regname)
   708                                regname)
       
   709                     self.unregister(obj)
   717                     self.unregister(obj)
   710                     continue
   718                     continue
   711                 for regid in regids:
   719                 for regid in regids:
   712                     if registry.get(regid):
   720                     if registry.get(regid):
   713                         break
   721                         break
   714                 else:
   722                 else:
   715                     self.debug('unregister %s (no %s object in registry %s)',
   723                     self.debug('unregister %s (no %s object in registry %s)',
   716                                classid(obj), ' or '.join(regids), regname)
   724                                registry.objid(obj), ' or '.join(regids), regname)
   717                     self.unregister(obj)
   725                     self.unregister(obj)
   718         super(CWRegistryStore, self).initialization_completed()
   726         super(CWRegistryStore, self).initialization_completed()
   719         for rtag in RTAGS:
   727         if 'uicfg' in self: # 'uicfg' is not loaded in a pure repository mode
   720             # don't check rtags if we don't want to cleanup_interface_sobjects
   728             for rtags in self['uicfg'].values():
   721             rtag.init(self.schema, check=self.config.cleanup_interface_sobjects)
   729                 for rtag in rtags:
       
   730                     # don't check rtags if we don't want to cleanup_interface_sobjects
       
   731                     rtag.init(self.schema, check=self.config.cleanup_interface_sobjects)
   722 
   732 
   723     # rql parsing utilities ####################################################
   733     # rql parsing utilities ####################################################
   724 
   734 
   725     @property
   735     @property
   726     @cached
   736     @cached