[evolution-kolab/ek-wip-porting: 3/3] CamelIMAPXExtd{Server, Store}: fixed capabilities handling



commit aef2d6ffc5e3a9b88f8bfd54820c6f5b5f385486
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Thu Jul 19 16:14:50 2012 +0200

    CamelIMAPXExtd{Server,Store}: fixed capabilities handling
    
    * moved registration of capabilities from CamelIMAPXServer
      to CamelIMAPXStore (though the capas technically belong
      to the Server, we must register new capas before having
      the ConnMan create the first Server instance for us, since
      it automatically connects and we need the capa tokens
      and flags in place before that)
    * moved storing of capabilities flags IDs from
      CamelIMAPXServer to CamelIMAPXStore and generalized
      the approach (so we can also store the ACL capa later
      on)

 src/libekolab/camel-imapx-extd-server.c       |   13 +--
 src/libekolab/camel-imapx-extd-store-friend.h |   13 +++
 src/libekolab/camel-imapx-extd-store.c        |  127 ++++++++++++++++++++++++-
 3 files changed, 143 insertions(+), 10 deletions(-)
---
diff --git a/src/libekolab/camel-imapx-extd-server.c b/src/libekolab/camel-imapx-extd-server.c
index 96917b9..7f40345 100644
--- a/src/libekolab/camel-imapx-extd-server.c
+++ b/src/libekolab/camel-imapx-extd-server.c
@@ -37,8 +37,6 @@
 
 /*----------------------------------------------------------------------------*/
 
