From df732aa0a454e07d85351c0205db677563d73b10 Mon Sep 17 00:00:00 2001 From: Srinivasa Ragavan Date: Wed, 8 Jun 2005 05:49:06 +0000 Subject: [PATCH] Added function to retrive deltainfo and delta Added a variable sync to 2005-06-08 Srinivasa Ragavan * e-gw-connection.[ch] :Added function to retrive deltainfo and delta * e-gw-item.[ch] : Added a variable sync to EGwItem to know the type of change to the item while reading the deltas --- addressbook/ChangeLog | 6 + .../backends/groupwise/e-book-backend-groupwise.c | 129 ++++++++++++++++- servers/groupwise/ChangeLog | 6 + servers/groupwise/e-gw-connection.c | 154 ++++++++++++++++++++- servers/groupwise/e-gw-connection.h | 3 + servers/groupwise/e-gw-item.c | 19 +++ servers/groupwise/e-gw-item.h | 1 + 7 files changed, 316 insertions(+), 2 deletions(-) diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 391b08f..e84dd79 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,9 @@ +2005-06-08 Srinivasa Ragavan + + * e-gw-connection.[ch] :Added function to retrive deltainfo and delta + * e-gw-item.[ch] : Added a variable sync to EGwItem to know the type + of change to the item while reading the deltas + 2005-05-24 Chenthill Palanisamy Commiting for Daniel van Eeden diff --git a/addressbook/backends/groupwise/e-book-backend-groupwise.c b/addressbook/backends/groupwise/e-book-backend-groupwise.c index a2ea630..ea72b9e 100644 --- a/addressbook/backends/groupwise/e-book-backend-groupwise.c +++ b/addressbook/backends/groupwise/e-book-backend-groupwise.c @@ -2181,9 +2181,9 @@ build_cache (EBookBackendGroupwise *ebgw) int cursor; gboolean done = FALSE; EBookBackendGroupwisePrivate *priv = ebgw->priv; + EBookBackendCache *cache = priv->cache; const char *position = E_GW_CURSOR_POSITION_START; - status = e_gw_connection_create_cursor (priv->cnc, priv->container_id, "name email default members", NULL, &cursor); if (status != E_GW_CONNECTION_STATUS_OK) return FALSE; @@ -2209,6 +2209,37 @@ build_cache (EBookBackendGroupwise *ebgw) gw_items = NULL; position = E_GW_CURSOR_POSITION_CURRENT; } + + if (!priv->is_writable) { + /* This could be the system address book. Let try add the sequence to maintain deltas */ + guint first_sequence = -1, last_sequence = -1, last_po_rebuild_time = -1; + gchar *tmp; + status = e_gw_connection_get_items_delta_info (priv->cnc, priv->container_id, &first_sequence, + &last_sequence, &last_po_rebuild_time); + if (status != E_GW_CONNECTION_STATUS_OK) + return FALSE; + + tmp = g_strdup_printf("%d", first_sequence); + if (!e_file_cache_get_object (E_FILE_CACHE(cache), "firstSequence")) + e_file_cache_add_object (E_FILE_CACHE(cache), "firstSequence", tmp); + else + e_file_cache_replace_object (E_FILE_CACHE(cache), "firstSequence", tmp); + g_free (tmp); + + tmp = g_strdup_printf("%d", last_sequence); + if (!e_file_cache_get_object (E_FILE_CACHE(cache), "lastSequence")) + e_file_cache_add_object (E_FILE_CACHE(cache), "lastSequence", tmp); + else + e_file_cache_replace_object (E_FILE_CACHE(cache), "lastSequence", tmp); + g_free (tmp); + + tmp = g_strdup_printf("%d", last_po_rebuild_time); + if (!e_file_cache_get_object (E_FILE_CACHE(cache), "lastTimePORebuild")) + e_file_cache_add_object (E_FILE_CACHE(cache), "lastTimePORebuild", tmp); + else + e_file_cache_replace_object (E_FILE_CACHE(cache), "lastTimePORebuild", tmp); + g_free (tmp); + } e_gw_connection_destroy_cursor (priv->cnc, priv->container_id, cursor); return NULL; @@ -2257,6 +2288,7 @@ update_cache (EBookBackendGroupwise *ebgw) } + ebgw->priv->is_cache_ready = TRUE; g_object_unref (filter); g_list_free (gw_items); @@ -2264,6 +2296,99 @@ update_cache (EBookBackendGroupwise *ebgw) } +static gboolean +update_address_book_deltas(EBookBackendGroupwise *ebgw) +{ + int status; + guint first_sequence = -1, last_sequence = -1, last_po_rebuild_time = -1; + guint cache_last_sequence = -1, cache_last_po_rebuild_time = -1; + char *tmp; + char *count, *sequence; + GList *add_list = NULL, *delete_list = NULL; + EContact *contact; + + EBookBackendGroupwisePrivate *priv = ebgw->priv; + EBookBackendCache *cache = priv->cache; + + status = e_gw_connection_get_items_delta_info (priv->cnc, ebgw->priv->container_id, &first_sequence, + &last_sequence, &last_po_rebuild_time); + if (status != E_GW_CONNECTION_STATUS_OK) + return FALSE; + + /* Check whether the sequence has been reset or not */ + if (first_sequence <= 0 || last_sequence <= 0) + build_cache (ebgw); /* Rebuild the entire cache */ + + tmp = e_file_cache_get_object (E_FILE_CACHE (cache), "lastSequence"); + if (tmp) + cache_last_sequence = atoi (tmp); + + tmp = e_file_cache_get_object (E_FILE_CACHE (cache), "lastTimePORebuild"); + if (tmp) + cache_last_po_rebuild_time = atoi (tmp); + + /* check whether the all the sequences are available and also whether the PO is rebuilt */ + if (first_sequence > cache_last_sequence || cache_last_sequence == -1 || last_po_rebuild_time != cache_last_po_rebuild_time) + build_cache (ebgw); + + sequence = g_strdup_printf ("%d", cache_last_sequence +1); + count = g_strdup_printf ("%d", CURSOR_ITEM_LIMIT); + e_gw_connection_get_items_delta (priv->cnc, ebgw->priv->container_id, "name email sync", count, sequence, &add_list, &delete_list); + + for (; add_list != NULL; add_list = g_list_next(add_list)) { + const char *id; + contact = e_contact_new (); + fill_contact_from_gw_item (contact, E_GW_ITEM (add_list->data), ebgw->priv->categories_by_id); + id = e_contact_get_const (contact, E_CONTACT_UID); + if (e_book_backend_cache_check_contact (ebgw->priv->cache, id)) { + e_book_backend_cache_remove_contact (ebgw->priv->cache, id); + e_book_backend_cache_add_contact (ebgw->priv->cache, contact); + + } else + e_book_backend_cache_add_contact (ebgw->priv->cache, contact); + + g_object_unref(contact); + g_object_unref (add_list->data); + + + } + + for (; delete_list != NULL; delete_list = g_list_next(delete_list)) { + const char *id; + contact = e_contact_new (); + fill_contact_from_gw_item (contact, E_GW_ITEM (delete_list->data), ebgw->priv->categories_by_id); + id = e_contact_get_const (contact, E_CONTACT_UID); + if (e_book_backend_cache_check_contact (ebgw->priv->cache, id)) { + e_book_backend_cache_remove_contact (ebgw->priv->cache, id); + + } + + g_object_unref(contact); + g_object_unref (delete_list->data); + + + } + + /* We can safely assume these are there cache, otherwise it couldnt have come here*/ + tmp = g_strdup_printf("%d", first_sequence); + e_file_cache_replace_object (E_FILE_CACHE(cache), "firstSequence", tmp); + g_free (tmp); + + tmp = g_strdup_printf("%d", last_sequence); + e_file_cache_replace_object (E_FILE_CACHE(cache), "lastSequence", tmp); + g_free (tmp); + + tmp = g_strdup_printf("%d", last_po_rebuild_time); + e_file_cache_replace_object (E_FILE_CACHE(cache), "lastTimePORebuild", tmp); + g_free (tmp); + + ebgw->priv->is_cache_ready = TRUE; + g_list_free (add_list); + g_list_free (delete_list); + + return FALSE; +} + static void e_book_backend_groupwise_authenticate_user (EBookBackend *backend, @@ -2349,6 +2474,8 @@ e_book_backend_groupwise_authenticate_user (EBookBackend *backend, if (e_book_backend_cache_is_populated (priv->cache)) { if (priv->is_writable) g_thread_create ((GThreadFunc) update_cache, ebgw, FALSE, NULL); + else + g_thread_create ((GThreadFunc) update_address_book_deltas, ebgw, FALSE, NULL); } else if (priv->is_writable || priv->marked_for_offline){ /* for personal books we always cache*/ g_thread_create ((GThreadFunc) build_cache, ebgw, FALSE, NULL); diff --git a/servers/groupwise/ChangeLog b/servers/groupwise/ChangeLog index 3801fb0..50adce3 100644 --- a/servers/groupwise/ChangeLog +++ b/servers/groupwise/ChangeLog @@ -1,3 +1,9 @@ +2005-06-08 Srinivasa Ragavan + + * e-gw-connection.[ch] :Added function to retrive deltainfo and delta + * e-gw-item.[ch] : Added a variable sync to EGwItem to know the type + of change to the item while reading the deltas + 2005-06-06 Chenthill Palanisamy * e-gw-connection.[ch] (e_gw_connection_delegate_request): Added a function for sending a delegate request. diff --git a/servers/groupwise/e-gw-connection.c b/servers/groupwise/e-gw-connection.c index 3be0d27..8324710 100644 --- a/servers/groupwise/e-gw-connection.c +++ b/servers/groupwise/e-gw-connection.c @@ -668,6 +668,158 @@ e_gw_connection_get_container_id (EGwConnection *cnc, const char *name) return container_id; } +EGwConnectionStatus +e_gw_connection_get_items_delta_info (EGwConnection *cnc, const char *container, guint *first_sequence, + guint *last_sequence, guint *last_po_rebuild_time ) +{ + SoupSoapMessage *msg; + SoupSoapResponse *response; + EGwConnectionStatus status; + SoupSoapParameter *param, *subparam; + + g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT); + + /* build the SOAP message */ + msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getDeltaInfoRequest"); + if (!msg) { + g_warning (G_STRLOC ": Could not build SOAP message"); + return E_GW_CONNECTION_STATUS_UNKNOWN; + } + + e_gw_message_write_string_parameter (msg, "container", NULL, container); + + e_gw_message_write_footer (msg); + + /* send message to server */ + response = e_gw_connection_send_message (cnc, msg); + if (!response) { + g_object_unref (msg); + return E_GW_CONNECTION_STATUS_NO_RESPONSE; + } + + status = e_gw_connection_parse_response_status (response); + if (status != E_GW_CONNECTION_STATUS_OK) { + if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION) + reauthenticate (cnc); + g_object_unref (response); + g_object_unref (msg); + return status; + } + + param = soup_soap_response_get_first_parameter_by_name (response, "deltaInfo"); + if (!param) { + g_object_unref (response); + g_object_unref (msg); + return E_GW_CONNECTION_STATUS_INVALID_RESPONSE; + } + + /* parse these parameters */ + + subparam = soup_soap_parameter_get_first_child_by_name (param, "firstSequence"); + + if (subparam) + *first_sequence = soup_soap_parameter_get_int_value(subparam); + else + *first_sequence = -1; + + subparam = soup_soap_parameter_get_first_child_by_name (param, "lastSequence"); + + if (subparam) + *last_sequence = soup_soap_parameter_get_int_value(subparam); + else + *last_sequence = -1; + + subparam = soup_soap_parameter_get_first_child_by_name (param, "lastTimePORebuild"); + + if (subparam) + *last_po_rebuild_time = soup_soap_parameter_get_int_value(subparam); + else + *last_po_rebuild_time = -1; + + g_object_unref (response); + g_object_unref (msg); + + return status; +} + +EGwConnectionStatus +e_gw_connection_get_items_delta (EGwConnection *cnc, const char *container, const char *view, const char *count, const char * start_sequence, GList **add_list, GList **delete_list) +{ + SoupSoapMessage *msg; + SoupSoapResponse *response; + EGwConnectionStatus status; + SoupSoapParameter *param, *subparam; + EGwItemChangeType sync = E_GW_ITEM_CHNAGE_TYPE_UNKNOWN; + + g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT); + + /* build the SOAP message */ + msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getDeltasRequest"); + if (!msg) { + g_warning (G_STRLOC ": Could not build SOAP message"); + return E_GW_CONNECTION_STATUS_UNKNOWN; + } + + e_gw_message_write_string_parameter (msg, "container", NULL, container); + if (view) + e_gw_message_write_string_parameter (msg, "view", NULL, view); + + soup_soap_message_start_element (msg, "deltaInfo", NULL, NULL); + e_gw_message_write_string_parameter (msg, "firstSequence", NULL, start_sequence); + e_gw_message_write_string_parameter (msg, "count", NULL, count); + soup_soap_message_end_element(msg); + + /* send message to server */ + + e_gw_message_write_footer (msg); + response = e_gw_connection_send_message (cnc, msg); + if (!response) { + g_object_unref (msg); + return E_GW_CONNECTION_STATUS_NO_RESPONSE; + } + + status = e_gw_connection_parse_response_status (response); + if (status != E_GW_CONNECTION_STATUS_OK) { + if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION) + reauthenticate (cnc); + g_object_unref (response); + g_object_unref (msg); + return status; + } + + /* if status is OK - parse result. return the list */ + param = soup_soap_response_get_first_parameter_by_name (response, "items"); + if (!param) { + g_object_unref (response); + g_object_unref (msg); + return E_GW_CONNECTION_STATUS_INVALID_RESPONSE; + } + + /* parse these parameters */ + for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item"); + subparam != NULL; + subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) { + EGwItem *item; + + item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, container, subparam); + if (item) + sync = e_gw_item_get_sync_type (item); + + if (sync == E_GW_ITEM_CHANGE_TYPE_ADD || sync == E_GW_ITEM_CHANGE_TYPE_UPDATE) + *add_list = g_list_append (*add_list, item); + else if (sync == E_GW_ITEM_CHANGE_TYPE_DELETE) + *delete_list = g_list_append (*delete_list, item); + } + + /* free memory */ + g_object_unref (response); + g_object_unref (msg); + + return E_GW_CONNECTION_STATUS_OK; + +} + + EGwConnectionStatus e_gw_connection_get_items (EGwConnection *cnc, const char *container, const char *view, EGwFilter *filter, GList **list) { @@ -688,7 +840,7 @@ e_gw_connection_get_items (EGwConnection *cnc, const char *container, const char e_gw_message_write_string_parameter (msg, "container", NULL, container); if (view) e_gw_message_write_string_parameter (msg, "view", NULL, view); - + if (filter) e_gw_filter_append_to_soap_message (filter, msg); e_gw_message_write_footer (msg); diff --git a/servers/groupwise/e-gw-connection.h b/servers/groupwise/e-gw-connection.h index c67a843..7e0446f 100644 --- a/servers/groupwise/e-gw-connection.h +++ b/servers/groupwise/e-gw-connection.h @@ -88,6 +88,9 @@ EGwConnectionStatus e_gw_connection_get_deltas ( EGwConnection *cnc, GSList **ad EGwConnectionStatus e_gw_connection_send_item (EGwConnection *cnc, EGwItem *item, GSList **id_list); EGwConnectionStatus e_gw_connection_remove_item (EGwConnection *cnc, const char *container, const char *id); EGwConnectionStatus e_gw_connection_remove_items (EGwConnection *cnc, const char *container, GList *item_ids); +EGwConnectionStatus e_gw_connection_get_items_delta_info (EGwConnection *cnc, const char *container, guint *first_sequence, guint *last_sequence, guint *last_po_rebuild_time); +EGwConnectionStatus e_gw_connection_get_items_delta (EGwConnection *cnc, const char *container, const char *view, const char *count, const char * start_sequence, GList **add_list, GList **delete_list); + const char *e_gw_connection_get_uri (EGwConnection *cnc); const char *e_gw_connection_get_session_id (EGwConnection *cnc); diff --git a/servers/groupwise/e-gw-item.c b/servers/groupwise/e-gw-item.c index 89046fd..2aa4867 100644 --- a/servers/groupwise/e-gw-item.c +++ b/servers/groupwise/e-gw-item.c @@ -53,6 +53,7 @@ struct _EGwItemPrivate { char *task_priority; char *place; char *source ; + EGwItemChangeType sync; GSList *recipient_list; GSList *recurrence_dates; int trigger; /* alarm */ @@ -1039,6 +1040,18 @@ set_contact_fields_from_soap_parameter (EGwItem *item, SoupSoapParameter *param) } g_free (primary_email); } + + subparam = soup_soap_parameter_get_first_child_by_name(param, "sync"); + if (subparam) { + value = soup_soap_parameter_get_string_value (subparam); + if (!strcmp (value, "add")) { + item->priv->sync = E_GW_ITEM_CHANGE_TYPE_ADD; + } else if (!strcmp (value, "delete")) { + item->priv->sync = E_GW_ITEM_CHANGE_TYPE_DELETE; + } else if (!strcmp (value, "update")) { + item->priv->sync = E_GW_ITEM_CHANGE_TYPE_UPDATE; + } + } subparam = soup_soap_parameter_get_first_child_by_name(param, "imList"); if(subparam) { @@ -1522,6 +1535,12 @@ append_group_fields_to_soap_message (EGwItem *item, SoupSoapMessage *msg) } +EGwItemChangeType +e_gw_item_get_sync_type (EGwItem *item) +{ + return item->priv->sync; +} + EGwItem * e_gw_item_new_from_soap_parameter (const char *email, const char *container, SoupSoapParameter *param) { diff --git a/servers/groupwise/e-gw-item.h b/servers/groupwise/e-gw-item.h index 670a585..442aa75 100644 --- a/servers/groupwise/e-gw-item.h +++ b/servers/groupwise/e-gw-item.h @@ -219,6 +219,7 @@ void e_gw_item_set_expires (EGwItem *item, char *expires); char *e_gw_item_get_expires (EGwItem *item); void e_gw_item_set_delay_until (EGwItem *item, char *delay_until); char *e_gw_item_get_delay_until (EGwItem *item); +EGwItemChangeType e_gw_item_get_sync_type (EGwItem *item); #define E_GW_ITEM_CLASSIFICATION_PUBLIC "Public" -- 2.7.4