183 |
183 |
184 from rql import RQLHelper |
184 from rql import RQLHelper |
185 |
185 |
186 from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid, |
186 from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid, |
187 ObjectNotFound, NoSelectableObject, RegistryNotFound, |
187 ObjectNotFound, NoSelectableObject, RegistryNotFound, |
188 RegistryOutOfDate, CW_EVENT_MANAGER, onevent) |
188 CW_EVENT_MANAGER, onevent) |
189 from cubicweb.utils import dump_class |
189 from cubicweb.utils import dump_class |
190 from cubicweb.vregistry import VRegistry, Registry, class_regid |
190 from cubicweb.vregistry import VRegistry, Registry, class_regid |
191 from cubicweb.rtags import RTAGS |
191 from cubicweb.rtags import RTAGS |
192 |
192 |
193 def clear_rtag_objects(): |
193 def clear_rtag_objects(): |
458 def values(self): |
458 def values(self): |
459 return [value for key, value in self.items()] |
459 return [value for key, value in self.items()] |
460 def itervalues(self): |
460 def itervalues(self): |
461 return (value for key, value in self.items()) |
461 return (value for key, value in self.items()) |
462 |
462 |
463 def reset(self, path=None, force_reload=None): |
463 def reset(self): |
464 super(CubicWebVRegistry, self).reset(path, force_reload) |
464 super(CubicWebVRegistry, self).reset() |
465 self._needs_iface = {} |
465 self._needs_iface = {} |
466 # two special registries, propertydefs which care all the property |
466 # two special registries, propertydefs which care all the property |
467 # definitions, and propertyvals which contains values for those |
467 # definitions, and propertyvals which contains values for those |
468 # properties |
468 # properties |
469 if not self.initialized: |
469 if not self.initialized: |
470 self['propertydefs'] = {} |
470 self['propertydefs'] = {} |
471 self['propertyvalues'] = self.eprop_values = {} |
471 self['propertyvalues'] = self.eprop_values = {} |
472 for key, propdef in self.config.eproperty_definitions(): |
472 for key, propdef in self.config.eproperty_definitions(): |
473 self.register_property(key, **propdef) |
473 self.register_property(key, **propdef) |
474 if path is not None and force_reload: |
|
475 cleanup_sys_modules(path) |
|
476 cubes = self.config.cubes() |
|
477 # if the fs code use some cubes not yet registered into the instance |
|
478 # we should cleanup sys.modules for those as well to avoid potential |
|
479 # bad class reference pb after reloading |
|
480 cfg = self.config |
|
481 for cube in cfg.expand_cubes(cubes, with_recommends=True): |
|
482 if not cube in cubes: |
|
483 cpath = cfg.build_vregistry_cube_path([cfg.cube_dir(cube)]) |
|
484 cleanup_sys_modules(cpath) |
|
485 |
474 |
486 def set_schema(self, schema): |
475 def set_schema(self, schema): |
487 """set instance'schema and load application objects""" |
476 """set instance'schema and load application objects""" |
488 self._set_schema(schema) |
477 self._set_schema(schema) |
489 # now we can load application's web objects |
478 # now we can load application's web objects |
490 self._reload(self.config.vregistry_path(), force_reload=False) |
479 self.reload(self.config.vregistry_path()) |
491 # map lowered entity type names to their actual name |
480 # map lowered entity type names to their actual name |
492 self.case_insensitive_etypes = {} |
481 self.case_insensitive_etypes = {} |
493 for eschema in self.schema.entities(): |
482 for eschema in self.schema.entities(): |
494 etype = str(eschema) |
483 etype = str(eschema) |
495 self.case_insensitive_etypes[etype.lower()] = etype |
484 self.case_insensitive_etypes[etype.lower()] = etype |
496 clear_cache(eschema, 'ordered_relations') |
485 clear_cache(eschema, 'ordered_relations') |
497 clear_cache(eschema, 'meta_attributes') |
486 clear_cache(eschema, 'meta_attributes') |
498 |
487 |
499 def _reload(self, path, force_reload): |
488 def reload_if_needed(self): |
|
489 path = self.config.vregistry_path() |
|
490 if self.is_reload_needed(path): |
|
491 self.reload(path) |
|
492 |
|
493 def reload(self, path): |
|
494 """modification detected, reset and reload the vreg""" |
500 CW_EVENT_MANAGER.emit('before-registry-reload') |
495 CW_EVENT_MANAGER.emit('before-registry-reload') |
501 # modification detected, reset and reload |
496 cleanup_sys_modules(path) |
502 self.reset(path, force_reload) |
497 cubes = self.config.cubes() |
503 super(CubicWebVRegistry, self).register_objects( |
498 # if the fs code use some cubes not yet registered into the instance we |
504 path, force_reload, self.config.extrapath) |
499 # should cleanup sys.modules for those as well to avoid potential bad |
|
500 # class reference pb after reloading |
|
501 cfg = self.config |
|
502 for cube in cfg.expand_cubes(cubes, with_recommends=True): |
|
503 if not cube in cubes: |
|
504 cpath = cfg.build_vregistry_cube_path([cfg.cube_dir(cube)]) |
|
505 cleanup_sys_modules(cpath) |
|
506 self.reset() |
|
507 self.register_objects(path, True) |
505 CW_EVENT_MANAGER.emit('after-registry-reload') |
508 CW_EVENT_MANAGER.emit('after-registry-reload') |
506 |
509 |
507 def _set_schema(self, schema): |
510 def _set_schema(self, schema): |
508 """set instance'schema""" |
511 """set instance'schema""" |
509 self.schema = schema |
512 self.schema = schema |
544 # XXX bw compat |
547 # XXX bw compat |
545 ifaces = use_interfaces(obj) |
548 ifaces = use_interfaces(obj) |
546 if ifaces: |
549 if ifaces: |
547 self._needs_iface[obj] = ifaces |
550 self._needs_iface[obj] = ifaces |
548 |
551 |
549 def register_objects(self, path, force_reload=None): |
552 def register_objects(self, path, force_reload=False): |
550 """overriden to remove objects requiring a missing interface""" |
553 """overriden to remove objects requiring a missing interface""" |
551 if force_reload is None: |
554 super(CubicWebVRegistry, self).register_objects( |
552 force_reload = self.config.debugmode |
555 path, force_reload, self.config.extrapath) |
553 try: |
|
554 super(CubicWebVRegistry, self).register_objects( |
|
555 path, force_reload, self.config.extrapath) |
|
556 except RegistryOutOfDate: |
|
557 self._reload(path, force_reload) |
|
558 |
556 |
559 def initialization_completed(self): |
557 def initialization_completed(self): |
560 """cw specific code once vreg initialization is completed: |
558 """cw specific code once vreg initialization is completed: |
561 |
559 |
562 * remove objects requiring a missing interface, unless |
560 * remove objects requiring a missing interface, unless |