common/registerers.py
changeset 1808 aa09e20dd8c0
parent 1693 49075f57cf2c
parent 1807 6d541c610165
child 1810 e95e876be17c
--- a/common/registerers.py	Tue May 05 17:18:49 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-"""This file contains some basic registerers required by application objects
-registry to handle registration at startup time.
-
-A registerer is responsible to tell if an object should be registered according
-to the application's schema or to already registered object
-
-:organization: Logilab
-:copyright: 2006-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-"""
-__docformat__ = "restructuredtext en"
-
-from cubicweb.vregistry import registerer
-
-
-def _accepts_interfaces(obj):
-    return sorted(getattr(obj, 'accepts_interfaces', ()))
-
-
-class yes_registerer(registerer):
-    """register without any other action"""
-    def do_it_yourself(self, registered):
-        return self.vobject
-
-class priority_registerer(registerer):
-    """systematically kick previous registered class and register the
-    wrapped class (based on the fact that directory containing vobjects
-    are loaded from the most generic to the most specific).
-
-    This is usually for templates or startup views where we want to
-    keep only the latest in the load path
-    """
-    def do_it_yourself(self, registered):
-        if registered:
-            if len(registered) > 1:
-                self.warning('priority_registerer found more than one registered objects '
-                             '(registerer monkey patch ?)')
-            for regobj in registered[:]:
-                self.kick(registered, regobj)
-        return self.vobject
-    
-    def remove_equivalents(self, registered):
-        for _obj in registered[:]:
-            if self.equivalent(_obj):
-                self.kick(registered, _obj)
-                break
-            
-    def remove_all_equivalents(self, registered):
-        for _obj in registered[:]:
-            if _obj is self.vobject:
-                continue
-            if self.equivalent(_obj):
-                self.kick(registered, _obj)
-
-    def equivalent(self, other):
-        raise NotImplementedError(self, self.vobject)
-
-
-class kick_registerer(registerer):
-    """systematically kick previous registered class and don't register the
-    wrapped class. This is temporarily used to discard library object registrable
-    but that we don't want to use
-    """
-    def do_it_yourself(self, registered):
-        if registered:
-            self.kick(registered, registered[-1])
-        return 
-    
-
-class accepts_registerer(priority_registerer):
-    """register according to the .accepts attribute of the wrapped
-    class, which should be a tuple refering some entity's types
-
-    * if no type is defined the application'schema, skip the wrapped
-      class
-    * if the class defines a requires attribute, each entity type defined
-      in the requires list must be in the schema
-    * if an object previously registered has equivalent .accepts
-      attribute, kick it out
-    * register
-    """
-    def do_it_yourself(self, registered):
-        # if object is accepting interface, we have register it now and
-        # remove it latter if no object is implementing accepted interfaces
-        if _accepts_interfaces(self.vobject):
-            return self.vobject
-        if not 'Any' in self.vobject.accepts:
-            for ertype in self.vobject.accepts:
-                if ertype in self.schema:
-                    break
-            else:
-                self.skip()
-                return None
-        for required in getattr(self.vobject, 'requires', ()):
-            if required not in self.schema:
-                self.skip()
-                return
-        self.remove_equivalents(registered)
-        return self.vobject
-    
-    def equivalent(self, other):
-        if _accepts_interfaces(self.vobject) != _accepts_interfaces(other):
-            return False
-        if getattr(self.vobject, 'require_groups', ()) != getattr(other, 'require_groups', ()):
-            return False
-        try:
-            newaccepts = list(other.accepts)
-            for etype in self.vobject.accepts:
-                try:
-                    newaccepts.remove(etype)
-                except ValueError:
-                    continue
-            if newaccepts:
-                other.accepts = tuple(newaccepts)
-                return False
-            return True
-        except AttributeError:
-            return False
-
-
-class id_registerer(priority_registerer):
-    """register according to the "id" attribute of the wrapped class,
-    refering to an entity type.
-    
-    * if the type is not Any and is not defined the application'schema,
-      skip the wrapped class
-    * if an object previously registered has the same .id attribute,
-      kick it out
-    * register
-    """
-    def do_it_yourself(self, registered):
-        etype = self.vobject.id
-        if etype != 'Any' and not self.schema.has_entity(etype):
-            self.skip()
-            return
-        self.remove_equivalents(registered)
-        return self.vobject
-    
-    def equivalent(self, other):
-        return other.id == self.vobject.id
-
-
-class etype_rtype_registerer(registerer):
-    """registerer handling optional .etype and .rtype attributes.:
-    
-    * if .etype is set and is not an entity type defined in the
-      application schema, skip the wrapped class
-    * if .rtype or .relname is set and is not a relation type defined in
-      the application schema, skip the wrapped class
-    * register
-    """
-    def do_it_yourself(self, registered):
-        cls = self.vobject
-        if hasattr(cls, 'etype'):
-            if not self.schema.has_entity(cls.etype):
-                return
-        rtype = getattr(cls, 'rtype', None)
-        if rtype and not self.schema.has_relation(rtype):
-            return
-        return cls
-
-class etype_rtype_priority_registerer(etype_rtype_registerer):
-    """add priority behaviour to the etype_rtype_registerer
-    """
-    def do_it_yourself(self, registered):
-        cls = super(etype_rtype_priority_registerer, self).do_it_yourself(registered)
-        if cls:
-            registerer = priority_registerer(self.registry, cls)
-            cls = registerer.do_it_yourself(registered)
-        return cls
-
-class action_registerer(etype_rtype_registerer):
-    """'all in one' actions registerer, handling optional .accepts,
-    .etype and .rtype attributes:
-    
-    * if .etype is set and is not an entity type defined in the
-      application schema, skip the wrapped class
-    * if .rtype or .relname is set and is not a relation type defined in
-      the application schema, skip the wrapped class
-    * if .accepts is set, delegate to the accepts_registerer
-    * register
-    """
-    def do_it_yourself(self, registered):
-        cls = super(action_registerer, self).do_it_yourself(registered)
-        if hasattr(cls, 'accepts'):
-            registerer = accepts_registerer(self.registry, cls)
-            cls = registerer.do_it_yourself(registered)
-        return cls
-
-
-class extresources_registerer(priority_registerer):
-    """'registerer according to a .need_resources attributes which
-    should list necessary resource identifiers for the wrapped object.
-    If one of its resources is missing, don't register
-    """
-    def do_it_yourself(self, registered):
-        if not hasattr(self.config, 'has_resource'):
-            return
-        for resourceid in self.vobject.need_resources:
-            if not self.config.has_resource(resourceid):
-                return
-        return super(extresources_registerer, self).do_it_yourself(registered)
-    
-
-__all__ = [cls.__name__ for cls in globals().values()
-           if isinstance(cls, type) and issubclass(cls, registerer)
-           and not cls is registerer]