-static guint32 imapx_capa_flag_annotatemore = 0;
-
 static gboolean
 camel_imapx_extd_server_untagged_annotation (CamelIMAPXServer *is,
                                              GCancellable *cancellable,
@@ -60,6 +58,7 @@ camel_imapx_extd_server_untagged_annotation (CamelIMAPXServer *is,
 	CamelIMAPXExtdStore *estore = NULL;
 	CamelImapxMetadata *md = NULL;
 	guint32 capa = 0;
+	guint32 capa_flag_id = 0;
 	GError *tmp_err = NULL;
 	gboolean parse_and_add_ok = FALSE;
 
@@ -70,7 +69,10 @@ camel_imapx_extd_server_untagged_annotation (CamelIMAPXServer *is,
 	estore = CAMEL_IMAPX_EXTD_STORE (is->store);
 
 	/* capability check */
-	capa = is->cinfo->capa & imapx_capa_flag_annotatemore;
+	capa_flag_id =
+		camel_imapx_extd_store_get_capa_flag_id (estore,
+		                                         CAMEL_IMAPX_EXTD_STORE_CAPA_FLAG_ANNOTATEMORE);
+	capa = is->cinfo->capa & capa_flag_id;
 	if (! capa) {
 		g_set_error (err,
 		             CAMEL_IMAPX_ERROR,
@@ -113,11 +115,6 @@ camel_imapx_extd_server_init (CamelIMAPXServer *is,
 	if (is_inited)
 		return TRUE;
 
-	/* ANNOTATEMORE server capability flag */
-	imapx_capa_flag_annotatemore =
-		imapx_register_capability (IMAPX_IMAP_TOKEN_ANNOTATEMORE);
-	g_assert (imapx_capa_flag_annotatemore > 0);
-
 	prev = camel_imapx_server_register_untagged_handler (is,
 	                                                     IMAPX_IMAP_TOKEN_ANNOTATION,
 	                                                     &desc);
diff --git a/src/libekolab/camel-imapx-extd-store-friend.h b/src/libekolab/camel-imapx-extd-store-friend.h
index ffd41c0..39230f9 100644
--- a/src/libekolab/camel-imapx-extd-store-friend.h
+++ b/src/libekolab/camel-imapx-extd-store-friend.h
@@ -30,9 +30,22 @@
 
 /*----------------------------------------------------------------------------*/
 
+typedef enum {
+	CAMEL_IMAPX_EXTD_STORE_CAPA_FLAG_ANNOTATEMORE,
+	CAMEL_IMAPX_EXTD_STORE_CAPA_FLAG_METADATA,
+	CAMEL_IMAPX_EXTD_STORE_CAPA_FLAG_ACL,
+	CAMEL_IMAPX_EXTD_STORE_CAPA_LAST_FLAG
+} camel_imapx_extd_store_capa_flag_t;
+
+/*----------------------------------------------------------------------------*/
+
 CamelImapxMetadata*
 camel_imapx_extd_store_get_md_table (CamelIMAPXExtdStore *self);
 
+guint32
+camel_imapx_extd_store_get_capa_flag_id (CamelIMAPXExtdStore *self,
+                                         camel_imapx_extd_store_capa_flag_t flag);
+
 /*----------------------------------------------------------------------------*/
 
 #endif /* _CAMEL_IMAPX_EXTD_STORE_FRIEND_H_ */
diff --git a/src/libekolab/camel-imapx-extd-store.c b/src/libekolab/camel-imapx-extd-store.c
index 13cfe36..58b0fc7 100644
--- a/src/libekolab/camel-imapx-extd-store.c
+++ b/src/libekolab/camel-imapx-extd-store.c
@@ -32,6 +32,7 @@
 #include <glib/gi18n-lib.h>
 
 #include "camel-imapx-extd-store.h"
+#include "camel-imapx-extd-store-friend.h"
 
 /*----------------------------------------------------------------------------*/
 
@@ -45,6 +46,7 @@ static CamelStoreClass *parent_store_class = NULL;
 /*----------------------------------------------------------------------------*/
 
 /* forward declarations */
+static gboolean imapx_extd_store_register_capability_flags (CamelIMAPXExtdStore *self);
 static void imapx_extd_store_initable_init (GInitableIface *interface);
 static void imapx_extd_store_network_service_init (CamelNetworkServiceInterface *interface);
 static void imapx_extd_store_subscribable_init (CamelSubscribableInterface *interface);
@@ -55,6 +57,7 @@ extern CamelServiceAuthType camel_imapx_password_authtype;
 typedef struct _CamelIMAPXExtdStorePrivate CamelIMAPXExtdStorePrivate;
 struct _CamelIMAPXExtdStorePrivate {
 	CamelImapxMetadata *md; /* raw annotation data (different from CamelKolabImapxMetadata) */
+	guint32 imapx_capa_flag_ids[CAMEL_IMAPX_EXTD_STORE_CAPA_LAST_FLAG];
 };
 
 #define CAMEL_IMAPX_EXTD_STORE_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CAMEL_TYPE_IMAPX_EXTD_STORE, CamelIMAPXExtdStorePrivate))
@@ -78,6 +81,7 @@ camel_imapx_extd_store_init (CamelIMAPXExtdStore *self)
 	CamelIMAPXExtdStorePrivate *priv = NULL;
 	CamelIMAPXStore *istore = NULL;
 	CamelIMAPXConnManager *cm = NULL;
+	gint ii = 0;
 
 	g_assert (CAMEL_IS_IMAPX_EXTD_STORE (self));
 
@@ -86,6 +90,8 @@ camel_imapx_extd_store_init (CamelIMAPXExtdStore *self)
 
 	priv->md = camel_imapx_metadata_new (CAMEL_IMAPX_METADATA_PROTO_INVAL,
 	                                     FALSE);
+	for (ii = 0; ii < CAMEL_IMAPX_EXTD_STORE_CAPA_LAST_FLAG; ii++)
+		priv->imapx_capa_flag_ids[ii] = 0;
 
 	/* remove existing conn manager.
 	 * should not normally be necessary
@@ -172,6 +178,53 @@ camel_imapx_extd_store_finalize (GObject *object)
 /*----------------------------------------------------------------------------*/
 /* internal statics */
 
+static void
+imapx_extd_store_set_capa_flag_id (CamelIMAPXExtdStore *self,
+                                   camel_imapx_extd_store_capa_flag_t flag,
+                                   guint32 id)
+{
+	CamelIMAPXExtdStorePrivate *priv = NULL;
+
+	g_assert (CAMEL_IS_IMAPX_EXTD_STORE (self));
+	g_assert (flag < CAMEL_IMAPX_EXTD_STORE_CAPA_LAST_FLAG);
+
+	priv = CAMEL_IMAPX_EXTD_STORE_PRIVATE (self);
+
+	priv->imapx_capa_flag_ids[flag] = id;
+}
+
+static gboolean
+imapx_extd_store_register_capability_flags (CamelIMAPXExtdStore *self)
+{
+	guint32 capa_flag_id = 0;
+
+	g_assert (CAMEL_IS_IMAPX_EXTD_STORE (self));
+
+	/* Registering the capability flags must be done
+	 * before CamelIMAPXServer init. The ConnManager
+	 * hands us out an inited and already connected
+	 * CamelIMAPXServer instance, which will already
+	 * have seen the server capabilities (and it will
+	 * have ignored the extended ones it did not know
+	 * about then). Hence, we need to make known to the
+	 * IMAPX utils the new flags before creating the
+	 * first CamelIMAPXServer instance. The registration
+	 * is not per CamelIMAPXServer, but global.
+	 * It is safe to call imapx_register_capability()
+	 * multiple times (if a capa is already registered, its
+	 * id is returned immediately).
+	 */
+
+	/* ANNOTATEMORE server capability flag */
+	capa_flag_id = imapx_register_capability (IMAPX_IMAP_TOKEN_ANNOTATEMORE);
+	g_return_val_if_fail (capa_flag_id > 0, FALSE);
+	imapx_extd_store_set_capa_flag_id (self,
+	                                   CAMEL_IMAPX_EXTD_STORE_CAPA_FLAG_ANNOTATEMORE,
+	                                   capa_flag_id);
+	/* (register METADATA server capability flag here) */
+
+	return TRUE;
+}
 
 /*----------------------------------------------------------------------------*/
 /* class functions */
@@ -283,6 +336,7 @@ imapx_extd_store_get_server (CamelIMAPXStore *self,
 {
 	CamelIMAPXServer *server = NULL;
 	GError *tmp_err = NULL;
+	gboolean ok = FALSE;
 
 	g_assert (CAMEL_IS_IMAPX_EXTD_STORE (self));
 	/* foldername may be NULL */
@@ -299,7 +353,20 @@ imapx_extd_store_get_server (CamelIMAPXStore *self,
 		return NULL;
 	}
 
-	g_assert (CAMEL_IS_IMAPX_SERVER (server));
+	g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (server), NULL);
+
+	/* this can be called multiple times,
+	 * which is okay (init() just returns
+	 * TRUE if already inited)
+	 */
+	ok = camel_imapx_extd_server_init (server,
+	                                   cancellable,
+	                                   &tmp_err);
+	if (! ok) {
+		g_propagate_error (err, tmp_err);
+		g_object_unref (server);
+		return NULL;
+	}
 
 	return server;
 }
@@ -327,6 +394,34 @@ imapx_extd_store_metadata_get_proto (CamelIMAPXExtdStore *self)
 
 	proto = camel_imapx_metadata_get_proto (priv->md);
 
+	if (proto != CAMEL_IMAPX_METADATA_PROTO_INVAL)
+		return proto;
+
+	/* Set the protocol type according to the
+	 * announced server capability, if we have
+	 * one advertised by the server (we assume
+	 * that the server advertises either one
+	 * or none, but not both)
+	 */
+
+	/* ANNOTATEMORE */
+	if (priv->imapx_capa_flag_ids[CAMEL_IMAPX_EXTD_STORE_CAPA_FLAG_ANNOTATEMORE]) {
+		proto = CAMEL_IMAPX_METADATA_PROTO_ANNOTATEMORE;
+		goto skip;
+	}
+
+	/* METADATA */
+	if (priv->imapx_capa_flag_ids[CAMEL_IMAPX_EXTD_STORE_CAPA_FLAG_METADATA]) {
+		proto = CAMEL_IMAPX_METADATA_PROTO_METADATA;
+		goto skip;
+	}
+
+ skip:
+	if (proto != CAMEL_IMAPX_METADATA_PROTO_INVAL) {
+		if (! camel_imapx_metadata_set_proto (priv->md, proto))
+			proto = CAMEL_IMAPX_METADATA_PROTO_INVAL;
+	}
+
 	return proto;
 }
 
@@ -446,12 +541,27 @@ imapx_extd_store_initable_initialize (GInitable *initable,
                                       GCancellable *cancellable,
                                       GError **err)
 {
+	CamelIMAPXExtdStore *self = NULL;
 	gboolean ok = FALSE;
 
 	g_assert (G_IS_INITABLE (initable));
 	/* cancellable may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
 
+	self = CAMEL_IMAPX_EXTD_STORE (initable);
+
+	/* register IMAPX capability flags (to be done before
+	 * instantiating the first CamelIMAPXServer)
+	 */
+	ok = imapx_extd_store_register_capability_flags (self);
+	if (! ok) {
+		g_set_error (err,
+		             CAMEL_IMAPX_ERROR,
+		             1, /* FIXME define and add a sensible code here */
+		             _("Cannot register extended IMAP capability flags"));
+		return FALSE;
+	}
+
 	/* chain up to parent interface's init() method. */
 	ok = parent_initable_iface->init (initable,
 	                                  cancellable,
@@ -674,7 +784,6 @@ camel_imapx_extd_store_set_metadata (CamelIMAPXExtdStore *self,
 
 /*----------------------------------------------------------------------------*/
 /* "friend" API */
-#include "camel-imapx-extd-store-friend.h"
 
 CamelImapxMetadata*
 camel_imapx_extd_store_get_md_table (CamelIMAPXExtdStore *self)
@@ -691,4 +800,18 @@ camel_imapx_extd_store_get_md_table (CamelIMAPXExtdStore *self)
 	return priv->md;
 }
 
+guint32
+camel_imapx_extd_store_get_capa_flag_id (CamelIMAPXExtdStore *self,
+                                         camel_imapx_extd_store_capa_flag_t flag)
+{
+	CamelIMAPXExtdStorePrivate *priv = NULL;
+
+	g_assert (CAMEL_IS_IMAPX_EXTD_STORE (self));
+	g_assert (flag < CAMEL_IMAPX_EXTD_STORE_CAPA_LAST_FLAG);
+
+	priv = CAMEL_IMAPX_EXTD_STORE_PRIVATE (self);
+
+	return priv->imapx_capa_flag_ids[flag];
+}
+
 /*----------------------------------------------------------------------------*/



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