209 from rql import RQLHelper |
209 from rql import RQLHelper |
210 from yams.constraints import BASE_CONVERTERS |
210 from yams.constraints import BASE_CONVERTERS |
211 |
211 |
212 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, |
213 onevent, Binary, UnknownProperty, UnknownEid) |
213 onevent, Binary, UnknownProperty, UnknownEid) |
214 from cubicweb.predicates import (implements, appobject_selectable, |
214 from cubicweb.predicates import appobject_selectable, _reset_is_instance_cache |
215 _reset_is_instance_cache) |
|
216 |
215 |
217 |
216 |
218 @onevent('before-registry-reload') |
217 @onevent('before-registry-reload') |
219 def cleanup_uicfg_compat(): |
218 def cleanup_uicfg_compat(): |
220 """ backward compat: those modules are now refering to app objects in |
219 """ backward compat: those modules are now refering to app objects in |
227 del sys.modules['cubicweb.web'].uicfg |
226 del sys.modules['cubicweb.web'].uicfg |
228 if getattr(sys.modules['cubicweb.web'], 'uihelper', None): |
227 if getattr(sys.modules['cubicweb.web'], 'uihelper', None): |
229 del sys.modules['cubicweb.web'].uihelper |
228 del sys.modules['cubicweb.web'].uihelper |
230 sys.modules.pop('cubicweb.web.uicfg', None) |
229 sys.modules.pop('cubicweb.web.uicfg', None) |
231 sys.modules.pop('cubicweb.web.uihelper', None) |
230 sys.modules.pop('cubicweb.web.uihelper', None) |
232 |
|
233 def use_interfaces(obj): |
|
234 """return interfaces required by the given object by searching for |
|
235 `implements` predicate |
|
236 """ |
|
237 impl = obj.__select__.search_selector(implements) |
|
238 if impl: |
|
239 return sorted(impl.expected_ifaces) |
|
240 return () |
|
241 |
231 |
242 def require_appobject(obj): |
232 def require_appobject(obj): |
243 """return appobjects required by the given object by searching for |
233 """return appobjects required by the given object by searching for |
244 `appobject_selectable` predicate |
234 `appobject_selectable` predicate |
245 """ |
235 """ |
566 return (value for key, value in self.items()) |
556 return (value for key, value in self.items()) |
567 |
557 |
568 def reset(self): |
558 def reset(self): |
569 CW_EVENT_MANAGER.emit('before-registry-reset', self) |
559 CW_EVENT_MANAGER.emit('before-registry-reset', self) |
570 super(CWRegistryStore, self).reset() |
560 super(CWRegistryStore, self).reset() |
571 self._needs_iface = {} |
|
572 self._needs_appobject = {} |
561 self._needs_appobject = {} |
573 # two special registries, propertydefs which care all the property |
562 # two special registries, propertydefs which care all the property |
574 # definitions, and propertyvals which contains values for those |
563 # definitions, and propertyvals which contains values for those |
575 # properties |
564 # properties |
576 if not self.initialized: |
565 if not self.initialized: |
639 for registry, regcontent in self.items(): |
628 for registry, regcontent in self.items(): |
640 for objects in regcontent.itervalues(): |
629 for objects in regcontent.itervalues(): |
641 for obj in objects: |
630 for obj in objects: |
642 obj.schema = schema |
631 obj.schema = schema |
643 |
632 |
644 @deprecated('[3.9] use .register instead') |
|
645 def register_if_interface_found(self, obj, ifaces, **kwargs): |
|
646 """register `obj` but remove it if no entity class implements one of |
|
647 the given `ifaces` interfaces at the end of the registration process. |
|
648 |
|
649 Extra keyword arguments are given to the |
|
650 :meth:`~cubicweb.cwvreg.CWRegistryStore.register` function. |
|
651 """ |
|
652 self.register(obj, **kwargs) |
|
653 if not isinstance(ifaces, (tuple, list)): |
|
654 self._needs_iface[obj] = (ifaces,) |
|
655 else: |
|
656 self._needs_iface[obj] = ifaces |
|
657 |
|
658 def register(self, obj, *args, **kwargs): |
633 def register(self, obj, *args, **kwargs): |
659 """register `obj` application object into `registryname` or |
634 """register `obj` application object into `registryname` or |
660 `obj.__registry__` if not specified, with identifier `oid` or |
635 `obj.__registry__` if not specified, with identifier `oid` or |
661 `obj.__regid__` if not specified. |
636 `obj.__regid__` if not specified. |
662 |
637 |
663 If `clear` is true, all objects with the same identifier will be |
638 If `clear` is true, all objects with the same identifier will be |
664 previously unregistered. |
639 previously unregistered. |
665 """ |
640 """ |
666 obj = related_appobject(obj) |
641 obj = related_appobject(obj) |
667 super(CWRegistryStore, self).register(obj, *args, **kwargs) |
642 super(CWRegistryStore, self).register(obj, *args, **kwargs) |
668 # XXX bw compat |
|
669 ifaces = use_interfaces(obj) |
|
670 if ifaces: |
|
671 if not obj.__name__.endswith('Adapter') and \ |
|
672 any(iface for iface in ifaces if not isinstance(iface, basestring)): |
|
673 warn('[3.9] %s: interfaces in implements selector are ' |
|
674 'deprecated in favor of adapters / adaptable ' |
|
675 'selector' % obj.__name__, DeprecationWarning) |
|
676 self._needs_iface[obj] = ifaces |
|
677 depends_on = require_appobject(obj) |
643 depends_on = require_appobject(obj) |
678 if depends_on is not None: |
644 if depends_on is not None: |
679 self._needs_appobject[obj] = depends_on |
645 self._needs_appobject[obj] = depends_on |
680 |
646 |
681 def register_objects(self, path): |
647 def register_objects(self, path): |
692 * init rtags |
658 * init rtags |
693 """ |
659 """ |
694 # we may want to keep interface dependent objects (e.g.for i18n |
660 # we may want to keep interface dependent objects (e.g.for i18n |
695 # catalog generation) |
661 # catalog generation) |
696 if self.config.cleanup_interface_sobjects: |
662 if self.config.cleanup_interface_sobjects: |
697 # XXX deprecated with cw 3.9: remove appobjects that don't support |
663 # remove appobjects which depend on other, unexistant appobjects |
698 # any available interface |
|
699 implemented_interfaces = set() |
|
700 if 'Any' in self.get('etypes', ()): |
|
701 for etype in self.schema.entities(): |
|
702 if etype.final: |
|
703 continue |
|
704 cls = self['etypes'].etype_class(etype) |
|
705 if cls.__implements__: |
|
706 warn('[3.9] %s: using __implements__/interfaces are ' |
|
707 'deprecated in favor of adapters' % cls.__name__, |
|
708 DeprecationWarning) |
|
709 for iface in cls.__implements__: |
|
710 implemented_interfaces.update(iface.__mro__) |
|
711 implemented_interfaces.update(cls.__mro__) |
|
712 for obj, ifaces in self._needs_iface.items(): |
|
713 ifaces = frozenset(isinstance(iface, basestring) |
|
714 and iface in self.schema |
|
715 and self['etypes'].etype_class(iface) |
|
716 or iface |
|
717 for iface in ifaces) |
|
718 if not ('Any' in ifaces or ifaces & implemented_interfaces): |
|
719 reg = self[obj_registries(obj)[0]] |
|
720 self.debug('unregister %s (no implemented ' |
|
721 'interface among %s)', reg.objid(obj), ifaces) |
|
722 self.unregister(obj) |
|
723 # since 3.9: remove appobjects which depending on other, unexistant |
|
724 # appobjects |
|
725 for obj, (regname, regids) in self._needs_appobject.items(): |
664 for obj, (regname, regids) in self._needs_appobject.items(): |
726 try: |
665 try: |
727 registry = self[regname] |
666 registry = self[regname] |
728 except RegistryNotFound: |
667 except RegistryNotFound: |
729 self.debug('unregister %s (no registry %s)', obj, regname) |
668 self.debug('unregister %s (no registry %s)', obj, regname) |