[evolution-kolab/ek-wip-porting] calendar: rewrite of util functions to GCancellable, error handling fixes



commit 222311cc8b2f7733e11a213a3d88a0ed054afc3d
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Mon Dec 12 19:53:28 2011 +0100

    calendar: rewrite of util functions to GCancellable, error handling fixes
    
    * removed GObject boilerplate from kolab-util-calendar
      (not needed)
    * added GCancellable* argument to util functions
      where needed by KolabMailAccess and friends
    * added GError** arguments where functions can fail
      (improved on the somewhat poor or non-exsitent
      error handling/reporting, needs more attention)
    * let functions which can fail indicate success or
      failure with a gboolena return value (if no other
      data is returned), in addition to a GError set
    * (temporarily) removed functions from API which use
      old calendar backend status return values
      (needs porting)

 src/calendar/e-cal-backend-kolab.c       |    3 +
 src/calendar/e-cal-backend-kolab.h       |    4 +-
 src/calendar/kolab-util-calendar-cache.c |  225 +++++++++----
 src/calendar/kolab-util-calendar-cache.h |  136 +++++---
 src/calendar/kolab-util-calendar.c       |  572 ++++++++++++++++-------------
 src/calendar/kolab-util-calendar.h       |   99 +++---
 6 files changed, 619 insertions(+), 420 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-kolab.c b/src/calendar/e-cal-backend-kolab.c
index cd8cb9f..d7e36ea 100644
--- a/src/calendar/e-cal-backend-kolab.c
+++ b/src/calendar/e-cal-backend-kolab.c
@@ -26,6 +26,9 @@
 
 /*----------------------------------------------------------------------------*/
 
+#include <glib.h>
+#include <gio/gio.h>
+
 #include <libedata-cal/e-cal-backend-cache.h>
 #include <libecal/e-cal.h>
 
diff --git a/src/calendar/e-cal-backend-kolab.h b/src/calendar/e-cal-backend-kolab.h
index c6cfd0e..79f21ed 100644
--- a/src/calendar/e-cal-backend-kolab.h
+++ b/src/calendar/e-cal-backend-kolab.h
@@ -3,8 +3,8 @@
  *            e-cal-backend-kolab.h
  *
  *  Thu Jun 10 18:25:26 2010
- *  Copyright  2010  Christian Hilberg
- *  <hilberg kernelconcepts de>
+ *  Copyright  2010  Christian Hilberg <hilberg kernelconcepts de>
+ *  and Silvan Marco Fin <silvan kernelconcepts de> in 2011
  ****************************************************************************/
 
 /*
diff --git a/src/calendar/kolab-util-calendar-cache.c b/src/calendar/kolab-util-calendar-cache.c
index 676d0a7..4c4a67b 100644
--- a/src/calendar/kolab-util-calendar-cache.c
+++ b/src/calendar/kolab-util-calendar-cache.c
@@ -1,22 +1,30 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/***************************************************************************
+ *            kolab-util-calendar-cache.h
+ *
+ *  2011
+ *  Copyright  2011  Silvan Marco Fin
+ *  <silvan kernelconcepts de>
+ ****************************************************************************/
+
 /*
- * evolution-kolab
- * Copyright (C) Silvan Marco Fin 2011 <silvan kernelconcepts de>
- * 
- * evolution-kolab is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * evolution-kolab is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
  */
 
+/*----------------------------------------------------------------------------*/
+
 #include "kolab-util-calendar.h"
 #include "kolab-util-calendar-cache.h"
 
@@ -24,6 +32,8 @@
 #include <libekolab/kolab-util-backend.h>
 #include <libekolabconv/main/src/evolution/evolution-util.h>
 
