Adapt libedata-book to the new ESource API.
authorMatthew Barnes <mbarnes@redhat.com>
Fri, 12 Nov 2010 21:48:26 +0000 (16:48 -0500)
committerMatthew Barnes <mbarnes@redhat.com>
Sun, 3 Jun 2012 23:51:08 +0000 (19:51 -0400)
addressbook/libedata-book/e-book-backend-factory.c
addressbook/libedata-book/e-book-backend-sync.c
addressbook/libedata-book/e-book-backend-sync.h
addressbook/libedata-book/e-book-backend.c
addressbook/libedata-book/e-book-backend.h
addressbook/libedata-book/e-data-book-factory.c
addressbook/libedata-book/e-data-book-factory.h
addressbook/libedata-book/e-data-book.c
addressbook/libedata-book/e-data-book.h
addressbook/libedata-book/e-data-book.xml
docs/reference/addressbook/libedata-book/libedata-book-sections.txt

index 155e9cf..e63c173 100644 (file)
@@ -18,6 +18,16 @@ G_DEFINE_ABSTRACT_TYPE (
        e_book_backend_factory,
        E_TYPE_BACKEND_FACTORY)
 
+static EDataBookFactory *
+book_backend_factory_get_data_factory (EBackendFactory *factory)
+{
+       EExtensible *extensible;
+
+       extensible = e_extension_get_extensible (E_EXTENSION (factory));
+
+       return E_DATA_BOOK_FACTORY (extensible);
+}
+
 static const gchar *
 book_backend_factory_get_hash_key (EBackendFactory *factory)
 {
@@ -38,12 +48,20 @@ book_backend_factory_new_backend (EBackendFactory *factory,
                                   ESource *source)
 {
        EBookBackendFactoryClass *class;
+       EDataBookFactory *data_factory;
+       ESourceRegistry *registry;
 
        class = E_BOOK_BACKEND_FACTORY_GET_CLASS (factory);
        g_return_val_if_fail (g_type_is_a (
                class->backend_type, E_TYPE_BOOK_BACKEND), NULL);
 
-       return g_object_new (class->backend_type, "source", source, NULL);
+       data_factory = book_backend_factory_get_data_factory (factory);
+       registry = e_data_book_factory_get_registry (data_factory);
+
+       return g_object_new (
+               class->backend_type,
+               "registry", registry,
+               "source", source, NULL);
 }
 
 static void
index e18c3aa..53d1538 100644 (file)
@@ -384,28 +384,6 @@ e_book_backend_sync_get_contact_list_uids (EBookBackendSync *backend,
        }
 }
 
