[evolution-data-server/account-mgmt: 16/42] Adapt libedata-book to the new ESource API.



commit c4e984334d3f7dc645d247d1a89e27946bdd101c
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Nov 12 16:48:26 2010 -0500

    Adapt libedata-book to the new ESource API.

 addressbook/libedata-book/e-book-backend-factory.c |   20 +-
 addressbook/libedata-book/e-book-backend-sync.c    |   35 --
 addressbook/libedata-book/e-book-backend-sync.h    |    4 -
 addressbook/libedata-book/e-book-backend.c         |  145 ++++-----
 addressbook/libedata-book/e-book-backend.h         |    8 +-
 addressbook/libedata-book/e-data-book-factory.c    |  345 +++++++++++++-------
 addressbook/libedata-book/e-data-book-factory.h    |    4 +
 addressbook/libedata-book/e-data-book.c            |   59 ----
 addressbook/libedata-book/e-data-book.h            |    2 -
 addressbook/libedata-book/e-data-book.xml          |    9 -
 .../libedata-book/libedata-book-sections.txt       |    7 +-
 11 files changed, 312 insertions(+), 326 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend-factory.c b/addressbook/libedata-book/e-book-backend-factory.c
index 155e9cf..e63c173 100644
--- a/addressbook/libedata-book/e-book-backend-factory.c
+++ b/addressbook/libedata-book/e-book-backend-factory.c
@@ -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
diff --git a/addressbook/libedata-book/e-book-backend-sync.c b/addressbook/libedata-book/e-book-backend-sync.c
index e18c3aa..53d1538 100644
--- a/addressbook/libedata-book/e-book-backend-sync.c
+++ b/addressbook/libedata-book/e-book-backend-sync.c
@@ -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;
diff --git a/addressbook/libedata-book/e-book-backend-sync.h b/addressbook/libedata-book/e-book-backend-sync.h
index de27624..770e5d8 100644
--- a/addressbook/libedata-book/e-book-backend-sync.h
+++ b/addressbook/libedata-book/e-book-backend-sync.h
@@ -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__ */
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index a4d974e..0b751e2 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -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
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index 78d1aae..919a0a9 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -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);
 
diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c
index 4a1f082..83d2dd7 100644
--- a/addressbook/libedata-book/e-data-book-factory.c
+++ b/addressbook/libedata-book/e-data-book-factory.c
@@ -29,12 +29,11 @@
 #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;
 }
@@ -167,19 +176,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;
@@ -187,84 +307,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);
+	registry = e_data_book_factory_get_registry (factory);
 
-		return TRUE;
-	}
-
-	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 ();
@@ -287,9 +374,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);
 
@@ -315,12 +399,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;
@@ -445,9 +552,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
@@ -460,6 +571,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;
 
@@ -472,6 +584,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
@@ -480,44 +603,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)
 {
@@ -555,17 +640,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);
@@ -581,3 +665,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;
+}
+
diff --git a/addressbook/libedata-book/e-data-book-factory.h b/addressbook/libedata-book/e-data-book-factory.h
index 13bba49..2c4de6a 100644
--- a/addressbook/libedata-book/e-data-book-factory.h
+++ b/addressbook/libedata-book/e-data-book-factory.h
@@ -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
 
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 03d7506..9038cd9 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -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 (
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index 2bd6d65..8cf1d98 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -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);
 
diff --git a/addressbook/libedata-book/e-data-book.xml b/addressbook/libedata-book/e-data-book.xml
index 8be711e..d6595a0 100644
--- a/addressbook/libedata-book/e-data-book.xml
+++ b/addressbook/libedata-book/e-data-book.xml
@@ -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"/>
@@ -44,14 +43,6 @@
       <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=""/>
diff --git a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
index 8a17ae2..902978d 100644
--- a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
+++ b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
@@ -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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]