+/*----------------------------------------------------------------------------*/
+
 typedef struct _KolabUtilCalendarCachePrivate KolabUtilCalendarCachePrivate;
 struct _KolabUtilCalendarCachePrivate
 {
@@ -35,6 +45,8 @@ struct _KolabUtilCalendarCachePrivate
 
 G_DEFINE_TYPE (KolabUtilCalendarCache, kolab_util_calendar_cache, G_TYPE_OBJECT)
 
+/*----------------------------------------------------------------------------*/
+
 /**
  * kolab_util_calendar_cache_get_tz:
  * @comp: An ECalComponent (Some calendar entry).
@@ -44,12 +56,12 @@ G_DEFINE_TYPE (KolabUtilCalendarCache, kolab_util_calendar_cache, G_TYPE_OBJECT)
  *.
  * The tzid of the ECalComponent DTSTART property is used to extract timezone
  * information from the supplied backend cache. The ECalComponent returned
- * should be freed, using g_object_unref (), once no longer needed. Note: 
- * Events may not provide a timezone/TZID (like UTC)! 
+ * should be freed, using g_object_unref (), once no longer needed. Note:
+ * Events may not provide a timezone/TZID (like UTC)!
  */
-ECalComponent *
+ECalComponent*
 kolab_util_calendar_cache_get_tz (ECalBackendCache *cache,
-                                  ECalComponent *comp) 
+                                  ECalComponent *comp)
 {
 	ECalComponent *ecaltz = NULL;
 	icalcomponent *icalcomp = NULL;
@@ -57,21 +69,24 @@ kolab_util_calendar_cache_get_tz (ECalBackendCache *cache,
 	gchar *tzid = NULL;
 	gint field_nr;
 	ECalComponentField tzid_search[3] = {
-		E_CAL_COMPONENT_FIELD_DTEND, 
+		E_CAL_COMPONENT_FIELD_DTEND,
 		E_CAL_COMPONENT_FIELD_DTSTART,
 		E_CAL_COMPONENT_FIELD_DUE
 	};
+	gboolean ok = FALSE;
 
 	g_assert (E_IS_CAL_BACKEND_CACHE (cache));
 	g_assert (E_IS_CAL_COMPONENT (comp));
-	
+
 	/* First of all: This method relies on Evolution already having sent the timezone.
 	 * Then retrieve timezone by its tzid and stuff it into another ECalComponent.
 	 */
 	g_assert (E_IS_CAL_COMPONENT (comp));
 	for (field_nr = 0; field_nr < 3; field_nr++) {
-		tzid = kolab_util_calendar_get_tzid (comp, tzid_search[field_nr]);
-		g_debug ("%s()[%u]: %s", __func__, __LINE__, tzid);
+		tzid = kolab_util_calendar_get_tzid (comp,
+		                                     tzid_search[field_nr]);
+		g_debug ("%s()[%u]: %s",
+		         __func__, __LINE__, tzid);
 		if (tzid != NULL)
 			break;
 	}
@@ -80,9 +95,11 @@ kolab_util_calendar_cache_get_tz (ECalBackendCache *cache,
 		 *  + All day events don't provide TZIDs. */
 		return NULL;
 	}
-	icaltz = e_cal_backend_cache_get_timezone (cache, tzid);
+	icaltz = e_cal_backend_cache_get_timezone (cache,
+	                                           tzid);
 	if (icaltz == NULL) {
-		g_debug ("%s()[%u]: timezone for \"%s\" not found.", __func__, __LINE__, tzid);
+		g_debug ("%s()[%u]: timezone for \"%s\" not found.",
+		         __func__, __LINE__, tzid);
 		g_free (tzid);
 		return NULL;
 	}
@@ -91,16 +108,18 @@ kolab_util_calendar_cache_get_tz (ECalBackendCache *cache,
 
 	ecaltz = e_cal_component_new();
 	e_cal_component_set_new_vtype (ecaltz, E_CAL_COMPONENT_TIMEZONE);
-	/* Copy the icalcomponent, so that the new created ECalComponent contains 
+	/* Copy the icalcomponent, so that the new created ECalComponent contains
 	 * a real copy und doesn't invalidate data on the backend cache on unref.
 	 */
 	icalcomp = icalcomponent_new_clone (icaltimezone_get_component ((icaltimezone *) icaltz));
 
-	if (e_cal_component_set_icalcomponent (ecaltz, icalcomp) == FALSE) {
+	ok = e_cal_component_set_icalcomponent (ecaltz, icalcomp);
+	if  (! ok) {
 		g_object_unref (ecaltz);
 		icalcomponent_free (icalcomp);
 		ecaltz = NULL;
-		g_warning ("%s[%u]: could not set timezone.", __func__, __LINE__);
+		g_warning ("%s[%u]: could not set timezone.",
+		           __func__, __LINE__);
 	}
 
 	return ecaltz;
@@ -113,19 +132,22 @@ kolab_util_calendar_cache_get_tz (ECalBackendCache *cache,
  * @uri: An ECalComponent uri string.
  * @uid: The uid to search for.
  * @bulk: Whether or not this is a mass operation.
+ * @cancellable: A cancellation stack.
  * @error: GError placeholder.
  *
  * Retrieves the the object referenced by @uid from the given @cal_cache. If
  * none is found, NULL is returned.
  *
- * Returns: An ECalComponent containing the object. Unref if no longer needed.
+ * Returns: A new ECalComponent containing the object.
+ *          Unref if no longer needed.
  **/
-ECalComponent *
+ECalComponent*
 kolab_util_calendar_cache_get_object (ECalBackendCache *cal_cache,
                                       KolabMailAccess *koma,
                                       const gchar *uri,
                                       const gchar *uid,
                                       gboolean bulk,
+                                      GCancellable *cancellable,
                                       GError **error)
 {
 	const KolabMailHandle *kmh = NULL;
@@ -134,14 +156,22 @@ kolab_util_calendar_cache_get_object (ECalBackendCache *cal_cache,
 	GError *tmp_error = NULL;
 	gchar *sourcename = NULL;
 	gchar *tzid = NULL;
+	gboolean ok = FALSE;
 
 	g_assert (E_IS_CAL_BACKEND_CACHE (cal_cache));
 	g_assert (KOLAB_IS_MAIL_ACCESS (koma));
+	g_assert (uri != NULL);
+	g_assert (uid != NULL);
+	/* cancellable may be NULL */
 	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
 	sourcename = kolab_util_backend_get_relative_path_from_uri (uri);
 
-	kmh = kolab_mail_access_get_handle (koma, uid, sourcename, &tmp_error);
+	kmh = kolab_mail_access_get_handle (koma,
+	                                    uid,
+	                                    sourcename,
+	                                    cancellable,
+	                                    &tmp_error);
 	g_free (sourcename);
 	if (kmh == NULL) {
 		/* empty object, could be "nothing found" */
@@ -151,23 +181,31 @@ kolab_util_calendar_cache_get_object (ECalBackendCache *cal_cache,
 		}
 		return NULL;
 	}
-	if (! kolab_mail_access_retrieve_handle (koma, kmh, bulk, &tmp_error)) {
+
+	ok = kolab_mail_access_retrieve_handle (koma,
+	                                        kmh,
+	                                        bulk,
+	                                        cancellable,
+	                                        &tmp_error);
+	if (! ok) {
 		g_propagate_error (error, tmp_error);
 		return NULL;
 	}
 	comp = kolab_mail_handle_get_ecalcomponent (kmh);
 
-	/* If there is timezone information, we extract it, too and put it in 
-	 * the cache, so that at any time after a call to cache_get_object() 
+	/* If there is timezone information, we extract it, too and put it in
+	 * the cache, so that at any time after a call to cache_get_object()
 	 * the timezone, if any, may be retrieved from the cache. */
-	tzid = kolab_util_calendar_get_tzid (comp, E_CAL_COMPONENT_FIELD_DTSTART);
+	tzid = kolab_util_calendar_get_tzid (comp,
+	                                     E_CAL_COMPONENT_FIELD_DTSTART);
 	if (tzid != NULL) {
 		icaltimezone *icaltz = NULL;
 		/* remember, this only works, after kolab_mail_access_retrieve_handle () */
 		tz = kolab_mail_handle_get_timezone (kmh);
 		if (tz != NULL) {
 			icaltz = ecalcomponent_tz_get_icaltimezone (tz);
-			e_cal_backend_cache_put_timezone (cal_cache, icaltz);
+			e_cal_backend_cache_put_timezone (cal_cache,
+			                                  icaltz);
 			g_free (tzid);
 			g_object_unref (tz);
 		}
@@ -176,23 +214,35 @@ kolab_util_calendar_cache_get_object (ECalBackendCache *cal_cache,
 	return comp;
 } /* kolab_util_calendar_cache_get_object () */
 
-void
+gboolean
 kolab_util_calendar_cache_update_object (ECalBackendCache *cache,
                                          KolabMailAccess *koma,
                                          const gchar *uri,
                                          const gchar *uid,
                                          gboolean bulk,
+                                         GCancellable *cancellable,
                                          GError **error)
 {
 	ECalComponent *ecalcomp = NULL;
 
 	g_assert (E_IS_CAL_BACKEND_CACHE (cache));
 	g_assert (KOLAB_IS_MAIL_ACCESS (koma));
-	g_return_if_fail (error == NULL || *error == NULL);
+	g_assert (uri != NULL);
+	g_assert (uid != NULL);
+	/* cancellable may be NULL */
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-	ecalcomp = kolab_util_calendar_cache_get_object (cache, koma, uri, uid, bulk, error);
-	if (ecalcomp != NULL)
-		g_object_unref (ecalcomp);
+	ecalcomp = kolab_util_calendar_cache_get_object (cache,
+	                                                 koma,
+	                                                 uri,
+	                                                 uid,
+	                                                 bulk,
+	                                                 cancellable,
+	                                                 error);
+	if (ecalcomp == NULL)
+		return FALSE;
+	g_object_unref (ecalcomp);
+	return TRUE;
 } /* kolab_util_calendar_cache_update_on_object () */
 
 /**
@@ -207,16 +257,18 @@ kolab_util_calendar_cache_update_object (ECalBackendCache *cache,
  *
  * Returns: The modified component.
  **/
-ECalComponent * 
+ECalComponent*
 kolab_util_calendar_cache_remove_instance (ECalBackendCache *cal_cache,
                                            CalObjModType mod,
                                            ECalComponent *oldcomp,
-                                           const gchar *uid, 
+                                           const gchar *uid,
                                            const gchar *rid)
 {
 	ECalComponent *newcomp = NULL;
 	icalcomponent *icalcomp = NULL;
-g_debug ("%s()[%u] called.", __func__, __LINE__);
+	gboolean ok = FALSE;
+
+	g_debug ("%s()[%u] called.", __func__, __LINE__);
 
 	g_assert (E_IS_CAL_BACKEND_CACHE (cal_cache));
 	g_assert (E_IS_CAL_COMPONENT (oldcomp));
@@ -224,47 +276,74 @@ g_debug ("%s()[%u] called.", __func__, __LINE__);
 	g_assert (rid != NULL);
 
 	icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (oldcomp));
-	e_cal_util_remove_instances (icalcomp, icaltime_from_string (rid), mod);
+	e_cal_util_remove_instances (icalcomp,
+	                             icaltime_from_string (rid),
+	                             mod);
 
 	newcomp = e_cal_component_new ();
 	e_cal_component_set_icalcomponent (newcomp, icalcomp);
-	if (e_cal_backend_cache_remove_component (cal_cache, uid, NULL) == FALSE) {
+	ok = e_cal_backend_cache_remove_component (cal_cache,
+	                                           uid,
+	                                           NULL);
+	if (! ok) {
 		g_debug (" + object with uid %s not found in cache", uid);
 	}
-	if (e_cal_backend_cache_put_component (cal_cache, newcomp) == FALSE) {
+	ok = e_cal_backend_cache_put_component (cal_cache,
+	                                        newcomp);
+	if (! ok) {
+		/* FIXME this is an error. If cache is still
+		 * in use, a GError needs to be set here
+		 */
 		g_debug (" + new component could not be placed into cache");
 	}
 	return newcomp;
 } /* kolab_util_calendar_cache_remove_instance () */
 
-void
+gboolean
 kolab_util_calendar_cache_update_on_query (ECalBackendCache *cache,
                                            KolabMailAccess *koma,
                                            const gchar *query,
-                                           const gchar *uri)
+                                           const gchar *uri,
+                                           GCancellable *cancellable,
+                                           GError **error)
 {
 	GList *changed_uids = NULL;
 	gchar *sourcename = NULL;
 	GError *tmp_error = NULL;
-g_debug ("%s()[%u] called.", __func__, __LINE__);
+
+	g_debug ("%s()[%u] called.", __func__, __LINE__);
 
 	g_assert (E_IS_CAL_BACKEND_CACHE (cache));
 	g_assert (KOLAB_IS_MAIL_ACCESS (koma));
+	/* query may be NULL */
+	g_assert (uri != NULL);
+	/* cancellable may be NULL */
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	sourcename = kolab_util_backend_get_relative_path_from_uri (uri);
 
-	/* First task: Update the BackendCache in case of changes */
-	changed_uids = kolab_mail_access_query_changed_uids (koma, sourcename, query, &tmp_error);
+	/* Backend cache no longer in use for PIM objects -
+	 * we can just free() the result (but must fetch
+	 * it nonetheless)
+	 */
+	changed_uids = kolab_mail_access_query_changed_uids (koma,
+	                                                     sourcename,
+	                                                     query,
+	                                                     cancellable,
+	                                                     &tmp_error);
 	if (tmp_error != NULL) {
-		g_warning ("%s()[%u]: %s", __func__, __LINE__, tmp_error->message);
-		g_error_free (tmp_error);
-		tmp_error = NULL;
+		g_propagate_error (error, tmp_error);
+		g_free (sourcename);
+		return FALSE;
 	}
 	if (changed_uids != NULL)
-		g_debug (" + changed_uids count: %u", g_list_length (changed_uids));
+		g_debug (" + changed_uids count: %u",
+		         g_list_length (changed_uids));
 	else
 		g_debug (" + changed_uids empty!");
+
 	kolab_util_glib_glist_free (changed_uids);
+	return TRUE;
 }
 
 /**
@@ -274,18 +353,20 @@ g_debug ("%s()[%u] called.", __func__, __LINE__);
  * @uri: An ECalComponent uri string.
  * @ecalcomp: An ECalComponent.
  * @bulk: Whether or not this is a mass operation.
- * @error: GError placeholder.
+ * @cancellable: A cancellation stack.
+ * @error: A GError placeholder.
  *
  * Sets a new uid to ecalcomp and assures, that it is not used in @koma, so far.
  *
  * Returns: On Success TRUE is returned.
  */
-gboolean 
-kolab_util_calendar_cache_assure_uid_on_ecalcomponent (ECalBackendCache *cache, 
+gboolean
+kolab_util_calendar_cache_assure_uid_on_ecalcomponent (ECalBackendCache *cache,
                                                        KolabMailAccess *koma,
-                                                       const gchar *uri,
                                                        ECalComponent *ecalcomp,
+                                                       const gchar *uri,
                                                        gboolean bulk,
+                                                       GCancellable *cancellable,
                                                        GError **error)
 {
 	ECalComponent *tmp_comp = NULL;
@@ -297,6 +378,8 @@ kolab_util_calendar_cache_assure_uid_on_ecalcomponent (ECalBackendCache *cache,
 	g_assert (E_IS_CAL_BACKEND_CACHE (cache));
 	g_assert (KOLAB_IS_MAIL_ACCESS (koma));
 	g_assert (E_IS_CAL_COMPONENT (ecalcomp));
+	g_assert (uri != NULL);
+	/* cancellable may be NULL */
 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	ksettings = kolab_mail_access_get_settings_handler (koma);
@@ -311,7 +394,13 @@ kolab_util_calendar_cache_assure_uid_on_ecalcomponent (ECalBackendCache *cache,
 		uid = e_cal_component_gen_uid();
 	for (;;) {
 		/* remember, this has to be called with a non-empty uid */
-		tmp_comp = kolab_util_calendar_cache_get_object (cache, koma, uri, uid, bulk, &tmp_error);
+		tmp_comp = kolab_util_calendar_cache_get_object (cache,
+		                                                 koma,
+		                                                 uri,
+		                                                 uid,
+		                                                 bulk,
+		                                                 cancellable,
+		                                                 &tmp_error);
 		if (tmp_error != NULL) {
 			g_propagate_error (error, tmp_error);
 			g_free (uid);
@@ -320,7 +409,7 @@ kolab_util_calendar_cache_assure_uid_on_ecalcomponent (ECalBackendCache *cache,
 		}
 		if (tmp_comp == NULL) {
 			e_cal_component_set_uid (ecalcomp, uid);
-			g_free (uid); 
+			g_free (uid);
 			break;
 		}
 		else {
@@ -341,9 +430,16 @@ kolab_util_calendar_cache_init (KolabUtilCalendarCache *object)
 }
 
 static void
+kolab_util_calendar_cache_dispose (GObject *object)
+{
+	/* TODO_ Add dispose code here */
+	G_OBJECT_CLASS (kolab_util_calendar_cache_parent_class)->dispose (object);
+}
+
+static void
 kolab_util_calendar_cache_finalize (GObject *object)
 {
-	/* TODO: Add deinitalization code here */
+	/* TODO: Add finalization code here */
 
 	G_OBJECT_CLASS (kolab_util_calendar_cache_parent_class)->finalize (object);
 }
@@ -356,5 +452,8 @@ kolab_util_calendar_cache_class_init (KolabUtilCalendarCacheClass *klass)
 
 	g_type_class_add_private (klass, sizeof (KolabUtilCalendarCachePrivate));
 
+	object_class->dispose = kolab_util_calendar_cache_dispose;
 	object_class->finalize = kolab_util_calendar_cache_finalize;
 }
+
+/*----------------------------------------------------------------------------*/
diff --git a/src/calendar/kolab-util-calendar-cache.h b/src/calendar/kolab-util-calendar-cache.h
index 86986fc..1ff3463 100644
--- a/src/calendar/kolab-util-calendar-cache.h
+++ b/src/calendar/kolab-util-calendar-cache.h
@@ -1,30 +1,44 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/***************************************************************************
+ *            kolab-util-calendar-cache.h
+ *
+ *  2011
+ *  Copyright  2011  Silvan Marco Fin
+ *  <silvan kernelconcepts de>
+ ****************************************************************************/
+
 /*
- * evolution-kolab
- * Copyright (C) Silvan Marco Fin 2011 <silvan kernelconcepts de>
- * 
- * evolution-kolab is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * evolution-kolab is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
  */
 
+/*----------------------------------------------------------------------------*/
+
 #ifndef _KOLAB_UTIL_CALENDAR_CACHE_H_
 #define _KOLAB_UTIL_CALENDAR_CACHE_H_
 
+/*----------------------------------------------------------------------------*/
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
 #include <libekolab/kolab-mail-access.h>
 #include <libecal/e-cal.h>
 #include <libedata-cal/e-cal-backend-cache.h>
 
-#include <glib-object.h>
+/*----------------------------------------------------------------------------*/
 
 G_BEGIN_DECLS
 
@@ -32,8 +46,8 @@ G_BEGIN_DECLS
  * SECTION:kolab-util-calendar-cache
  * @short_description: Utility methods for Evolution-Kolab calendar backend implementation with ECalBackendCache side effects.
  * @title: KolabUtilCalendarCache
- * 
- * The methods in KolabUtilCalendarCache are supposed to update the 
+ *
+ * The methods in KolabUtilCalendarCache are supposed to update the
  * ECalBackendCache as a side effect to their primary task or retrieve data
  * from the cache to fulfill its task.
  */
@@ -59,41 +73,59 @@ struct _KolabUtilCalendarCache
 	GObject parent_instance;
 };
 
-GType kolab_util_calendar_cache_get_type (void) G_GNUC_CONST;
-
-/* library functions */
-
-ECalComponent *kolab_util_calendar_cache_get_tz (ECalBackendCache *cache, ECalComponent *comp);
-ECalComponent *kolab_util_calendar_cache_get_object (ECalBackendCache *cal_cache,
-                                                     KolabMailAccess *koma,
-                                                     const gchar *uri,
-                                                     const gchar *uid,
-                                                     gboolean bulk,
-                                                     GError **error);
-ECalComponent *kolab_util_calendar_cache_remove_instance (ECalBackendCache *cal_cache,
-                                                          CalObjModType mod,
-                                                          ECalComponent *ecalcomp,
-                                                          const gchar *uid, 
-                                                          const gchar *rid);
-gboolean kolab_util_calendar_cache_assure_uid_on_ecalcomponent (ECalBackendCache *cache, 
-                                                                KolabMailAccess *koma,
-                                                                const gchar *uri,
-                                                                ECalComponent *ecalcomp,
-                                                                gboolean bulk,
-                                                                GError **error);
-void kolab_util_calendar_cache_update_on_query (ECalBackendCache *cache,
-                                                KolabMailAccess *koma,
-                                                const gchar *query,
-                                                const gchar *uri);
-void kolab_util_calendar_cache_update_object (ECalBackendCache *cache,
-                                              KolabMailAccess *koma,
-                                              const gchar *uri,
-                                              const gchar *uid,
-                                              gboolean bulk,
-                                              GError **error);
-
-/* object methods */
+GType
+kolab_util_calendar_cache_get_type (void) G_GNUC_CONST;
+
+ECalComponent*
+kolab_util_calendar_cache_get_tz (ECalBackendCache *cache,
+                                  ECalComponent *comp);
+
+ECalComponent*
+kolab_util_calendar_cache_get_object (ECalBackendCache *cal_cache,
+                                      KolabMailAccess *koma,
+                                      const gchar *uri,
+                                      const gchar *uid,
+                                      gboolean bulk,
+                                      GCancellable *cancellable,
+                                      GError **error);
+
+ECalComponent*
+kolab_util_calendar_cache_remove_instance (ECalBackendCache *cal_cache,
+                                           CalObjModType mod,
+                                           ECalComponent *ecalcomp,
+                                           const gchar *uid,
+                                           const gchar *rid);
+
+gboolean
+kolab_util_calendar_cache_assure_uid_on_ecalcomponent (ECalBackendCache *cache,
+                                                       KolabMailAccess *koma,
+                                                       ECalComponent *ecalcomp,
+                                                       const gchar *uri,
+                                                       gboolean bulk,
+                                                       GCancellable *cancellable,
+                                                       GError **error);
+
+gboolean
+kolab_util_calendar_cache_update_on_query (ECalBackendCache *cache,
+                                           KolabMailAccess *koma,
+                                           const gchar *query,
+                                           const gchar *uri,
+                                           GCancellable *cancellable,
+                                           GError **error);
+
+gboolean
+kolab_util_calendar_cache_update_object (ECalBackendCache *cache,
+                                         KolabMailAccess *koma,
+                                         const gchar *uri,
+                                         const gchar *uid,
+                                         gboolean bulk,
+                                         GCancellable *cancellable,
+                                         GError **error);
 
 G_END_DECLS
 
+/*----------------------------------------------------------------------------*/
+
 #endif /* _KOLAB_UTIL_CALENDAR_CACHE_H_ */
+
+/*----------------------------------------------------------------------------*/
diff --git a/src/calendar/kolab-util-calendar.c b/src/calendar/kolab-util-calendar.c
index 575721d..cb90054 100644
--- a/src/calendar/kolab-util-calendar.c
+++ b/src/calendar/kolab-util-calendar.c
@@ -1,210 +1,114 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/***************************************************************************
+ *            kolab-util-calendar.h
+ *
+ *  2011
+ *  Copyright  2011  Silvan Marco Fin
+ *  <silvan kernelconcepts de>
+ ****************************************************************************/
+
 /*
- * evolution-kolab
- * Copyright (C) Silvan Marco Fin <silvan kernelconcepts de> in 2011
- * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
  */
 
-#include "kolab-util-calendar.h"
+/*----------------------------------------------------------------------------*/
 
+#include <libecal/e-cal.h>
+
+#include <libekolabutil/camel-system-headers.h>
 #include <libekolabutil/kolab-util-http.h>
+#include <libekolabutil/kolab-http-job.h>
 #include <libekolabutil/kolab-util-types.h>
 #include <libekolab/kolab-settings-handler.h>
 #include <libekolab/kolab-mail-access.h>
 
-#include <camel/camel-exception.h>
-#include <libecal/e-cal.h>
-
-typedef struct _KolabUtilCalendarPrivate KolabUtilCalendarPrivate;
-struct _KolabUtilCalendarPrivate
-{
-	gchar * generic;
-};
-
-#define KOLAB_UTIL_CALENDAR_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), KOLAB_TYPE_UTIL_CALENDAR, KolabUtilCalendarPrivate))
-
-G_DEFINE_TYPE (KolabUtilCalendar, kolab_util_calendar, G_TYPE_OBJECT)
-
-/**
- * kolab_util_calendar_extract:
- * @icalcomp: An icalcomponent.
- * @source_type: The data type to process.
- * @ecalcomp: An ECalComponent to return the extracted values to.
- * @tzcomp: An ECaComponent to return contained timezone data.
- *
- * Extract supported information from icalcomponent and return them through
- * ecalcomp and tzcomp.
- * 
- * Returns: if the given component type could be extracted successfully into ecalcomp + tzcomp;
- */
-ECalBackendSyncStatus
-kolab_util_calendar_extract (icalcomponent *icalcomp,
-                             ECalSourceType source_type, 
-                             ECalComponent **ecalcomp, 
-                             ECalComponent **tzcomp) 
-{
-	ECalComponent *comp = NULL;
-	ECalComponent *tz = NULL;
-	icalcomponent *icalsub = NULL;
-	icalcomponent *icaltz = NULL;
-	icalcomponent_kind icalkind;
-
-	switch (source_type) {
-	case E_CAL_SOURCE_TYPE_EVENT:
-		icalkind = ICAL_VEVENT_COMPONENT;
-		break;
-	case E_CAL_SOURCE_TYPE_TODO:
-		icalkind = ICAL_VTODO_COMPONENT;
-		break;
-	case E_CAL_SOURCE_TYPE_JOURNAL:
-		icalkind = ICAL_VJOURNAL_COMPONENT;
-		break;
-	default:
-		g_error ("%s()[%u] Got an unknown value for ECalSourceType, this should not happen.", __func__, __LINE__);
-	}
-
-	icalsub = icalcomponent_get_first_component (icalcomp, icalkind);
-	if (icalsub == NULL) {
-		return GNOME_Evolution_Calendar_InvalidObject;
-	}
-
-	comp = e_cal_component_new ();
-	e_cal_component_set_icalcomponent (comp, icalsub);
-	*ecalcomp = e_cal_component_clone (comp);
-	g_object_unref (comp);
-
-	icaltz = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
-	if (icaltz == NULL) {
-		/* no TZ - no problem */
-		tzcomp = NULL;
-	}
-	else {
-		/* Create a new ECalComponent from the ical timezone component. */
-		tz = e_cal_component_new ();
-		e_cal_component_set_icalcomponent (tz, icaltz);
-		*tzcomp = e_cal_component_clone (tz);
-		g_object_unref (tz);
-	}
-
-	return GNOME_Evolution_Calendar_Success;
-} /* kolab_util_calendar_extract () */
-
-/**
- * kolab_util_calendar_get_tzid:
- * @comp: An ECalComponent to derive the tzid from.
- * @from: field to get the tzid from.
- *
- * The ECalComponentDateTime Struct from an ECalComponents dtstart field or 
- * dtend field is queried for its tzid.
- *
- * Returns: A newly allocated tzid string (g_free() after usage) or NULL if no ID was found.
- */
-gchar *
-kolab_util_calendar_get_tzid (ECalComponent *comp,
-                              ECalComponentField from)
-{
-	ECalComponentDateTime *dt = NULL;
-	gchar *tzid;
-
-	g_assert (E_IS_CAL_COMPONENT (comp));
-
-	dt = g_new0 (ECalComponentDateTime, 1);
-	switch (from) {
-	case E_CAL_COMPONENT_FIELD_DTSTART:
-		e_cal_component_get_dtstart (comp, dt);
-		break;
-	case E_CAL_COMPONENT_FIELD_DTEND:
-		e_cal_component_get_dtend (comp, dt);
-		break;
-	case E_CAL_COMPONENT_FIELD_DUE:
-		e_cal_component_get_due (comp, dt);
-		break;
-	default:
-		g_warning ("%s()[%u]: TZID from %u not supported.", __func__, __LINE__, from);
-		return NULL;
-	}
-
-	if (dt == NULL) {
-		g_warning ("%s()[%u]: Found ECalComponent without ECalComponentField %u.", __func__, __LINE__, from);
-		g_assert_not_reached();
-	}
+#include "kolab-util-calendar.h"
 
-	tzid = g_strdup (dt->tzid);
-	e_cal_component_free_datetime (dt);
-	g_free (dt);
-	return tzid;
-} /* kolab_util_calendar_get_tzid () */
+/*----------------------------------------------------------------------------*/
+/* internal statics */
 
-static KolabHttpJob *
+static KolabHttpJob*
 kolab_util_calendar_create_http_request (KolabSettingsHandler *ksettings,
-                                         const gchar *path)
+                                         const gchar *path,
+                                         GError **error)
 {
 	CamelURL *uri = NULL;
 	const gchar *url = NULL;
 	const gchar *user = NULL;
 	const gchar *passwd = NULL;
 	guint tls_variant = KOLAB_TLS_VARIANT_DEFAULT;
-	GError *error = NULL;
-	CamelException *ex = NULL;
+	GError *tmp_error = NULL;
 	KolabHttpJob *job = NULL;
 
-	url = kolab_settings_handler_get_char_field (ksettings, KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_URI, &error);
+	g_assert (KOLAB_IS_SETTINGS_HANDLER (ksettings));
+	g_assert (path != NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	url = kolab_settings_handler_get_char_field (ksettings,
+	                                             KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_URI,
+	                                             &tmp_error);
 	if (url == NULL) {
-		/* TODO: check for error */
-		g_error_free (error);
+		g_propagate_error (error, tmp_error);
 		return NULL;
 	}
-	tls_variant = kolab_settings_handler_get_uint_field (ksettings, KOLAB_SETTINGS_HANDLER_UINT_FIELD_TLS_VARIANT, &error);
+	tls_variant = kolab_settings_handler_get_uint_field (ksettings,
+	                                                     KOLAB_SETTINGS_HANDLER_UINT_FIELD_TLS_VARIANT,
+	                                                     &tmp_error);
 	if (error != NULL) {
-		g_warning ("%s()[%i]: %s", __func__, __LINE__, error->message);
-		g_error_free (error);
+		g_propagate_error (error, tmp_error);
+		return NULL;
+	}
+	uri = camel_url_new (url, &tmp_error);
+	if (tmp_error != NULL) {
+		g_propagate_error (error, tmp_error);
 		return NULL;
 	}
-	ex = camel_exception_new ();
-	uri = camel_url_new (url, ex);
 	if (uri == NULL) {
-		/* TODO: check for exception */
-		camel_exception_free (ex);
+		/* FIXME is this an error condition? */
 		return NULL;
 	}
-	camel_exception_free (ex);
 	switch (tls_variant) {
-		case KOLAB_TLS_VARIANT_NONE:
-			camel_url_set_protocol (uri, "http");
-			break;
-		default:
-			camel_url_set_protocol (uri, "https");			
+	case KOLAB_TLS_VARIANT_NONE:
+		camel_url_set_protocol (uri, "http");
+		break;
+	default:
+		camel_url_set_protocol (uri, "https");
 	}
 	camel_url_set_path (uri, path);
-	user = kolab_settings_handler_get_char_field (ksettings, KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_NAME, &error);
+	user = kolab_settings_handler_get_char_field (ksettings,
+	                                              KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_NAME,
+	                                              &tmp_error);
 	if (user == NULL) {
-		/* TODO: error handling */
-		g_error_free (error);
+		g_propagate_error (error, tmp_error);
 		camel_url_free (uri);
 		return NULL;
 	}
 	camel_url_set_user (uri, user);
-	passwd = kolab_settings_handler_get_char_field (ksettings, KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_PASSWORD, &error);
+	passwd = kolab_settings_handler_get_char_field (ksettings,
+	                                                KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_PASSWORD,
+	                                                &tmp_error);
 	if (passwd == NULL) {
-		/* TODO: error handling */
-		g_error_free (error);
+		g_propagate_error (error, tmp_error);
 		camel_url_free (uri);
 		return NULL;
 	}
-	camel_url_set_passwd (uri, passwd);
+
+	/* FIXME CamelURL does no longer carry auth details */
+	g_error ("%s: FIXME CamelURL does no longer carry auth details",
+	         __func__);
+	/* camel_url_set_passwd (uri, passwd); */
 
 	job = kolab_http_job_new ();
 	job->url = uri;
@@ -212,143 +116,248 @@ kolab_util_calendar_create_http_request (KolabSettingsHandler *ksettings,
 	return job;
 } /* kolab_util_calendar_create_http_request () */
 
-static KolabHttpJob *
+static KolabHttpJob*
 kolab_util_calendar_create_pfb_trigger (KolabSettingsHandler *ksettings,
-                                        const gchar *sourcename)
+                                        const gchar *sourcename,
+                                        GError **error)
 {
 	KolabHttpJob *job = NULL;
 	gchar *path = NULL;
 	const gchar *username = NULL;
 	gint source_offset = 0;
-	GError *error = NULL;
-	
-	username = kolab_settings_handler_get_char_field (ksettings, KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_NAME, &error);
-	if (error != NULL) {
-		g_warning ("%s()[%u] error: %s", __func__, __LINE__, error->message);
-		g_error_free (error);
+	GError *tmp_error = NULL;
+
+	g_assert (KOLAB_IS_SETTINGS_HANDLER (ksettings));
+	g_assert (sourcename != NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	username = kolab_settings_handler_get_char_field (ksettings,
+	                                                  KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_NAME,
+	                                                  &tmp_error);
+	if (tmp_error != NULL) {
+		g_propagate_error (error, tmp_error);
 		return NULL;
 	}
 
 	if (strncmp (username, "INBOX/", 6))
 		source_offset = 6;
-	path = g_strdup_printf ("/freebusy/trigger/%s/%s.pfb", username, sourcename+source_offset);
+	path = g_strdup_printf ("/freebusy/trigger/%s/%s.pfb",
+	                        username, sourcename+source_offset);
 
-	job = kolab_util_calendar_create_http_request (ksettings, path);
+	job = kolab_util_calendar_create_http_request (ksettings,
+	                                               path,
+	                                               &tmp_error);
 	g_free (path);
 	if (job == NULL) {
-		g_warning ("%s()[%u] call to kolab_util_calendar_http_request() returned NULL!", __func__, __LINE__);
+		g_propagate_error (error, tmp_error);
 		return NULL;
 	}
 	return job;
 } /* kolab_util_calendar_create_pfb_trigger () */
 
-static KolabHttpJob *
-kolab_util_calendar_create_xfb_request (KolabSettingsHandler *ksettings, gchar *query)
+static KolabHttpJob*
+kolab_util_calendar_create_xfb_request (KolabSettingsHandler *ksettings,
+                                        gchar *query,
+                                        GError **error)
 {
 	KolabHttpJob *job = NULL;
 	gchar *path = NULL;
+	GError *tmp_error = NULL;
+
+	g_assert (KOLAB_IS_SETTINGS_HANDLER (ksettings));
+	g_assert (query != NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
 	path = g_strdup_printf ("/freebusy/%s.ifb", query);
 
-	job = kolab_util_calendar_create_http_request (ksettings, path);
+	job = kolab_util_calendar_create_http_request (ksettings,
+	                                               path,
+	                                               &tmp_error);
 	g_free (path);
 	if (job == NULL) {
-		g_warning ("%s()[%u] call to kolab_util_calendar_create_http_request() returned NULL!", __func__, __LINE__);
+		g_propagate_error (error, tmp_error);
+		g_warning ("%s()[%u] call to kolab_util_calendar_create_http_request() returned NULL!",
+		           __func__, __LINE__);
 		return NULL;
 	}
 	return job;
 } /* kolab_util_calendar_create_xfb_request () */
 
+/*----------------------------------------------------------------------------*/
+/* public API */
+
+/**
+ * kolab_util_calendar_get_tzid:
+ * @comp: An ECalComponent to derive the tzid from.
+ * @from: field to get the tzid from.
+ *
+ * The ECalComponentDateTime Struct from an ECalComponents dtstart field or
+ * dtend field is queried for its tzid.
+ *
+ * Returns: A newly allocated tzid string (g_free() after use)
+ *          or NULL if no ID was found.
+ */
+gchar*
+kolab_util_calendar_get_tzid (ECalComponent *comp,
+                              ECalComponentField from)
+{
+	ECalComponentDateTime *dt = NULL;
+	gchar *tzid = NULL;
+
+	g_assert (E_IS_CAL_COMPONENT (comp));
+
+	dt = g_new0 (ECalComponentDateTime, 1);
+	switch (from) {
+	case E_CAL_COMPONENT_FIELD_DTSTART:
+		e_cal_component_get_dtstart (comp, dt);
+		break;
+	case E_CAL_COMPONENT_FIELD_DTEND:
+		e_cal_component_get_dtend (comp, dt);
+		break;
+	case E_CAL_COMPONENT_FIELD_DUE:
+		e_cal_component_get_due (comp, dt);
+		break;
+	default:
+		g_warning ("%s()[%u]: TZID from %u not supported.",
+		           __func__, __LINE__, from);
+		return NULL;
+	}
+
+	if (dt == NULL) {
+		g_warning ("%s()[%u]: Found ECalComponent without ECalComponentField %u.",
+		           __func__, __LINE__, from);
+		g_assert_not_reached();
+	}
+
+	tzid = g_strdup (dt->tzid);
+	e_cal_component_free_datetime (dt);
+	g_free (dt);
+	return tzid;
+} /* kolab_util_calendar_get_tzid () */
+
 gboolean
 kolab_util_calendar_toggle_pfb_trigger (KolabSettingsHandler *ksettings,
-                                        const gchar *sourcename)
+                                        const gchar *sourcename,
+                                        GError **error)
 {
-	/* Keep running on errors. 
+	/* Keep running on errors.
 	 * If an error occured, internal_state is set to false as indicator.
 	 */
 	KolabHttpJob *job = NULL;
-	gssize nbytes = 0;
-	GError *error = NULL;
+	GError *tmp_error = NULL;
 
-	job = kolab_util_calendar_create_pfb_trigger (ksettings, sourcename);
+	g_assert (KOLAB_IS_SETTINGS_HANDLER (ksettings));
+	g_assert (sourcename != NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	job = kolab_util_calendar_create_pfb_trigger (ksettings,
+	                                              sourcename,
+	                                              &tmp_error);
 	if (job == NULL) {
-		g_warning ("%s()[%u] error: could not create F/B toggle, giving up on %s.", __func__, __LINE__, sourcename);
+		g_propagate_error (error, tmp_error);
+		g_warning ("%s()[%u] error: could not create F/B toggle, giving up on %s.",
+		           __func__, __LINE__, sourcename);
 		return FALSE;
 	}
 	job->buffer = g_byte_array_new ();
-	nbytes = kolab_util_http_get (job, &error);
-	if (error == NULL) {
-		kolab_http_job_free (job);
-		return TRUE;
-	}
-	else {
-		g_warning ("%s()[%u] error: %s", __func__, __LINE__, error->message);
-		g_error_free (error);
+	(void)kolab_util_http_get (job, &tmp_error);
+	kolab_http_job_free (job);
+
+	if (tmp_error != NULL) {
+		g_propagate_error (error, tmp_error);
+		return FALSE;
 	}
-	return FALSE;
+	return TRUE;
 } /* kolab_util_calendar_toggle_pfb_trigger () */
 
-KolabHttpJob *
+KolabHttpJob*
 kolab_util_calendar_retrieve_xfb (KolabSettingsHandler *ksettings,
-                                  gchar *query)
+                                  gchar *query,
+                                  GError **error)
 {
 	KolabHttpJob *job = NULL;
-	gssize nbytes = 0;
-	GError *error = NULL;
+	GError *tmp_error = NULL;
+
+	g_assert (KOLAB_IS_SETTINGS_HANDLER (ksettings));
+	g_assert (query != NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-	job = kolab_util_calendar_create_xfb_request (ksettings, (gchar *) query);
+	job = kolab_util_calendar_create_xfb_request (ksettings,
+	                                              (gchar *) query,
+	                                              &tmp_error);
 	if (job == NULL) {
-		g_warning ("%s()[%u] error creating job, giving up on %s.", __func__, __LINE__, (gchar *) query);
+		g_propagate_error (error, tmp_error);
+		g_warning ("%s()[%u] error creating job, giving up on %s.",
+		           __func__, __LINE__, (gchar *) query);
 		return NULL;
 	}
 
 	job->buffer = g_byte_array_new ();
-	nbytes = kolab_util_http_get (job, &error);
-	if (error == NULL) {
-		job->nbytes = nbytes;
-		return job;
+	(void)kolab_util_http_get (job, &tmp_error);
+	if (tmp_error != NULL) {
+		/* might happen, perhaps the server did not now about the user. */
+		kolab_http_job_free (job);
+		g_propagate_error (error, tmp_error);
+		return NULL;
 	}
-	g_error_free (error);
-	error = NULL;
-	/* might happen, perhaps the server did not now about the user.
-	 * Do not set internal_state to false. 
-	 */
-	return NULL;
+
+	return job;
 } /* kolab_util_calendar_retrieve_xfb () */
 
-void
+gboolean
 kolab_util_calendar_store (ECalComponent *ecalcomp,
                            ECalComponent *ecaltz,
                            ECalComponent *default_tz,
                            KolabMailAccess *koma,
                            const gchar *uri,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	gchar *sourcename = NULL;
 	KolabMailHandle *kmh = NULL;
-	GError *tmp_error = NULL;
 	KolabSettingsHandler *ksettings = NULL;
-	KolabMailAccessOpmodeID mode;
+	KolabMailAccessOpmodeID mode = KOLAB_MAIL_ACCESS_OPMODE_INVAL;
 	gboolean do_trigger = FALSE;
+	gboolean ok = FALSE;
+	GError *tmp_error = NULL;
 
-	g_return_if_fail (error == NULL || *error == NULL);
-	g_assert (default_tz != NULL);
+	g_assert (E_IS_CAL_COMPONENT (ecalcomp));
+	/* ecaltz may be NULL */
+	g_assert (E_IS_CAL_COMPONENT (default_tz));
+	g_assert (KOLAB_IS_MAIL_ACCESS (koma));
+	g_assert (uri != NULL);
+	/* cancellable may be NULL */
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	ksettings = kolab_mail_access_get_settings_handler (koma);
-	if (ksettings == NULL)
-		/* FIXME: obviously, this lacks some conclusive error notification */
-		return;
+	if (ksettings == NULL) {
+		/* FIXME: set GError here */
+		return FALSE;
+	}
 
 	sourcename = kolab_util_backend_get_relative_path_from_uri (uri);
 
 	kolab_util_backend_modtime_set_on_ecalcomp (ecalcomp);
-	kmh = kolab_mail_handle_new_from_ecalcomponent (ecalcomp, ecaltz);
-	if (! kolab_mail_access_store_handle (koma, kmh, sourcename, &tmp_error))
+	kmh = kolab_mail_handle_new_from_ecalcomponent (ecalcomp,
+	                                                ecaltz);
+	ok =  kolab_mail_access_store_handle (koma,
+	                                      kmh,
+	                                      sourcename,
+	                                      cancellable,
+	                                      &tmp_error);
+	if (! ok)
 		goto cleanup;
 
-	mode = kolab_mail_access_get_opmode (koma, &tmp_error);
+	mode = kolab_mail_access_get_opmode (koma,
+	                                     &tmp_error);
 	if (tmp_error != NULL)
 		goto cleanup;
+	if (mode < KOLAB_MAIL_ACCESS_OPMODE_ONLINE) {
+		/* In OFFLINE state, the triggers are generated during
+		 * changing to ONLINE state in e_cal_backend_set_mode ().
+		 */
+		goto cleanup;
+	}
 
 	do_trigger = kolab_mail_access_source_fbtrigger_needed (koma,
 	                                                        sourcename,
@@ -357,70 +366,121 @@ kolab_util_calendar_store (ECalComponent *ecalcomp,
 		goto cleanup;
 
 	if (do_trigger == TRUE)
-		(void) kolab_util_calendar_toggle_pfb_trigger (ksettings, sourcename);
-
-	/* In OFFLINE state, the triggers are generated during changing to ONLINE 
-	 * state in e_cal_backend_set_mode ().
-	 */
-cleanup:
-	if (tmp_error != NULL)
-		g_propagate_error (error, tmp_error);
+		(void) kolab_util_calendar_toggle_pfb_trigger (ksettings,
+		                                               sourcename,
+		                                               &tmp_error);
+ cleanup:
 	g_object_unref (ksettings);
 	g_free (sourcename);
+	if (tmp_error != NULL) {
+		g_propagate_error (error, tmp_error);
+		return FALSE;
+	}
+	return TRUE;
 } /* kolab_util_calendar_store () */
 
+/*----------------------------------------------------------------------------*/
+
+#if 0 /* FIXME old */
 ECalBackendSyncStatus
 kolab_util_calendar_map_error (GError *error)
 {
 	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_Success;
-	
+
 	if (error == NULL)
 		return GNOME_Evolution_Calendar_Success;
-	
+
 	switch (error->code) {
-		case KOLAB_BACKEND_ERROR_SYNC_NOTSTORED:
-			status = GNOME_Evolution_Calendar_Success;
-			break;
-		case KOLAB_BACKEND_ERROR_NOTFOUND:
-			status = GNOME_Evolution_Calendar_ObjectNotFound;
-			break;
-		case KOLAB_BACKEND_ERROR_CONTEXT_MISUSE:
-		case KOLAB_BACKEND_ERROR_INFODB_NOFOLDER:
-			status = GNOME_Evolution_Calendar_NoSuchCal;
-			break;
-		case KOLAB_BACKEND_ERROR_DATATYPE_EVOLUTION:
-		case KOLAB_BACKEND_ERROR_DATATYPE_KOLAB:
-			status = GNOME_Evolution_Calendar_InvalidObject;
-		default:
-			status = GNOME_Evolution_Calendar_OtherError;
+	case KOLAB_BACKEND_ERROR_SYNC_NOTSTORED:
+		status = GNOME_Evolution_Calendar_Success;
+		break;
+	case KOLAB_BACKEND_ERROR_NOTFOUND:
+		status = GNOME_Evolution_Calendar_ObjectNotFound;
+		break;
+	case KOLAB_BACKEND_ERROR_CONTEXT_MISUSE:
+	case KOLAB_BACKEND_ERROR_INFODB_NOFOLDER:
+		status = GNOME_Evolution_Calendar_NoSuchCal;
+		break;
+	case KOLAB_BACKEND_ERROR_DATATYPE_EVOLUTION:
+	case KOLAB_BACKEND_ERROR_DATATYPE_KOLAB:
+		status = GNOME_Evolution_Calendar_InvalidObject;
+	default:
+		status = GNOME_Evolution_Calendar_OtherError;
 	}
-	
+
 	g_debug ("%s()[%u] ECalBackendSyncStatus: %i", __func__, __LINE__, status);
 	return status;
 }
+#endif
 
-static void
-kolab_util_calendar_init (KolabUtilCalendar *object)
-{
-	/* TODO: Add initialization code here */
-	(void) object;
-}
-
-static void
-kolab_util_calendar_finalize (GObject *object)
+#if 0 /* FIXME old */
+/**
+ * kolab_util_calendar_extract:
+ * @icalcomp: An icalcomponent.
+ * @source_type: The data type to process.
+ * @ecalcomp: An ECalComponent to return the extracted values to.
+ * @tzcomp: An ECaComponent to return contained timezone data.
+ *
+ * Extract supported information from icalcomponent and return them through
+ * ecalcomp and tzcomp.
+ *
+ * Returns: if the given component type could be extracted successfully into ecalcomp + tzcomp;
+ */
+ECalBackendSyncStatus
+kolab_util_calendar_extract (icalcomponent *icalcomp,
+                             ECalSourceType source_type,
+                             ECalComponent **ecalcomp,
+                             ECalComponent **tzcomp)
 {
-	/* TODO: Add deinitalization code here */
+	ECalComponent *comp = NULL;
+	ECalComponent *tz = NULL;
+	icalcomponent *icalsub = NULL;
+	icalcomponent *icaltz = NULL;
+	icalcomponent_kind icalkind;
 
-	G_OBJECT_CLASS (kolab_util_calendar_parent_class)->finalize (object);
-}
+	switch (source_type) {
+	case E_CAL_SOURCE_TYPE_EVENT:
+		icalkind = ICAL_VEVENT_COMPONENT;
+		break;
+	case E_CAL_SOURCE_TYPE_TODO:
+		icalkind = ICAL_VTODO_COMPONENT;
+		break;
+	case E_CAL_SOURCE_TYPE_JOURNAL:
+		icalkind = ICAL_VJOURNAL_COMPONENT;
+		break;
+	default:
+		g_error ("%s()[%u] Got an unknown value for ECalSourceType, this should not happen.",
+		         __func__, __LINE__);
+	}
 
-static void
-kolab_util_calendar_class_init (KolabUtilCalendarClass *klass)
-{
-	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	icalsub = icalcomponent_get_first_component (icalcomp,
+	                                             icalkind);
+	if (icalsub == NULL) {
+		return GNOME_Evolution_Calendar_InvalidObject;
+	}
 
-	g_type_class_add_private (klass, sizeof (KolabUtilCalendarPrivate));
+	comp = e_cal_component_new ();
+	e_cal_component_set_icalcomponent (comp, icalsub);
+	*ecalcomp = e_cal_component_clone (comp);
+	g_object_unref (comp);
 
-	object_class->finalize = kolab_util_calendar_finalize;
-}
+	icaltz = icalcomponent_get_first_component (icalcomp,
+	                                            ICAL_VTIMEZONE_COMPONENT);
+	if (icaltz == NULL) {
+		/* no TZ - no problem */
+		tzcomp = NULL;
+	}
+	else {
+		/* Create a new ECalComponent from the
+		 * ical timezone component.
+		 */
+		tz = e_cal_component_new ();
+		e_cal_component_set_icalcomponent (tz,
+		                                   icaltz);
+		*tzcomp = e_cal_component_clone (tz);
+		g_object_unref (tz);
+	}
 
+	return GNOME_Evolution_Calendar_Success;
+} /* kolab_util_calendar_extract () */
+#endif
diff --git a/src/calendar/kolab-util-calendar.h b/src/calendar/kolab-util-calendar.h
index d98d035..cc3e615 100644
--- a/src/calendar/kolab-util-calendar.h
+++ b/src/calendar/kolab-util-calendar.h
@@ -1,8 +1,13 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
-/*
- * evolution-kolab
- * Copyright (C) Silvan Marco Fin 2011 <silvan kernelconcepts de>
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/***************************************************************************
+ *            kolab-util-calendar.c
  *
+ *  2011
+ *  Copyright  2011  Silvan Marco Fin
+ *  <silvan kernelconcepts de>
+ ****************************************************************************/
+
+/*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -18,21 +23,24 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
  */
 
+/*----------------------------------------------------------------------------*/
+
 #ifndef _KOLAB_UTIL_CALENDAR_H_
 #define _KOLAB_UTIL_CALENDAR_H_
 
-#include <libekolabutil/kolab-http-job.h>
-#include <libekolab/kolab-settings-handler.h>
-#include <libekolab/kolab-mail-access.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
 
 #include <libical/icalcomponent.h>
 #include <libecal/e-cal.h>
 #include <libedata-cal/e-cal-backend-sync.h>
 
-#include <glib.h>
-#include <glib-object.h>
+#include <libekolabutil/kolab-http-job.h>
+#include <libekolab/kolab-settings-handler.h>
+#include <libekolab/kolab-mail-access.h>
 
-G_BEGIN_DECLS
+/*----------------------------------------------------------------------------*/
 
 /**
  * SECTION:kolab-util-calendar
@@ -42,46 +50,43 @@ G_BEGIN_DECLS
  * The methods in this library don't use the ECalBackendCache.
  */
 
-#define KOLAB_TYPE_UTIL_CALENDAR             (kolab_util_calendar_get_type ())
-#define KOLAB_UTIL_CALENDAR(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), KOLAB_TYPE_UTIL_CALENDAR, ECalBackendKolabUtil))
-#define KOLAB_UTIL_CALENDAR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), KOLAB_TYPE_UTIL_CALENDAR, ECalBackendKolabUtilClass))
-#define KOLAB_IS_UTIL_CALENDAR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KOLAB_TYPE_UTIL_CALENDAR))
-#define KOLAB_IS_UTIL_CALENDAR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), KOLAB_TYPE_UTIL_CALENDAR))
-#define KOLAB_UTIL_CALENDAR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), KOLAB_TYPE_UTIL_CALENDAR, ECalBackendKolabUtilClass))
-
-typedef struct _KolabUtilCalendarClass KolabUtilCalendarClass;
-typedef struct _KolabUtilCalendar KolabUtilCalendar;
-
-
-struct _KolabUtilCalendarClass
-{
-	GObjectClass parent_class;
-};
-
-struct _KolabUtilCalendar
-{
-	GObject parent_instance;
-};
-
-GType kolab_util_calendar_get_type (void) G_GNUC_CONST;
+/*----------------------------------------------------------------------------*/
+
+gchar*
+kolab_util_calendar_get_tzid (ECalComponent *comp,
+                              ECalComponentField from);
+
+gboolean
+kolab_util_calendar_toggle_pfb_trigger (KolabSettingsHandler *ksettings,
+                                        const gchar *sourcename,
+                                        GError **error);
+
+KolabHttpJob*
+kolab_util_calendar_retrieve_xfb (KolabSettingsHandler *ksettings,
+                                  gchar *query,
+                                  GError **error);
+
+gboolean
+kolab_util_calendar_store (ECalComponent *ecalcomp,
+                           ECalComponent *ecaltz,
+                           ECalComponent *default_tz,
+                           KolabMailAccess *koma,
+                           const gchar *uri,
+                           GCancellable *cancellable,
+                           GError **error);
+
+#if 0 /* FIXME old */
+ECalBackendSyncStatus
+kolab_util_calendar_extract (icalcomponent *icalcomp,
+                             ECalSourceType source_type,
+                             ECalComponent **ecalcomp,
+                             ECalComponent **tzcomp);
 
-/* library functions */
-
-#if 0
-ECalBackendSyncStatus kolab_util_calendar_extract (icalcomponent *icalcomp, ECalSourceType source_type, ECalComponent **ecalcomp, ECalComponent **tzcomp);
-#endif
-
-gchar *kolab_util_calendar_get_tzid (ECalComponent *comp, ECalComponentField from);
-gboolean kolab_util_calendar_toggle_pfb_trigger (KolabSettingsHandler *ksettings, const gchar *sourcename);
-KolabHttpJob *kolab_util_calendar_retrieve_xfb (KolabSettingsHandler *ksettings, gchar *query);
-void kolab_util_calendar_store (ECalComponent *ecalcomp, ECalComponent *ecaltz, ECalComponent *default_tz, KolabMailAccess *koma, const gchar *uri, GError **error);
-
-#if 0
 ECalBackendSyncStatus kolab_util_calendar_map_error (GError *error);
 #endif
 
-/* object methods */
-
-G_END_DECLS
+/*----------------------------------------------------------------------------*/
 
 #endif /* _KOLAB_UTIL_CALENDAR_H_ */
+
+/*----------------------------------------------------------------------------*/



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