-/**
- * e_book_backend_sync_authenticate_user:
- * @backend: an #EBookBackendSync
- * @cancellable: a #GCancellable for the operation
- * @credentials: an #ECredentials to authenticate with
- * @error: #GError to set, when something fails
- *
- * Authenticates @backend with given @credentials.
- **/
-void
-e_book_backend_sync_authenticate_user (EBookBackendSync *backend,
-                                       GCancellable *cancellable,
-                                       ECredentials *credentials,
-                                       GError **error)
-{
-       e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
-       e_return_data_book_error_if_fail (credentials, E_DATA_BOOK_STATUS_INVALID_ARG);
-       e_return_data_book_error_if_fail (E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync, E_DATA_BOOK_STATUS_NOT_SUPPORTED);
-
-       (* E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync) (backend, cancellable, credentials, error);
-}
-
 static void
 book_backend_open (EBookBackend *backend,
                    EDataBook *book,
@@ -587,18 +565,6 @@ book_backend_get_contact_list_uids (EBookBackend *backend,
        g_slist_free (uids);
 }
 
-static void
-book_backend_authenticate_user (EBookBackend *backend,
-                                GCancellable *cancellable,
-                                ECredentials *credentials)
-{
-       GError *error = NULL;
-
-       e_book_backend_sync_authenticate_user (E_BOOK_BACKEND_SYNC (backend), cancellable, credentials, &error);
-
-       e_book_backend_notify_opened (backend, error);
-}
-
 static gboolean
 book_backend_sync_get_backend_property (EBookBackendSync *backend,
                                         EDataBook *book,
@@ -634,7 +600,6 @@ e_book_backend_sync_class_init (EBookBackendSyncClass *class)
        EBookBackendClass *backend_class = E_BOOK_BACKEND_CLASS (class);
 
        backend_class->open                     = book_backend_open;
-       backend_class->authenticate_user        = book_backend_authenticate_user;
        backend_class->remove                   = book_backend_remove;
        backend_class->refresh                  = book_backend_refresh;
        backend_class->get_backend_property     = book_backend_get_backend_property;
index de27624..770e5d8 100644 (file)
@@ -39,8 +39,6 @@ struct _EBookBackendSyncClass {
        void (*get_contact_sync)                (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *id, gchar **vcard, GError **error);
        void (*get_contact_list_sync)           (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts, GError **error);
        void (*get_contact_list_uids_sync)      (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts_uids, GError **error);
-
-       void (*authenticate_user_sync)          (EBookBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
 };
 
 GType          e_book_backend_sync_get_type            (void);
@@ -59,8 +57,6 @@ void          e_book_backend_sync_get_contact         (EBookBackendSync *backend, EDataBook *bo
 void           e_book_backend_sync_get_contact_list    (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts, GError **error);
 void           e_book_backend_sync_get_contact_list_uids (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts_uids, GError **error);
 
-void           e_book_backend_sync_authenticate_user   (EBookBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
-
 G_END_DECLS
 
 #endif /* __E_BOOK_BACKEND_SYNC_H__ */
index a4d974e..0b751e2 100644 (file)
@@ -24,6 +24,8 @@
        ((obj), E_TYPE_BOOK_BACKEND, EBookBackendPrivate))
 
 struct _EBookBackendPrivate {
+       ESourceRegistry *registry;
+
        GMutex *clients_mutex;
        GSList *clients;
 
@@ -38,7 +40,8 @@ struct _EBookBackendPrivate {
 /* Property IDs */
 enum {
        PROP_0,
-       PROP_CACHE_DIR
+       PROP_CACHE_DIR,
+       PROP_REGISTRY
 };
 
 G_DEFINE_TYPE (EBookBackend, e_book_backend, E_TYPE_BACKEND)
@@ -48,21 +51,19 @@ book_backend_set_default_cache_dir (EBookBackend *backend)
 {
        ESource *source;
        const gchar *user_cache_dir;
-       gchar *mangled_uri;
+       const gchar *uid;
        gchar *filename;
 
        user_cache_dir = e_get_user_cache_dir ();
        source = e_backend_get_source (E_BACKEND (backend));
 
-       /* Mangle the URI to not contain invalid characters. */
-       mangled_uri = g_strdelimit (e_source_get_uri (source), ":/", '_');
+       uid = e_source_get_uid (source);
+       g_return_if_fail (uid != NULL);
 
        filename = g_build_filename (
-               user_cache_dir, "addressbook", mangled_uri, NULL);
+               user_cache_dir, "addressbook", uid, NULL);
        e_book_backend_set_cache_dir (backend, filename);
        g_free (filename);
-
-       g_free (mangled_uri);
 }
 
 static void
@@ -109,6 +110,16 @@ book_backend_set_backend_property (EBookBackend *backend,
 }
 
 static void
+book_backend_set_registry (EBookBackend *backend,
+                           ESourceRegistry *registry)
+{
+       g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+       g_return_if_fail (backend->priv->registry == NULL);
+
+       backend->priv->registry = g_object_ref (registry);
+}
+
+static void
 book_backend_set_property (GObject *object,
                            guint property_id,
                            const GValue *value,
@@ -120,6 +131,12 @@ book_backend_set_property (GObject *object,
                                E_BOOK_BACKEND (object),
                                g_value_get_string (value));
                        return;
+
+               case PROP_REGISTRY:
+                       book_backend_set_registry (
+                               E_BOOK_BACKEND (object),
+                               g_value_get_object (value));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -137,6 +154,12 @@ book_backend_get_property (GObject *object,
                                value, e_book_backend_get_cache_dir (
                                E_BOOK_BACKEND (object)));
                        return;
+
+               case PROP_REGISTRY:
+                       g_value_set_object (
+                               value, e_book_backend_get_registry (
+                               E_BOOK_BACKEND (object)));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -149,6 +172,11 @@ book_backend_dispose (GObject *object)
 
        priv = E_BOOK_BACKEND_GET_PRIVATE (object);
 
+       if (priv->registry != NULL) {
+               g_object_unref (priv->registry);
+               priv->registry = NULL;
+       }
+
        if (priv->views != NULL) {
                g_slist_free (priv->views);
                priv->views = NULL;
@@ -219,6 +247,18 @@ e_book_backend_class_init (EBookBackendClass *class)
                        NULL,
                        G_PARAM_READWRITE |
                        G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
+               PROP_REGISTRY,
+               g_param_spec_object (
+                       "registry",
+                       "Registry",
+                       "Data source registry",
+                       E_TYPE_SOURCE_REGISTRY,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -278,6 +318,24 @@ e_book_backend_set_cache_dir (EBookBackend *backend,
 }
 
 /**
+ * e_book_backend_get_registry:
+ * @backend: an #EBookBackend
+ *
+ * Returns the data source registry to which #EBackend:source belongs.
+ *
+ * Returns: an #ESourceRegistry
+ *
+ * Since: 3.6
+ **/
+ESourceRegistry *
+e_book_backend_get_registry (EBookBackend *backend)
+{
+       g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), NULL);
+
+       return backend->priv->registry;
+}
+
+/**
  * e_book_backend_open:
  * @backend: an #EBookBackend
  * @book: an #EDataBook
@@ -668,37 +726,6 @@ e_book_backend_stop_book_view (EBookBackend *backend,
 }
 
 /**
- * e_book_backend_authenticate_user:
- * @backend: an #EBookBackend
- * @cancellable: a #GCancellable for the operation
- * @credentials: #ECredentials to use for authentication
- *
- * Notifies @backend about @credentials provided by user to use
- * for authentication. This notification is usually called during
- * opening phase as a response to e_book_backend_notify_auth_required()
- * on the client side and it results in setting property 'opening' to %TRUE
- * unless the backend is already opened. This function finishes opening
- * phase, thus it should be finished with e_book_backend_notify_opened().
- *
- * See information at e_book_backend_open() for more details
- * how the opening phase works.
- **/
-void
-e_book_backend_authenticate_user (EBookBackend *backend,
-                                  GCancellable *cancellable,
-                                  ECredentials *credentials)
-{
-       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
-       g_return_if_fail (credentials != NULL);
-       g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->authenticate_user);
-
-       if (backend->priv->opened)
-               backend->priv->opening = TRUE;
-
-       (* E_BOOK_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, cancellable, credentials);
-}
-
-/**
  * e_book_backend_add_book_view:
  * @backend: an #EBookBackend
  * @view: an #EDataBookView
@@ -1162,48 +1189,6 @@ e_book_backend_notify_online (EBookBackend *backend,
 }
 
 /**
- * e_book_backend_notify_auth_required:
- * @backend: an #EBookBackend
- * @is_self: Use %TRUE to indicate the authentication is required
- *    for the @backend, otheriwse the authentication is for any
- *    other source. Having @credentials %NULL means @is_self
- *    automatically.
- * @credentials: an #ECredentials that contains extra information for
- *    a source for which authentication is requested.
- *    This parameter can be %NULL to indicate "for this book".
- *
- * Notifies clients that @backend requires authentication in order to
- * connect. This function call does not influence 'opening', but 
- * influences 'opened' property, which is set to %FALSE when @is_self
- * is %TRUE or @credentials is %NULL. Opening phase is finished
- * by e_book_backend_notify_opened() if this is requested for @backend.
- *
- * See e_book_backend_open() for a description how the whole opening
- * phase works.
- *
- * Meant to be used by backend implementations.
- **/
-void
-e_book_backend_notify_auth_required (EBookBackend *backend,
-                                     gboolean is_self,
-                                     const ECredentials *credentials)
-{
-       EBookBackendPrivate *priv;
-       GSList *clients;
-
-       priv = backend->priv;
-       g_mutex_lock (priv->clients_mutex);
-
-       if (is_self || !credentials)
-               priv->opened = FALSE;
-
-       for (clients = priv->clients; clients != NULL; clients = g_slist_next (clients))
-               e_data_book_report_auth_required (E_DATA_BOOK (clients->data), credentials);
-
-       g_mutex_unlock (priv->clients_mutex);
-}
-
-/**
  * e_book_backend_notify_opened:
  * @backend: an #EBookBackend
  * @error: a #GError corresponding to the error encountered during
index 78d1aae..919a0a9 100644 (file)
@@ -28,8 +28,7 @@
 #include <libebackend/e-backend.h>
 #include <libedata-book/e-data-book-types.h>
 #include <libedata-book/e-data-book.h>
-#include <libedataserver/e-source.h>
-#include <libedataserver/e-credentials.h>
+#include <libedataserver/e-source-registry.h>
 
 G_BEGIN_DECLS
 
@@ -148,7 +147,6 @@ struct _EBookBackendClass {
 
        void    (* open)                        (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, gboolean only_if_exists);
        void    (* remove)                      (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable);
-       void    (* authenticate_user)           (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials);
 
        void    (* refresh)                     (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable);
        void    (* create_contacts)             (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const GSList *vcards);
@@ -171,6 +169,8 @@ GType               e_book_backend_get_type         (void);
 
 const gchar *  e_book_backend_get_cache_dir    (EBookBackend *backend);
 void           e_book_backend_set_cache_dir    (EBookBackend *backend, const gchar *cache_dir);
+ESourceRegistry *
+               e_book_backend_get_registry     (EBookBackend *backend);
 
 gboolean       e_book_backend_add_client       (EBookBackend *backend, EDataBook *book);
 void           e_book_backend_remove_client    (EBookBackend *backend, EDataBook *book);
@@ -179,7 +179,6 @@ gboolean    e_book_backend_is_opened        (EBookBackend *backend);
 gboolean       e_book_backend_is_opening       (EBookBackend *backend);
 gboolean       e_book_backend_is_readonly      (EBookBackend *backend);
 gboolean       e_book_backend_is_removed       (EBookBackend *backend);
-void           e_book_backend_authenticate_user (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials);
 
 void           e_book_backend_get_backend_property (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *prop_name);
 void           e_book_backend_set_backend_property (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value);
@@ -207,7 +206,6 @@ void                e_book_backend_notify_complete  (EBookBackend *backend);
 void           e_book_backend_notify_error     (EBookBackend *backend, const gchar *message);
 void           e_book_backend_notify_readonly  (EBookBackend *backend, gboolean is_readonly);
 void           e_book_backend_notify_online    (EBookBackend *backend, gboolean is_online);
-void           e_book_backend_notify_auth_required (EBookBackend *backend, gboolean is_self, const ECredentials *credentials);
 void           e_book_backend_notify_opened    (EBookBackend *backend, GError *error);
 void           e_book_backend_notify_property_changed (EBookBackend *backend, const gchar *prop_name, const gchar *prop_value);
 
index bf8e67b..f421cdf 100644 (file)
 #ifdef HAVE_GOA
 #define GOA_API_IS_SUBJECT_TO_CHANGE
 #include <goa/goa.h>
-
-/* This is the property name or URL parameter under which we
- * embed the GoaAccount ID into an EAccount or ESource object. */
-#define GOA_KEY "goa-account-id"
 #endif
 
+#include <libedataserver/e-source-address-book.h>
+#include <libedataserver/e-source-goa.h>
+
 #include "e-book-backend.h"
 #include "e-book-backend-factory.h"
 #include "e-data-book.h"
@@ -49,6 +48,7 @@
        ((obj), E_TYPE_DATA_BOOK_FACTORY, EDataBookFactoryPrivate))
 
 struct _EDataBookFactoryPrivate {
+       ESourceRegistry *registry;
        EGdbusBookFactory *gdbus_object;
 
        GMutex *books_lock;
@@ -65,6 +65,11 @@ struct _EDataBookFactoryPrivate {
 #endif
 };
 
+enum {
+       PROP_0,
+       PROP_REGISTRY
+};
+
 /* Forward Declarations */
 static void    e_data_book_factory_initable_init
                                                (GInitableIface *interface);
@@ -77,39 +82,43 @@ G_DEFINE_TYPE_WITH_CODE (
                G_TYPE_INITABLE,
                e_data_book_factory_initable_init))
 
-static gchar *
-e_data_book_factory_extract_proto_from_uri (const gchar *uri)
-{
-       gchar *proto, *cp;
-
-       cp = strchr (uri, ':');
-       if (cp == NULL)
-               return NULL;
-
-       proto = g_malloc0 (cp - uri + 1);
-       strncpy (proto, uri, cp - uri);
-
-       return proto;
-}
-
 static EBackend *
-data_book_factory_ref_backend (EDataBookFactory *factory,
+data_book_factory_ref_backend (EDataFactory *factory,
                                ESource *source,
-                               const gchar *uri)
+                               GError **error)
 {
        EBackend *backend;
-       gchar *hash_key;
+       ESourceBackend *extension;
+       const gchar *extension_name;
+       gchar *backend_name;
+
+       /* For address books the hash key is simply the backend name.
+        * (cf. calendar hash keys, which are slightly more complex) */
 
-       hash_key = e_data_book_factory_extract_proto_from_uri (uri);
-       if (hash_key == NULL) {
-               g_warning ("Cannot extract protocol from URI %s", uri);
+       extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+       extension = e_source_get_extension (source, extension_name);
+       backend_name = e_source_backend_dup_backend_name (extension);
+
+       if (backend_name == NULL || *backend_name == '\0') {
+               g_set_error (
+                       error, E_DATA_BOOK_ERROR,
+                       E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
+                       _("No backend name in source '%s'"),
+                       e_source_get_display_name (source));
+               g_free (backend_name);
                return NULL;
        }
 
-       backend = e_data_factory_ref_backend (
-               E_DATA_FACTORY (factory), hash_key, source);
+       backend = e_data_factory_ref_backend (factory, backend_name, source);
 
-       g_free (hash_key);
+       if (backend == NULL)
+               g_set_error (
+                       error, E_DATA_BOOK_ERROR,
+                       E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
+                       _("Invalid backend name '%s' in source '%s'"),
+                       backend_name, e_source_get_display_name (source));
+
+       g_free (backend_name);
 
        return backend;
 }
@@ -173,19 +182,130 @@ book_freed_cb (EDataBookFactory *factory,
        e_dbus_server_release (E_DBUS_SERVER (factory));
 }
 
+#ifdef HAVE_GOA
+static void
+data_book_factory_collect_goa_accounts (EDataBookFactory *factory)
+{
+       GList *list, *iter;
+
+       g_hash_table_remove_all (factory->priv->goa_accounts);
+
+       list = goa_client_get_accounts (factory->priv->goa_client);
+
+       for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+               GoaObject *goa_object;
+               GoaAccount *goa_account;
+               const gchar *goa_account_id;
+
+               goa_object = GOA_OBJECT (iter->data);
+
+               goa_account = goa_object_peek_account (goa_object);
+               goa_account_id = goa_account_get_id (goa_account);
+               g_return_if_fail (goa_account_id != NULL);
+
+               /* Takes ownership of the GoaObject. */
+               g_hash_table_insert (
+                       factory->priv->goa_accounts,
+                       g_strdup (goa_account_id), goa_object);
+       }
+
+       g_list_free (list);
+}
+
+static void
+data_book_factory_goa_account_added_cb (GoaClient *goa_client,
+                                        GoaObject *goa_object,
+                                        EDataBookFactory *factory)
+{
+       GoaAccount *goa_account;
+       const gchar *goa_account_id;
+
+       goa_account = goa_object_peek_account (goa_object);
+       goa_account_id = goa_account_get_id (goa_account);
+       g_return_if_fail (goa_account_id != NULL);
+
+       g_hash_table_insert (
+               factory->priv->goa_accounts,
+               g_strdup (goa_account_id),
+               g_object_ref (goa_object));
+}
+
+static void
+data_book_factory_goa_account_removed_cb (GoaClient *goa_client,
+                                          GoaObject *goa_object,
+                                          EDataBookFactory *factory)
+{
+       GoaAccount *goa_account;
+       const gchar *goa_account_id;
+
+       goa_account = goa_object_peek_account (goa_object);
+       goa_account_id = goa_account_get_id (goa_account);
+       g_return_if_fail (goa_account_id != NULL);
+
+       g_hash_table_remove (factory->priv->goa_accounts, goa_account_id);
+}
+
+static void
+book_backend_factory_match_goa_object (EDataBookFactory *factory,
+                                       EBackend *backend)
+{
+       ESource *source;
+       ESourceRegistry *registry;
+       GoaObject *goa_object = NULL;
+       gchar *goa_account_id = NULL;
+       const gchar *extension_name;
+
+       /* Embed the corresponding GoaObject in the EBookBackend
+        * so the backend can retrieve it.  We're not ready to add
+        * formal API for this to EBookBackend just yet. */
+
+       registry = e_data_book_factory_get_registry (factory);
+
+       source = e_backend_get_source (backend);
+       extension_name = E_SOURCE_EXTENSION_GOA;
+
+       /* Check source and its ancestors for a
+        * [GNOME Online Accounts] extension. */
+       source = e_source_registry_find_extension (
+               registry, source, extension_name);
+
+       if (source != NULL) {
+               ESourceGoa *extension;
+
+               extension = e_source_get_extension (source, extension_name);
+               goa_account_id = e_source_goa_dup_account_id (extension);
+               g_object_unref (source);
+       }
+
+       if (goa_account_id != NULL) {
+               goa_object = g_hash_table_lookup (
+                       factory->priv->goa_accounts, goa_account_id);
+               g_free (goa_account_id);
+       }
+
+       if (goa_object != NULL) {
+               g_object_set_data_full (
+                       G_OBJECT (backend),
+                       "GNOME Online Account",
+                       g_object_ref (goa_object),
+                       (GDestroyNotify) g_object_unref);
+       }
+}
+#endif /* HAVE_GOA */
+
 static gboolean
 impl_BookFactory_get_book (EGdbusBookFactory *object,
                            GDBusMethodInvocation *invocation,
-                           const gchar *in_source,
+                           const gchar *uid,
                            EDataBookFactory *factory)
 {
        EDataBook *book;
        EBackend *backend;
        EDataBookFactoryPrivate *priv = factory->priv;
        GDBusConnection *connection;
+       ESourceRegistry *registry;
        ESource *source;
        gchar *path;
-       gchar *uri;
        const gchar *sender;
        GList *list;
        GError *error = NULL;
@@ -193,84 +313,51 @@ impl_BookFactory_get_book (EGdbusBookFactory *object,
        sender = g_dbus_method_invocation_get_sender (invocation);
        connection = g_dbus_method_invocation_get_connection (invocation);
 
-       if (in_source == NULL || in_source[0] == '\0') {
-               error = g_error_new (
-                       E_DATA_BOOK_ERROR,
-                       E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
-                       _("Empty URI"));
-               g_dbus_method_invocation_return_gerror (invocation, error);
-               g_error_free (error);
-
-               return TRUE;
-       }
+       registry = e_data_book_factory_get_registry (factory);
 
-       source = e_source_new_from_standalone_xml (in_source);
-       if (!source) {
-               error = g_error_new (
+       if (uid == NULL || *uid == '\0') {
+               error = g_error_new_literal (
                        E_DATA_BOOK_ERROR,
                        E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
-                       _("Invalid source"));
+                       _("Missing source UID"));
                g_dbus_method_invocation_return_gerror (invocation, error);
                g_error_free (error);
 
                return TRUE;
        }
 
-       uri = e_source_get_uri (source);
-
-       if (uri == NULL || *uri == '\0') {
-               g_object_unref (source);
-               g_free (uri);
+       source = e_source_registry_ref_source (registry, uid);
 
+       if (source == NULL) {
                error = g_error_new (
                        E_DATA_BOOK_ERROR,
                        E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
-                       _("Empty URI"));
+                       _("No such source for UID '%s'"), uid);
                g_dbus_method_invocation_return_gerror (invocation, error);
                g_error_free (error);
 
                return TRUE;
        }
 
-       backend = data_book_factory_ref_backend (factory, source, uri);
+       backend = data_book_factory_ref_backend (
+               E_DATA_FACTORY (factory), source, &error);
 
-       if (backend == NULL) {
-               g_free (uri);
-               g_object_unref (source);
+       g_object_unref (source);
 
-               error = g_error_new (
-                       E_DATA_BOOK_ERROR,
-                       E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
-                       _("Invalid source"));
+       if (error != NULL) {
                g_dbus_method_invocation_return_gerror (invocation, error);
                g_error_free (error);
 
                return TRUE;
        }
 
-       g_mutex_lock (priv->books_lock);
+       g_return_val_if_fail (E_IS_BACKEND (backend), FALSE);
 
        e_dbus_server_hold (E_DBUS_SERVER (factory));
 
 #ifdef HAVE_GOA
-       {
-               GoaObject *goa_object = NULL;
-               const gchar *goa_account_id;
-
-               /* Embed the corresponding GoaObject in the EBookBackend
-                * so the backend can retrieve it.  We're not ready to add
-                * formal API for this to EBookBackend just yet. */
-               goa_account_id = e_source_get_property (source, GOA_KEY);
-               if (goa_account_id != NULL)
-                       goa_object = g_hash_table_lookup (
-                               factory->priv->goa_accounts, goa_account_id);
-               if (GOA_IS_OBJECT (goa_object))
-                       g_object_set_data_full (
-                               G_OBJECT (backend),
-                               "GNOME Online Account",
-                               g_object_ref (goa_object),
-                               (GDestroyNotify) g_object_unref);
-       }
+       /* See if there's a matching GoaObject for this backend. */
+       book_backend_factory_match_goa_object (factory, backend);
 #endif
 
        path = construct_book_factory_path ();
@@ -293,9 +380,6 @@ impl_BookFactory_get_book (EGdbusBookFactory *object,
 
        g_mutex_unlock (priv->books_lock);
 
-       g_object_unref (source);
-       g_free (uri);
-
        e_gdbus_book_factory_complete_get_book (
                object, invocation, path, error);
 
@@ -321,12 +405,35 @@ remove_data_book_cb (EDataBook *data_book)
 }
 
 static void
+data_book_factory_get_property (GObject *object,
+                                guint property_id,
+                                GValue *value,
+                                GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_REGISTRY:
+                       g_value_set_object (
+                               value,
+                               e_data_book_factory_get_registry (
+                               E_DATA_BOOK_FACTORY (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
 data_book_factory_dispose (GObject *object)
 {
        EDataBookFactoryPrivate *priv;
 
        priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (object);
 
+       if (priv->registry != NULL) {
+               g_object_unref (priv->registry);
+               priv->registry = NULL;
+       }
+
        if (priv->gdbus_object != NULL) {
                g_object_unref (priv->gdbus_object);
                priv->gdbus_object = NULL;
@@ -451,9 +558,13 @@ data_book_factory_initable_init (GInitable *initable,
                                  GCancellable *cancellable,
                                  GError **error)
 {
-       /* XXX Nothing to do here just yet.  More to come soon. */
+       EDataBookFactoryPrivate *priv;
 
-       return TRUE;
+       priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (initable);
+
+       priv->registry = e_source_registry_new_sync (cancellable, error);
+
+       return (priv->registry != NULL);
 }
 
 static void
@@ -466,6 +577,7 @@ e_data_book_factory_class_init (EDataBookFactoryClass *class)
        g_type_class_add_private (class, sizeof (EDataBookFactoryPrivate));
 
        object_class = G_OBJECT_CLASS (class);
+       object_class->get_property = data_book_factory_get_property;
        object_class->dispose = data_book_factory_dispose;
        object_class->finalize = data_book_factory_finalize;
 
@@ -478,6 +590,17 @@ e_data_book_factory_class_init (EDataBookFactoryClass *class)
 
        data_factory_class = E_DATA_FACTORY_CLASS (class);
        data_factory_class->backend_factory_type = E_TYPE_BOOK_BACKEND_FACTORY;
+
+       g_object_class_install_property (
+               object_class,
+               PROP_REGISTRY,
+               g_param_spec_object (
+                       "registry",
+                       "Registry",
+                       "Data source registry",
+                       E_TYPE_SOURCE_REGISTRY,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -486,44 +609,6 @@ e_data_book_factory_initable_init (GInitableIface *interface)
        interface->init = data_book_factory_initable_init;
 }
 
-#ifdef HAVE_GOA
-static void
-e_data_book_factory_update_goa_accounts (EDataBookFactory *factory)
-{
-       GList *list, *iter;
-
-       g_hash_table_remove_all (factory->priv->goa_accounts);
-
-       list = goa_client_get_accounts (factory->priv->goa_client);
-
-       for (iter = list; iter != NULL; iter = g_list_next (iter)) {
-               GoaObject *goa_object;
-               GoaAccount *goa_account;
-               const gchar *goa_account_id;
-
-               goa_object = GOA_OBJECT (iter->data);
-               goa_account = goa_object_peek_account (goa_object);
-               goa_account_id = goa_account_get_id (goa_account);
-
-               /* Takes ownership of the GoaObject. */
-               g_hash_table_insert (
-                       factory->priv->goa_accounts,
-                       g_strdup (goa_account_id), goa_object);
-       }
-
-       g_list_free (list);
-}
-
-static void
-e_data_book_factory_accounts_changed_cb (GoaClient *client,
-                                         GDBusObject *object,
-                                         EDataBookFactory *factory)
-{
-       e_data_book_factory_update_goa_accounts (factory);
-}
-
-#endif
-
 static void
 e_data_book_factory_init (EDataBookFactory *factory)
 {
@@ -561,17 +646,16 @@ e_data_book_factory_init (EDataBookFactory *factory)
        factory->priv->goa_client = goa_client_new_sync (NULL, &error);
 
        if (factory->priv->goa_client != NULL) {
-               e_data_book_factory_update_goa_accounts (factory);
+               data_book_factory_collect_goa_accounts (factory);
 
                g_signal_connect (
                        factory->priv->goa_client, "account_added",
-                       G_CALLBACK (e_data_book_factory_accounts_changed_cb), factory);
+                       G_CALLBACK (data_book_factory_goa_account_added_cb),
+                       factory);
                g_signal_connect (
                        factory->priv->goa_client, "account_removed",
-                       G_CALLBACK (e_data_book_factory_accounts_changed_cb), factory);
-               g_signal_connect (
-                       factory->priv->goa_client, "account_changed",
-                       G_CALLBACK (e_data_book_factory_accounts_changed_cb), factory);
+                       G_CALLBACK (data_book_factory_goa_account_removed_cb),
+                       factory);
        } else if (error != NULL) {
                g_warning ("%s", error->message);
                g_error_free (error);
@@ -587,3 +671,12 @@ e_data_book_factory_new (GCancellable *cancellable,
                E_TYPE_DATA_BOOK_FACTORY,
                cancellable, error, NULL);
 }
+
+ESourceRegistry *
+e_data_book_factory_get_registry (EDataBookFactory *factory)
+{
+       g_return_val_if_fail (E_IS_DATA_BOOK_FACTORY (factory), NULL);
+
+       return factory->priv->registry;
+}
+
index 13bba49..2c4de6a 100644 (file)
@@ -22,6 +22,7 @@
 #define E_DATA_BOOK_FACTORY_H
 
 #include <libebackend/e-data-factory.h>
+#include <libedataserver/e-source-registry.h>
 
 /* Standard GObject macros */
 #define E_TYPE_DATA_BOOK_FACTORY \
@@ -60,6 +61,9 @@ struct _EDataBookFactoryClass {
 GType          e_data_book_factory_get_type    (void) G_GNUC_CONST;
 EDBusServer *  e_data_book_factory_new         (GCancellable *cancellable,
                                                 GError **error);
+ESourceRegistry *
+               e_data_book_factory_get_registry
+                                               (EDataBookFactory *factory);
 
 G_END_DECLS
 
index 095c9bd..54cc379 100644 (file)
@@ -25,7 +25,6 @@
 #include <glib/gi18n.h>
 #include <gio/gio.h>
 
-#include <libedataserver/e-credentials.h>
 #include <libedataserver/e-data-server-util.h>
 #include <libedataserver/e-operation-pool.h>
 
@@ -65,7 +64,6 @@ typedef enum {
        OP_GET_CONTACT,
        OP_GET_CONTACTS,
        OP_GET_CONTACTS_UIDS,
-       OP_AUTHENTICATE,
        OP_ADD_CONTACTS,
        OP_REMOVE_CONTACTS,
        OP_MODIFY_CONTACTS,
@@ -88,8 +86,6 @@ typedef struct {
                gboolean only_if_exists;
                /* OP_GET_CONTACT */
                gchar *uid;
-               /* OP_AUTHENTICATE */
-               ECredentials *credentials;
                /* OP_REMOVE_CONTACTS */
                GSList *ids;
                /* OP_ADD_CONTACT */
@@ -233,10 +229,6 @@ operation_thread (gpointer data,
                }
                g_free (op->d.query);
                break;
-       case OP_AUTHENTICATE:
-               e_book_backend_authenticate_user (backend, op->cancellable, op->d.credentials);
-               e_credentials_free (op->d.credentials);
-               break;
        case OP_CANCEL_OPERATION:
                g_static_rec_mutex_lock (&op->book->priv->pending_ops_lock);
 
@@ -746,31 +738,6 @@ impl_Book_get_view (EGdbusBook *object,
 }
 
 static gboolean
-impl_Book_authenticate_user (EGdbusBook *object,
-                             GDBusMethodInvocation *invocation,
-                             const gchar * const *in_credentials,
-                             EDataBook *book)
-{
-       OperationData *op;
-
-       if (in_credentials == NULL) {
-               GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_ARG, NULL);
-               /* Translators: This is prefix to a detailed error message */
-               data_book_return_error (invocation, error, _("Cannot authenticate user: "));
-               g_error_free (error);
-               return TRUE;
-       }
-
-       op = op_new (OP_AUTHENTICATE, book);
-       op->d.credentials = e_credentials_new_strv (in_credentials);
-
-       e_gdbus_book_complete_authenticate_user (book->priv->gdbus_object, invocation, NULL);
-       e_operation_pool_push (ops_pool, op);
-
-       return TRUE;
-}
-
-static gboolean
 impl_Book_cancel_operation (EGdbusBook *object,
                             GDBusMethodInvocation *invocation,
                             guint in_opid,
@@ -1163,29 +1130,6 @@ e_data_book_report_online (EDataBook *book,
        e_gdbus_book_emit_online (book->priv->gdbus_object, is_online);
 }
 
-/* credentilas contains extra information for a source for which authentication is requested.
- * This parameter can be NULL to indicate "for this book".
-*/
-void
-e_data_book_report_auth_required (EDataBook *book,
-                                  const ECredentials *credentials)
-{
-       gchar *empty_strv[2];
-       gchar **strv = NULL;
-
-       g_return_if_fail (book != NULL);
-
-       empty_strv[0] = NULL;
-       empty_strv[1] = NULL;
-
-       if (credentials)
-               strv = e_credentials_to_strv (credentials);
-
-       e_gdbus_book_emit_auth_required (book->priv->gdbus_object, (const gchar * const *) (strv ? strv : empty_strv));
-
-       g_strfreev (strv);
-}
-
 /**
  * e_data_book_report_opened:
  *
@@ -1404,9 +1348,6 @@ e_data_book_init (EDataBook *ebook)
                gdbus_object, "handle-get-contact-list-uids",
                G_CALLBACK (impl_Book_get_contact_list_uids), ebook);
        g_signal_connect (
-               gdbus_object, "handle-authenticate-user",
-               G_CALLBACK (impl_Book_authenticate_user), ebook);
-       g_signal_connect (
                gdbus_object, "handle-add-contacts",
                G_CALLBACK (impl_Book_add_contacts), ebook);
        g_signal_connect (
index 2bd6d65..8cf1d98 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <gio/gio.h>
 
-#include <libedataserver/e-credentials.h>
 #include <libedataserver/e-source.h>
 
 #include "e-book-backend.h"
@@ -146,7 +145,6 @@ void                e_data_book_respond_get_contact_list_uids       (EDataBook *book, guint32 opid,
 void           e_data_book_report_error                        (EDataBook *book, const gchar *message);
 void           e_data_book_report_readonly                     (EDataBook *book, gboolean readonly);
 void           e_data_book_report_online                       (EDataBook *book, gboolean is_online);
-void           e_data_book_report_auth_required                (EDataBook *book, const ECredentials *credentials);
 void           e_data_book_report_opened                       (EDataBook *book, const GError *error);
 void           e_data_book_report_backend_property_changed     (EDataBook *book, const gchar *prop_name, const gchar *prop_value);
 
index 8be711e..d6595a0 100644 (file)
@@ -17,7 +17,6 @@
     <signal name="connection">
        <arg name="connected" type="b"/>
     </signal>
-    <signal name="auth_required"/>
 
     <method name="open">
       <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_AddressBook_Book_open"/>
       <arg name="vcards" type="as" direction="out"/>
     </method>
 
-    <method name="authenticateUser">
-      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_AddressBook_Book_authenticateUser"/>
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg name="user" type="s" direction="in"/>
-      <arg name="passwd" type="s" direction="in"/>
-      <arg name="auth_method" type="s" direction="in"/>
-    </method>
-
     <method name="addContact">
       <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_AddressBook_Book_addContact"/>
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
index 8a17ae2..902978d 100644 (file)
@@ -14,13 +14,13 @@ BOOK_BACKEND_PROPERTY_SUPPORTED_AUTH_METHODS
 BOOK_BACKEND_PROPERTY_REVISION
 e_book_backend_get_cache_dir
 e_book_backend_set_cache_dir
+e_book_backend_get_registry
 e_book_backend_add_client
 e_book_backend_remove_client
 e_book_backend_is_opened
 e_book_backend_is_opening
 e_book_backend_is_readonly
 e_book_backend_is_removed
-e_book_backend_authenticate_user
 e_book_backend_get_backend_property
 e_book_backend_set_backend_property
 e_book_backend_open
@@ -32,7 +32,6 @@ e_book_backend_modify_contacts
 e_book_backend_get_contact
 e_book_backend_get_contact_list
 e_book_backend_get_contact_list_uids
-e_book_backend_authenticate_user
 e_book_backend_start_book_view
 e_book_backend_stop_book_view
 e_book_backend_add_book_view
@@ -44,7 +43,6 @@ e_book_backend_notify_complete
 e_book_backend_notify_error
 e_book_backend_notify_readonly
 e_book_backend_notify_online
-e_book_backend_notify_auth_required
 e_book_backend_notify_opened
 e_book_backend_notify_property_changed
 e_book_backend_sync
@@ -244,7 +242,6 @@ e_book_backend_sync_modify_contacts
 e_book_backend_sync_get_contact
 e_book_backend_sync_get_contact_list
 e_book_backend_sync_get_contact_list_uids
-e_book_backend_sync_authenticate_user
 <SUBSECTION Standard>
 E_BOOK_BACKEND_SYNC
 E_IS_BOOK_BACKEND_SYNC
@@ -285,7 +282,6 @@ e_data_book_respond_get_contact_list_uids
 e_data_book_report_error
 e_data_book_report_readonly
 e_data_book_report_online
-e_data_book_report_auth_required
 e_data_book_report_opened
 e_data_book_report_backend_property_changed
 e_data_book_string_slist_to_comma_string
@@ -314,6 +310,7 @@ e_data_book_status_get_type
 <TITLE>EDataBookFactory</TITLE>
 EDataBookFactory
 e_data_book_factory_new
+e_data_book_factory_get_registry
 <SUBSECTION Standard>
 E_DATA_BOOK_FACTORY
 E_IS_DATA_BOOK_FACTORY