[evolution-ews] Bug #657320 - Cannot Modify a Contact
- From: Vibha Yadav <yvibha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Bug #657320 - Cannot Modify a Contact
- Date: Tue, 6 Sep 2011 14:30:53 +0000 (UTC)
commit 305f065adb0da7c396346a4a64297ee88caab6da
Author: Vibha Yadav <yvibha novell com>
Date: Tue Sep 6 19:57:03 2011 +0530
Bug #657320 - Cannot Modify a Contact
Added Code for Modifying a contact for EWS connector.
This patch addresses sending request for both Normal Fields as well as
IndexedField. Also added code DeleteItemField as part of IndexedField
request.
src/addressbook/e-book-backend-ews.c | 237 ++++++++++++++++++++++++++++++++--
src/server/e-ews-item-change.c | 30 +++++
src/server/e-ews-item-change.h | 4 +
3 files changed, 260 insertions(+), 11 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 0540ce3..66e9aea 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -47,6 +47,7 @@
#include "e-book-backend-ews.h"
#include "e-book-backend-sqlitedb.h"
#include "e-book-backend-ews-utils.h"
+#include "e-ews-item-change.h"
#include "e-ews-message.h"
#include "e-ews-connection.h"
@@ -381,8 +382,50 @@ ebews_set_emails (ESoapMessage *msg, EContact *contact)
}
static void
+convert_contact_property_to_updatexml (ESoapMessage *msg, const gchar *name, const gchar *value, const gchar * prefix, const gchar *attr_name, const gchar *attr_value)
+{
+ e_ews_message_start_set_item_field (msg, name, prefix, "Contact");
+ e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
+ e_ews_message_end_set_item_field (msg);
+}
+
+static void
+convert_indexed_contact_property_to_updatexml (ESoapMessage *message, const gchar *name, const gchar *value, const gchar * prefix, const gchar *element_name, const gchar *key)
+{
+ gboolean delete_field = FALSE;
+
+ if(!value)
+ delete_field = TRUE;
+ e_ews_message_start_set_indexed_item_field (message, name , prefix, "Contact", key, delete_field);
+
+ if(!delete_field)
+ {
+ e_soap_message_start_element(message, element_name, NULL, NULL);
+ e_ews_message_write_string_parameter_with_attribute(message, "Entry", NULL, value, "Key", key);
+ e_soap_message_end_element(message);
+ }
+ e_ews_message_end_set_indexed_item_field (message, delete_field);
+}
+
+
+static void
ebews_set_full_name_changes (ESoapMessage *message, EContact *new, EContact *old)
{
+ EContactName *name, *old_name;
+
+ name = e_contact_get (new, E_CONTACT_NAME);
+ old_name = e_contact_get (old, E_CONTACT_NAME);
+ if (!name && !old_name)
+ return;
+
+ if (g_ascii_strcasecmp(name->given, old_name->given))
+ convert_contact_property_to_updatexml(message, "GivenName", name->given, "contacts", NULL, NULL);
+
+ if (g_ascii_strcasecmp(name->additional, old_name->additional))
+ convert_contact_property_to_updatexml(message, "MiddleName", name->additional, "contacts", NULL, NULL);
+
+ e_contact_name_free (name);
+ e_contact_name_free (old_name);
}
@@ -395,7 +438,20 @@ ebews_set_birth_date_changes (ESoapMessage *message, EContact *new, EContact *ol
static void
ebews_set_phone_number_changes (ESoapMessage *message, EContact *new, EContact *old)
{
-
+ gint i;
+ gchar *new_value, *old_value;
+
+ for (i = 0; i < G_N_ELEMENTS (phone_field_map); i++) {
+ new_value = e_contact_get (new, phone_field_map[i].field);
+ old_value = e_contact_get (old, phone_field_map[i].field);
+ if((new_value && !old_value) || (!new_value && old_value) ||(new_value && old_value && g_ascii_strcasecmp(new_value, old_value)))
+ convert_indexed_contact_property_to_updatexml (message, "PhoneNumber", new_value, "contacts", "PhoneNumbers", phone_field_map[i].element);
+ if(new_value)
+ g_free(new_value);
+
+ if(old_value)
+ g_free(old_value);
+ }
}
static void
@@ -413,7 +469,34 @@ ebews_set_im_changes (ESoapMessage *message, EContact *new, EContact *old)
static void
ebews_set_email_changes (ESoapMessage *message, EContact *new, EContact *old)
{
-
+ gchar *new_value, *old_value;
+
+ new_value = e_contact_get (new, E_CONTACT_EMAIL_1);
+ old_value = e_contact_get (old, E_CONTACT_EMAIL_1);
+ if((new_value && !old_value) || (!new_value && old_value) ||(new_value && old_value && g_ascii_strcasecmp(new_value, old_value)))
+ convert_indexed_contact_property_to_updatexml (message, "EmailAddress", new_value, "contacts", "EmailAddresses", "EmailAddress1");
+ if(new_value)
+ g_free(new_value);
+ if (old_value)
+ g_free(old_value);
+
+ new_value = e_contact_get (new, E_CONTACT_EMAIL_2);
+ old_value = e_contact_get (old, E_CONTACT_EMAIL_2);
+ if((new_value && !old_value) || (!new_value && old_value) ||(new_value && old_value && g_ascii_strcasecmp(new_value, old_value)))
+ convert_indexed_contact_property_to_updatexml (message, "EmailAddress", new_value, "contacts", "EmailAddresses", "EmailAddress2");
+ if(new_value)
+ g_free(new_value);
+ if (old_value)
+ g_free(old_value);
+
+ new_value = e_contact_get (new, E_CONTACT_EMAIL_3);
+ old_value = e_contact_get (old, E_CONTACT_EMAIL_3);
+ if((new_value && !old_value) || (!new_value && old_value) ||(new_value && old_value && g_ascii_strcasecmp(new_value, old_value)))
+ convert_indexed_contact_property_to_updatexml (message, "EmailAddress", new_value, "contacts", "EmailAddresses", "EmailAddress3");
+ if(new_value)
+ g_free(new_value);
+ if (old_value)
+ g_free(old_value);
}
static const struct field_element_mapping {
@@ -692,6 +775,107 @@ e_book_backend_ews_remove_contacts (EBookBackend *backend,
}
}
+typedef struct {
+ EBookBackendEws *ebews;
+ EDataBook *book;
+ EContact *new_contact;
+ EContact *old_contact;
+ guint32 opid;
+} EwsModifyContact;
+
+static void
+ews_modify_contact_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ EEwsConnection *cnc = E_EWS_CONNECTION (object);
+ EwsModifyContact *modify_contact = user_data;
+ EBookBackendEws *ebews = modify_contact->ebews;
+ EBookBackendEwsPrivate *priv = ebews->priv;
+ GError *error = NULL;
+ GSList *items = NULL;
+ gchar *id;
+ const EwsId *item_id;
+
+ g_object_ref (modify_contact->new_contact);
+ g_object_ref (modify_contact->old_contact);
+
+
+ e_ews_connection_update_items_finish(cnc, res, &items, &error);
+
+ if (error == NULL) {
+ EEwsItem *item = (EEwsItem *) items->data;
+
+ /* set item id */
+ item_id = e_ews_item_get_id((EEwsItem *)items->data);
+
+ e_contact_set (modify_contact->new_contact, E_CONTACT_UID, item_id->id);
+ e_contact_set (modify_contact->new_contact, E_CONTACT_REV, item_id->change_key);
+
+ id = e_contact_get (modify_contact->old_contact, E_CONTACT_UID);
+
+ e_book_backend_sqlitedb_remove_contact (priv->ebsdb, priv->folder_id, id, &error);
+ e_book_backend_sqlitedb_add_contact (ebews->priv->ebsdb, ebews->priv->folder_id, modify_contact->new_contact, FALSE, &error);
+
+ if (error == NULL)
+ e_data_book_respond_modify (modify_contact->book, modify_contact->opid, EDB_ERROR (SUCCESS), modify_contact->new_contact);
+
+ g_object_unref (item);
+ g_slist_free (items);
+ }
+
+ if (error) {
+ g_warning("Error while Creating contact: %s", error->message);
+ e_data_book_respond_modify (modify_contact->book, modify_contact->opid, EDB_ERROR_EX (OTHER_ERROR, error->message), modify_contact->new_contact);
+ }
+
+ /* free memory allocated for create_contact & unref contained objects */
+ g_object_unref(modify_contact->ebews);
+ g_object_unref(modify_contact->new_contact);
+ g_object_unref(modify_contact->old_contact);
+ g_free(modify_contact);
+ g_clear_error (&error);
+}
+
+static void
+convert_contact_to_updatexml (ESoapMessage *msg, gpointer user_data)
+{
+ EwsModifyContact *modify_contact = user_data;
+ EwsId *id;
+ EContact *old_contact = modify_contact->old_contact;
+ EContact *new_contact = modify_contact->new_contact;
+ gchar *value = NULL, *old_value = NULL ;
+ gint i, element_type;
+
+ id = g_new0 (EwsId, 1);
+ id->id = e_contact_get (old_contact, E_CONTACT_UID);
+ id->change_key = e_contact_get (old_contact, E_CONTACT_REV);
+
+ e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+ id->id, id->change_key, 0);
+
+ /*Iterate for each field in contact*/
+
+ for (i = 0; i < G_N_ELEMENTS (mappings); i++) {
+ element_type = mappings[i].element_type;
+ if (element_type == ELEMENT_TYPE_SIMPLE) {
+ value = e_contact_get (new_contact, mappings[i].field_id);
+ old_value = e_contact_get (old_contact, mappings[i].field_id);
+ if (value)
+ {
+ if(( *value && !old_value) || g_ascii_strcasecmp (value, old_value))
+ convert_contact_property_to_updatexml(msg, mappings[i].element_name, value, "contacts", NULL, NULL);
+ g_free(value);
+ }
+ if(old_value)
+ g_free(old_value);
+ } else if (element_type == ELEMENT_TYPE_COMPLEX) {
+ if(mappings [i].field_id == E_CONTACT_UID)
+ continue;
+ mappings[i].set_changes (msg, new_contact, old_contact);
+ }
+ }
+
+ e_ews_message_end_item_change (msg);
+}
static void
e_book_backend_ews_modify_contact (EBookBackend *backend,
@@ -699,39 +883,70 @@ e_book_backend_ews_modify_contact (EBookBackend *backend,
guint32 opid,
const gchar *vcard)
{
- EContact *contact = NULL;
- EBookBackendEws *egwb;
+ EContact *contact = NULL, *old_contact;
+ EwsModifyContact *modify_contact;
+ EBookBackendEws *ebews;
+ EwsId *id;
+ EBookBackendEwsPrivate *priv;
+ GCancellable *cancellable = NULL;
+ GError *error;
- egwb = E_BOOK_BACKEND_EWS (backend);
- switch (egwb->priv->mode) {
+ ebews = E_BOOK_BACKEND_EWS (backend);
+ priv = ebews->priv;
+
+ switch (priv->mode) {
case E_DATA_BOOK_MODE_LOCAL :
e_data_book_respond_modify (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
return;
case E_DATA_BOOK_MODE_REMOTE :
- if (egwb->priv->cnc == NULL) {
+ if (priv->cnc == NULL) {
e_data_book_respond_modify (book, opid, EDB_ERROR (AUTHENTICATION_REQUIRED), NULL);
return;
}
- if (!egwb->priv->is_writable) {
+ if (!priv->is_writable) {
e_data_book_respond_modify (book, opid, EDB_ERROR (PERMISSION_DENIED), NULL);
return;
}
contact = e_contact_new_from_vcard (vcard);
+ id = g_new0 (EwsId, 1);
+ id->id = e_contact_get (contact, E_CONTACT_UID);
+ id->change_key = e_contact_get (contact, E_CONTACT_REV);
+
+ /*get item id and change key from contact and fetch old contact and assign.*/
+
if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
g_object_unref (contact);
- e_data_book_respond_create (book, opid, EDB_ERROR (NOT_SUPPORTED), NULL);
+ e_data_book_respond_modify (book, opid, EDB_ERROR (NOT_SUPPORTED), NULL);
+ return;
+ }
+
+ old_contact = e_book_backend_sqlitedb_get_contact ( priv->ebsdb, priv->folder_id,
+ id->id, &error);
+ if (!old_contact) {
+ g_object_unref (contact);
+ e_data_book_respond_modify (book, opid, EDB_ERROR (NOT_SUPPORTED), NULL);
return;
}
/* TODO implement */
- g_object_unref (contact);
- e_data_book_respond_create (book, opid, EDB_ERROR (NOT_SUPPORTED), NULL);
+ modify_contact = g_new0 (EwsModifyContact, 1);
+ modify_contact->ebews = g_object_ref(ebews);
+ modify_contact->book = g_object_ref(book);
+ modify_contact->opid = opid;
+ modify_contact->old_contact = g_object_ref(old_contact);
+ modify_contact->new_contact = g_object_ref(contact);
+ e_ews_connection_update_items_start (priv->cnc, EWS_PRIORITY_MEDIUM,
+ "AlwaysOverwrite", "SendAndSaveCopy",
+ "SendToAllAndSaveCopy", priv->folder_id,
+ convert_contact_to_updatexml, modify_contact,
+ ews_modify_contact_cb, cancellable,
+ modify_contact);
return;
default :
break;
diff --git a/src/server/e-ews-item-change.c b/src/server/e-ews-item-change.c
index 9b2b94f..ee9aecf 100644
--- a/src/server/e-ews-item-change.c
+++ b/src/server/e-ews-item-change.c
@@ -97,6 +97,36 @@ e_ews_message_start_set_item_field (ESoapMessage *msg, const gchar *name, const
}
void
+e_ews_message_start_set_indexed_item_field (ESoapMessage *msg, const gchar *name, const gchar * fielduri_prefix, const char *field_kind, const char *field_index, gboolean delete_field)
+{
+ gchar * fielduri = NULL;
+ fielduri = g_strconcat (fielduri_prefix, ":", name, NULL);
+
+ if(delete_field)
+ e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
+ else
+ e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
+
+ e_soap_message_start_element (msg, "IndexedFieldURI", NULL, NULL);
+ e_soap_message_add_attribute (msg, "FieldURI", fielduri, NULL, NULL);
+ e_soap_message_add_attribute (msg, "FieldIndex", field_index, NULL, NULL);
+ e_soap_message_end_element (msg);
+
+ if(!delete_field)
+ e_soap_message_start_element (msg, field_kind, NULL, NULL);
+
+ g_free (fielduri);
+}
+
+void
+e_ews_message_end_set_indexed_item_field (ESoapMessage *msg, gboolean delete_field)
+{
+ if(!delete_field)
+ e_soap_message_end_element (msg); /* CalendarItem */
+ e_soap_message_end_element (msg); /* SetItemField */
+}
+
+void
e_ews_message_end_set_item_field (ESoapMessage *msg)
{
e_soap_message_end_element (msg); /* CalendarItem */
diff --git a/src/server/e-ews-item-change.h b/src/server/e-ews-item-change.h
index 527467c..780cda8 100644
--- a/src/server/e-ews-item-change.h
+++ b/src/server/e-ews-item-change.h
@@ -41,6 +41,10 @@ void e_ews_message_end_item_change (ESoapMessage *msg);
void e_ews_message_start_set_item_field (ESoapMessage *msg, const gchar *name, const gchar * fielduri_prefix, const char *field_kind);
+void e_ews_message_start_set_indexed_item_field (ESoapMessage *msg, const gchar *name, const gchar * fielduri_prefix, const char *field_kind, const char *field_index, gboolean delete_field);
+
+void e_ews_message_end_set_indexed_item_field (ESoapMessage *msg, gboolean delete_field);
+
void e_ews_message_end_set_item_field (ESoapMessage *msg);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]