server/sources/__init__.py
changeset 6945 28bf94d062a9
parent 6944 0cf10429ad39
child 6957 ffda12be2e9f
--- a/server/sources/__init__.py	Mon Feb 07 18:19:36 2011 +0100
+++ b/server/sources/__init__.py	Mon Feb 07 18:19:39 2011 +0100
@@ -24,7 +24,11 @@
 from datetime import datetime, timedelta
 from logging import getLogger
 
-from cubicweb import set_log_methods, server
+from logilab.common import configuration
+
+from yams.schema import role_name
+
+from cubicweb import ValidationError, set_log_methods, server
 from cubicweb.schema import VIRTUAL_RTYPES
 from cubicweb.server.sqlutils import SQL_PREFIX
 from cubicweb.server.ssplanner import EditedEntity
@@ -103,15 +107,19 @@
     # force deactivation (configuration error for instance)
     disabled = False
 
-    def __init__(self, repo, source_config, *args, **kwargs):
+    # source configuration options
+    options = ()
+
+    def __init__(self, repo, source_config, eid=None):
         self.repo = repo
-        self.uri = source_config['uri']
-        set_log_methods(self, getLogger('cubicweb.sources.'+self.uri))
         self.set_schema(repo.schema)
         self.support_relations['identity'] = False
-        self.eid = None
+        self.eid = eid
         self.public_config = source_config.copy()
         self.remove_sensitive_information(self.public_config)
+        self.uri = source_config.pop('uri')
+        set_log_methods(self, getLogger('cubicweb.sources.'+self.uri))
+        source_config.pop('type')
 
     def __repr__(self):
         return '<%s source %s @%#x>' % (self.uri, self.eid, id(self))
@@ -136,6 +144,56 @@
         """method called to restore a backup of source's data"""
         pass
 
+    @classmethod
+    def check_conf_dict(cls, eid, confdict, _=unicode, fail_if_unknown=True):
+        """check configuration of source entity. Return config dict properly
+        typed with defaults set.
+        """
+        processed = {}
+        for optname, optdict in cls.options:
+            value = confdict.pop(optname, optdict.get('default'))
+            if value is configuration.REQUIRED:
+                if not fail_if_unknown:
+                    continue
+                msg = _('specifying %s is mandatory' % optname)
+                raise ValidationError(eid, {role_name('config', 'subject'): msg})
+            elif value is not None:
+                # type check
+                try:
+                    value = configuration.convert(value, optdict, optname)
+                except Exception, ex:
+                    msg = unicode(ex) # XXX internationalization
+                    raise ValidationError(eid, {role_name('config', 'subject'): msg})
+            processed[optname] = value
+        # cw < 3.10 bw compat
+        try:
+            processed['adapter'] = confdict['adapter']
+        except:
+            pass
+        # check for unknown options
+        if confdict and not confdict.keys() == ['adapter']:
+            if fail_if_unknown:
+                msg = _('unknown options %s') % ', '.join(confdict)
+                raise ValidationError(eid, {role_name('config', 'subject'): msg})
+            else:
+                logger = getLogger('cubicweb.sources')
+                logger.warning('unknown options %s', ', '.join(confdict))
+                # add options to processed, they may be necessary during migration
+                processed.update(confdict)
+        return processed
+
+    @classmethod
+    def check_config(cls, source_entity):
+        """check configuration of source entity"""
+        return cls.check_conf_dict(source_entity.eid, source_entity.host_config,
+                                    _=source_entity._cw._)
+
+    def update_config(self, source_entity, typedconfig):
+        """update configuration from source entity. `typedconfig` is config
+        properly typed with defaults set
+        """
+        pass
+
     # source initialization / finalization #####################################
 
     def set_schema(self, schema):
@@ -503,8 +561,8 @@
     except KeyError:
         raise RuntimeError('Unknown source type %r' % source_type)
 
-def get_source(type, source_config, repo):
-    """return a source adapter according to the adapter field in the
-    source's configuration
+def get_source(type, source_config, repo, eid):
+    """return a source adapter according to the adapter field in the source's
+    configuration
     """
-    return source_adapter(type)(repo, source_config)
+    return source_adapter(type)(repo, source_config, eid)