[evolution-patches] patch for groupwise address book backend



Hi, 
I am attaching patch for first version of the groupwise address book
backend.i have attached two diff files.
groupwise_addressbook_backend.diff contains the new files
e_book_backend_groupwise.h and e_book_backend_groupwise.c 

groupwise_common_classes.diff contains the changes i made to common
groupwise classes e-gw-* (present under
evolution-data-server/servers/groupwise in groupwise-addressbook-backend
branch of e-d-s) to implement apis required for address book backend.

Thanks,
Sivaiah
--- e-book-backend-groupwise.h.orig	2004-02-22 18:43:26.000000000 +0530
+++ e-book-backend-groupwise.h	2004-02-22 17:48:58.000000000 +0530
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ *   Sivaiah Nallagatla (snallagatla novell com)
+ *
+ * Copyright 2004, Novell, Inc.
+ */
+                                                                                                                          
+#ifndef __E_BOOK_BACKEND_GROUPWISE_H__
+#define __E_BOOK_BACKEND_GROUPWISE_H__
+                                                                                                                             
+#include <libedata-book/e-book-backend-sync.h>
+                                                                                                                             
+#define E_TYPE_BOOK_BACKEND_GROUPWISE        (e_book_backend_groupwise_get_type ())
+#define E_BOOK_BACKEND_GROUPWISE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_BACKEND_GROUPWISE, EBookBackendGroupwise))
+#define E_BOOK_BACKEND_GROUPWISE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_BOOK_BACKEND_GROUPWISE, EBookBackendGroupwiseClass))
+#define E_IS_BOOK_BACKEND_GROUPWISE(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK_BACKEND_GROUPWISE))
+#define E_IS_BOOK_BACKEND_GROUPWISE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_BACKEND_GROUPWISE))
+#define E_BOOK_BACKEND_GROUPWISE_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_BOOK_BACKEND_GROUPWISE, EBookBackenGroupwiseClass))                                                                                                                             
+typedef struct _EBookBackendGroupwisePrivate EBookBackendGroupwisePrivate;
+                                                                                                                             
+typedef struct {
+	EBookBackend         parent_object;
+	EBookBackendGroupwisePrivate *priv;
+} EBookBackendGroupwise;
+                                                                                                                             
+typedef struct {
+	EBookBackendClass parent_class;
+} EBookBackendGroupwiseClass;
+                                                                                                                             
+EBookBackend *e_book_backend_groupwise_new      (void);
+GType       e_book_backend_groupwise_get_type (void);
+                                                                                                                             
+#endif /* ! __E_BOOK_BACKEND_GROUPWISE_H__ */
+                                                                                                                             
+
+
--- e-book-backend-groupwise.c.orig	2004-02-22 18:43:33.000000000 +0530
+++ e-book-backend-groupwise.c	2004-02-22 18:42:40.000000000 +0530
@@ -0,0 +1,889 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ *   Sivaiah Nallagatla (snallagatla novell com)
+ *
+ * Copyright 2004, Novell, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+
+#include <libebook/e-contact.h>
+                                                                                                                             
+#include <libedata-book/e-book-backend-sexp.h>
+#include <libedata-book/e-book-backend-summary.h>
+#include <libedata-book/e-data-book.h>
+#include <libedata-book/e-data-book-view.h>
+#include "e-book-backend-groupwise.h"
+#include  <e-gw-connection.h>
+#include <e-gw-item.h>
+
+static EBookBackendClass *e_book_backend_groupwise_parent_class;
+                                                                                                                             
+struct _EBookBackendGroupwisePrivate {
+	EGwConnection *cnc; 
+	char *uri;
+	char *container_id;
+	char *book_name;
+	gboolean only_if_exists;
+
+};
+
+#define ELEMENT_TYPE_SIMPLE 0x01
+#define ELEMENT_TYPE_COMPLEX 0x02 /* fields which require explicit functions to set values into EContact and EGwItem */
+
+static void populate_emails (EContact *contact, gpointer data);
+static void populate_full_name (EContact *contact, gpointer data);
+static void populate_contact_members (EContact *contact, gpointer data);
+static void set_full_name_in_gw_item (EGwItem *item, gpointer data);
+static void  set_emails_in_gw_item (EGwItem *item, gpointer data);
+static void set_members_in_gw_item (EGwItem *item, gpointer data);
+static void populate_birth_date (EContact *contact, gpointer data);
+static void set_birth_date_in_gw_item (EGwItem *item, gpointer data);
+static void populate_address (EContact *contact, gpointer data);
+static void set_address_in_gw_item (EGwItem *item, gpointer data);
+static void populate_ims (EContact *contact, gpointer data);
+static void set_ims_in_gw_item (EGwItem *item, gpointer data);
+
+struct field_element_mapping {
+	EContactField field_id;
+  
+	int element_type;
+	char *element_name;
+	
+	void (*populate_contact_func)(EContact *contact,    gpointer data);
+	void (*set_value_in_gw_item) (EGwItem *item, gpointer data);
+	
+ 
+} mappings [] = { 
+  
+	{ E_CONTACT_UID, ELEMENT_TYPE_SIMPLE, "id"},
+	{ E_CONTACT_FILE_AS, ELEMENT_TYPE_SIMPLE, "name" },
+	{ E_CONTACT_FULL_NAME, ELEMENT_TYPE_COMPLEX, "full_name", populate_full_name, set_full_name_in_gw_item},
+	{ E_CONTACT_BIRTH_DATE, ELEMENT_TYPE_COMPLEX, "birthday", populate_birth_date, set_birth_date_in_gw_item},
+	{ E_CONTACT_HOMEPAGE_URL, ELEMENT_TYPE_SIMPLE, "website"},
+	{ E_CONTACT_NOTE, ELEMENT_TYPE_SIMPLE, "comment"},
+	{ E_CONTACT_PHONE_PRIMARY, ELEMENT_TYPE_SIMPLE , "default_phone"},
+	{ E_CONTACT_EMAIL_1, ELEMENT_TYPE_COMPLEX, "email", populate_emails, set_emails_in_gw_item },
+	{ E_CONTACT_PHONE_BUSINESS, ELEMENT_TYPE_SIMPLE, "phone_Office"},
+	{ E_CONTACT_PHONE_HOME, ELEMENT_TYPE_SIMPLE, "phone_Home"},
+	{ E_CONTACT_PHONE_MOBILE, ELEMENT_TYPE_SIMPLE, "phone_Mobile"},
+	{ E_CONTACT_PHONE_BUSINESS_FAX, ELEMENT_TYPE_SIMPLE, "phone_Fax" },
+	{ E_CONTACT_PHONE_PAGER, ELEMENT_TYPE_SIMPLE, "phone_Pager"},
+	{ E_CONTACT_ORG, ELEMENT_TYPE_SIMPLE, "organization"},
+	{ E_CONTACT_ORG_UNIT, ELEMENT_TYPE_SIMPLE, "department"},
+	{ E_CONTACT_TITLE, ELEMENT_TYPE_SIMPLE, "title"},
+	{ E_CONTACT_EMAIL, ELEMENT_TYPE_COMPLEX, "members", populate_contact_members, set_members_in_gw_item},
+	{ E_CONTACT_ADDRESS_HOME, ELEMENT_TYPE_COMPLEX, "Home", populate_address, set_address_in_gw_item },
+	{ E_CONTACT_IM_AIM, ELEMENT_TYPE_COMPLEX, "service", populate_ims, set_ims_in_gw_item }
+
+}; 
+
+
+static int num_mappings = sizeof(mappings) / sizeof(mappings [0]);
+
+static int email_fields [3] = {
+	E_CONTACT_EMAIL_1,
+	E_CONTACT_EMAIL_2,
+	E_CONTACT_EMAIL_3
+
+};
+
+static void 
+populate_ims (EContact *contact, gpointer data)
+{
+	GList *im_list;
+	GList *aim_list = NULL;
+	GList *icq_list = NULL;
+	GList *yahoo_list = NULL;
+	GList *msn_list = NULL;
+	GList *jabber_list = NULL;
+	IMAddress *address;
+
+	EGwItem *item;
+  
+	item = E_GW_ITEM (data);
+  
+	im_list = e_gw_item_get_im_list (item);
+	for (; im_list != NULL; im_list = g_list_next (im_list)) {
+
+		address = (IMAddress *) (im_list->data);
+		if (address->service == NULL) {
+			continue;
+		}
+		if (g_str_equal (address->service, "icq"))
+			icq_list = g_list_append (icq_list, address->address);
+		else if (g_str_equal (address->service, "aim"))
+			aim_list = g_list_append (aim_list, address->address);
+		else if ( g_str_equal (address->service, "msn"))
+			msn_list = g_list_append (msn_list, address->address);
+		else if (g_str_equal (address->service, "yahoo"))
+			yahoo_list = g_list_append (yahoo_list, address->address);
+		else if (g_str_equal (address->service, "jabber"))
+			jabber_list = g_list_append (jabber_list, address->address);
+	}
+     
+	e_contact_set (contact, E_CONTACT_IM_AIM, aim_list);
+	e_contact_set (contact, E_CONTACT_IM_JABBER, jabber_list);
+	e_contact_set (contact, E_CONTACT_IM_ICQ, icq_list);
+	e_contact_set (contact, E_CONTACT_IM_YAHOO, yahoo_list);
+	e_contact_set (contact, E_CONTACT_IM_MSN, msn_list);
+}
+
+
+static void append_ims_to_list (GList **im_list, EContact *contact,  char *service_name, EContactField field_id)
+{
+	GList *list;
+	IMAddress *address;
+	list = e_contact_get (contact, field_id);
+	for (; list != NULL; list =  g_list_next (list)) {
+		address = g_new0 (IMAddress , 1);
+		address->service = g_strdup (service_name);
+		address->address = list->data;
+		*im_list = g_list_append (*im_list, address);
+	}
+	
+}
+
+static void 
+set_ims_in_gw_item (EGwItem *item, gpointer data)
+{
+	EContact *contact;
+	GList *im_list = NULL;
+  
+	contact = E_CONTACT (data);
+  
+	append_ims_to_list (&im_list, contact, "aim", E_CONTACT_IM_AIM);
+	append_ims_to_list (&im_list, contact, "yahoo", E_CONTACT_IM_YAHOO);
+	append_ims_to_list (&im_list, contact, "icq", E_CONTACT_IM_ICQ);
+	append_ims_to_list (&im_list, contact, "msn", E_CONTACT_IM_MSN);
+	append_ims_to_list (&im_list, contact, "jabber", E_CONTACT_IM_JABBER);
+	if (im_list)
+		e_gw_item_set_im_list (item, im_list);
+}
+
+static void 
+copy_postal_address_to_contact_address ( EContactAddress *contact_addr, PostalAddress *address)
+{
+	contact_addr->address_format = NULL;
+	contact_addr->po = NULL;
+	contact_addr->street = g_strdup (address->street_address);
+	contact_addr->locality = g_strdup (address->location);
+	contact_addr->region = g_strdup (address->state);
+	contact_addr->code = g_strdup (address->postal_code);
+	contact_addr->country = g_strdup (address->country);
+}
+
+static void 
+copy_contact_address_to_postal_address (PostalAddress *address, EContactAddress *contact_addr)
+{
+	address->street_address = g_strdup (contact_addr->street);
+	address->location = g_strdup (contact_addr->locality);
+	address->state = g_strdup (contact_addr->region);
+	address->postal_code = g_strdup (contact_addr->code);
+	address->country = g_strdup (contact_addr->country);
+}
+
+static void 
+populate_address (EContact *contact, gpointer data)
+{
+	PostalAddress *address;
+	EGwItem *item;
+	EContactAddress *contact_addr;
+	
+	item = E_GW_ITEM (data);
+	
+	address = e_gw_item_get_address (item, "Home");
+	contact_addr = NULL;
+
+	if (address) {
+		contact_addr = g_new0(EContactAddress, 1);
+		copy_postal_address_to_contact_address (contact_addr, address);
+		e_contact_set (contact, E_CONTACT_ADDRESS_HOME, contact_addr);
+	}
+  
+	address = e_gw_item_get_address (item, "Office");
+	if (address) {
+		contact_addr = g_new0(EContactAddress, 1);
+		copy_postal_address_to_contact_address (contact_addr, address);
+		e_contact_set (contact, E_CONTACT_ADDRESS_WORK, contact_addr);
+	}
+
+}
+
+static void 
+set_address_in_gw_item (EGwItem *item, gpointer data)
+{
+	EContact *contact;
+	EContactAddress *contact_address;
+	PostalAddress *address;
+
+	contact = E_CONTACT (data);
+	
+	contact_address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+	if (contact_address) {
+		address = g_new0(PostalAddress, 1);
+		copy_contact_address_to_postal_address (address, contact_address);
+		e_gw_item_set_address (item, "Home", address);
+	}
+		
+	contact_address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+	if (contact_address) {
+		address = g_new0(PostalAddress, 1);
+		copy_contact_address_to_postal_address (address, contact_address);
+		e_gw_item_set_address (item, "Office", address);
+	}
+	
+
+}
+
+static void 
+populate_birth_date (EContact *contact, gpointer data)
+{
+	EGwItem *item;
+  
+	item = E_GW_ITEM (data);
+	char *value ;
+	EContactDate *date;
+	value = e_gw_item_get_field_value (item, "birthday");
+ 
+  
+	if (value) {
+		date =  e_contact_date_from_string (value);
+		e_contact_set (contact, E_CONTACT_BIRTH_DATE, date);
+		e_contact_date_free (date);
+	}
+}
+
+static void 
+set_birth_date_in_gw_item (EGwItem *item, gpointer data)
+{
+	EContact *contact;
+	EContactDate *date;
+
+	contact = E_CONTACT (data);
+	date = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
+	if (date)
+		e_gw_item_set_field_value (item, "birthday", e_contact_date_to_string (date));
+
+
+}
+
+static void 
+populate_emails (EContact *contact, gpointer data)
+{
+	GList *email_list;
+	EGwItem *item;
+	int i;
+
+	item = E_GW_ITEM (data);
+	email_list = e_gw_item_get_email_list(item);
+
+	for (i =0 ; i < 3; i++, email_list = g_list_next (email_list)) {
+		if (email_list && email_list->data)
+			e_contact_set (contact, email_fields[i], email_list->data);
+
+	}
+  
+} 
+
+static void 
+set_emails_in_gw_item (EGwItem *item, gpointer data)
+{
+	GList *email_list;
+	EContact *contact;
+	char *email;
+	contact = E_CONTACT (data);
+	int i;
+
+	email_list = NULL;
+	for (i =0 ; i < 3; i++) {
+		email = g_strdup (e_contact_get (contact, email_fields[i]));
+		if(email)
+			email_list = g_list_append (email_list, email);
+	}
+	e_gw_item_set_email_list (item, email_list);
+
+}  
+
+static void 
+populate_full_name (EContact *contact, gpointer data)
+{
+	EGwItem *item;
+	item = E_GW_ITEM(data);
+	char *value ;
+	value = e_gw_item_get_full_name (item);
+	if (value) {
+		e_contact_set (contact, E_CONTACT_FULL_NAME, value);
+	}
+
+}
+
+static void 
+set_full_name_in_gw_item (EGwItem *item, gpointer data)
+{
+	EContact *contact;
+	char   *name;
+	EContactName *contact_name;
+	FullName *full_name;
+
+	contact = E_CONTACT (data);
+  
+	name = e_contact_get (contact, E_CONTACT_FULL_NAME);
+
+	if(name) {
+		contact_name = e_contact_name_from_string (name);
+		full_name = g_new0 (FullName, 1);
+		if (contact_name && full_name) {
+		  
+			full_name->name_prefix = g_strdup (contact_name->prefixes);
+			full_name->first_name =  g_strdup (contact_name->given);
+			full_name->middle_name = g_strdup (contact_name->additional);
+			full_name->last_name = g_strdup (contact_name->family);
+			full_name->name_suffix = g_strdup (contact_name->suffixes);
+			e_contact_name_free (contact_name);
+		}
+		  
+		e_gw_item_set_full_name (item, full_name);
+	}
+}
+
+static void 
+populate_contact_members (EContact *contact, gpointer data)
+{
+	EGwItem *item;
+	item = E_GW_ITEM(data);
+	e_contact_set (contact, E_CONTACT_EMAIL, e_gw_item_get_member_list(item));
+
+}
+static void
+set_members_in_gw_item (EGwItem  *item, gpointer data)
+{
+  
+	EContact *contact;
+	contact = E_CONTACT (data);
+	GList*  members ;
+	members = e_contact_get (contact, E_CONTACT_EMAIL);
+	e_gw_item_set_member_list (item, members);
+  
+}
+
+static void 
+fill_contact_from_gw_item (EContact *contact, EGwItem *item)
+{
+
+	char* value;
+	int element_type;
+	int i;
+
+	e_contact_set (contact, E_CONTACT_IS_LIST, e_gw_item_get_item_type (item) == E_GW_ITEM_TYPE_GROUP ? TRUE: FALSE);
+	for ( i = 0; i < num_mappings; i++) {
+		element_type = mappings[i].element_type;
+		if(element_type == ELEMENT_TYPE_SIMPLE)
+			{
+				value = e_gw_item_get_field_value (item, mappings[i].element_name);
+				if(value != NULL)
+					e_contact_set (contact, mappings[i].field_id, value);
+	
+			} else if (element_type == ELEMENT_TYPE_COMPLEX) {
+
+				mappings[i].populate_contact_func(contact, item);
+			}
+    
+	}
+}
+
+static void
+e_book_backend_groupwise_create_contact (EBookBackend *backend,
+					 EDataBook *book,
+					 const char *vcard )
+{
+	EContact *contact;
+	EBookBackendGroupwise *egwb;
+	char *id;
+	int status;
+	EGwItem *item;
+	int element_type;
+	char* value;
+	int i;
+
+	egwb = E_BOOK_BACKEND_GROUPWISE (backend);
+	contact = e_contact_new_from_vcard(vcard);
+	item = e_gw_item_new_empty ();
+	e_gw_item_set_item_type (item, e_contact_get (contact, E_CONTACT_IS_LIST) ? E_GW_ITEM_TYPE_GROUP :E_GW_ITEM_TYPE_CONTACT);
+	e_gw_item_set_container_id (item, g_strdup(egwb->priv->container_id));
+
+	for (i = 0; i < num_mappings; i++) {
+		element_type = mappings[i].element_type;
+		if (element_type == ELEMENT_TYPE_SIMPLE)  {
+			value =  e_contact_get(contact, mappings[i].field_id);
+			if (value != NULL)
+				e_gw_item_set_field_value (item, mappings[i].element_name, value);
+		} else if (element_type == ELEMENT_TYPE_COMPLEX) {
+			mappings[i].set_value_in_gw_item (item, contact);
+		}
+     
+    
+	}
+	status = e_gw_connection_create_item (egwb->priv->cnc, item, &id);  
+	if (status == E_GW_CONNECTION_STATUS_OK) {
+		e_contact_set (contact, E_CONTACT_UID, id);
+		e_data_book_respond_create(book,  GNOME_Evolution_Addressbook_Success, contact);
+		g_free(id);
+	}
+	else {
+		e_data_book_respond_create(book, GNOME_Evolution_Addressbook_OtherError, NULL);
+	}
+  
+}
+
+static void
+e_book_backend_groupwise_remove_contacts (EBookBackend *backend,
+					  EDataBook    *book,
+					  GList *id_list    )
+{
+  
+	char *id;
+ 
+	EBookBackendGroupwise *ebgw;
+	GList *deleted_ids = NULL;
+	/* FIXME use removeItems method so that all contacts can be deleted in a single SOAP interaction */
+	ebgw = E_BOOK_BACKEND_GROUPWISE (backend);
+	for ( ; id_list != NULL; id_list = g_list_next (id_list)) {
+		id = (char*) id_list->data;
+		if (e_gw_connection_remove_item (ebgw->priv->cnc, ebgw->priv->container_id, id) == E_GW_CONNECTION_STATUS_OK) 
+			deleted_ids =  g_list_append (deleted_ids, id);
+	}
+	e_data_book_respond_remove_contacts (book,
+					     GNOME_Evolution_Addressbook_Success,  deleted_ids);
+}
+
+
+static void
+e_book_backend_groupwise_modify_contact (EBookBackend *backend,
+					 EDataBook    *book,
+					 const char *vcard    )
+{	
+	EContact *contact;
+	EBookBackendGroupwise *egwb;
+	char *id;
+	int status;
+	EGwItem *item;
+	int element_type;
+	char* value;
+	int i;
+	
+	egwb = E_BOOK_BACKEND_GROUPWISE (backend);
+	contact = e_contact_new_from_vcard(vcard);
+	item = e_gw_item_new_empty ();
+	e_gw_item_set_item_type (item, e_contact_get (contact, E_CONTACT_IS_LIST) ? E_GW_ITEM_TYPE_GROUP :E_GW_ITEM_TYPE_CONTACT);
+	e_gw_item_set_container_id (item, g_strdup(egwb->priv->container_id));
+
+	for (i = 0; i < num_mappings; i++) {
+		element_type = mappings[i].element_type;
+		if (element_type == ELEMENT_TYPE_SIMPLE)  {
+			value =  e_contact_get(contact, mappings[i].field_id);
+			if (value != NULL)
+				e_gw_item_set_field_value (item, mappings[i].element_name, value);
+		} else if (element_type == ELEMENT_TYPE_COMPLEX) {
+			mappings[i].set_value_in_gw_item (item, contact);
+		}
+   
+	}
+	id = e_contact_get (contact, E_CONTACT_UID);
+	status = e_gw_connection_modify_item (egwb->priv->cnc, id, item);
+	if (status == E_GW_CONNECTION_STATUS_OK) 
+		e_data_book_respond_modify (book, GNOME_Evolution_Addressbook_Success, contact);
+	else 
+		e_data_book_respond_modify (book, GNOME_Evolution_Addressbook_OtherError, NULL);
+	g_object_unref (item);
+	g_object_unref (contact);
+		
+
+	
+}
+
+static void
+e_book_backend_groupwise_get_contact (EBookBackend *backend,
+				      EDataBook    *book,
+				      const char *id   )
+{
+	EBookBackendGroupwise *gwb ;
+	int status ;
+	EGwItem *item;
+	EContact *contact;
+	char *vcard;
+
+	gwb =  E_BOOK_BACKEND_GROUPWISE (backend);
+  	status = e_gw_connection_get_item (gwb->priv->cnc, gwb->priv->container_id, id,  &item);
+	if (status == E_GW_CONNECTION_STATUS_OK) {
+		if (item) {
+			contact = e_contact_new ();
+			fill_contact_from_gw_item (contact, item);
+			vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+			e_data_book_respond_get_contact (book, GNOME_Evolution_Addressbook_Success, vcard);
+			g_free (vcard);
+			g_object_unref (contact);
+			g_object_unref (item);
+			return;
+		}
+    
+	}
+	e_data_book_respond_get_contact (book, GNOME_Evolution_Addressbook_OtherError, "");  
+	
+}
+
+
+
+
+static void
+e_book_backend_groupwise_get_contact_list (EBookBackend *backend,
+					   EDataBook    *book,
+					   const char *query )
+{
+  
+	GList *vcard_list;
+	int status;
+	GList *gw_items;
+	EContact *contact;
+	EBookBackendGroupwise *egwb;
+	gboolean search_needed;
+	EBookBackendSExp *card_sexp = NULL;
+
+	egwb = E_BOOK_BACKEND_GROUPWISE (backend);
+	vcard_list = NULL;
+	gw_items = NULL;
+
+	/* FIXME currently contacts received form Gw Server are checked for match against the query.
+	   Instead of this Groupwise filter should be formed frm the query and given as input to get items calls
+	   to make things more efficient */
+
+	search_needed = TRUE;
+	if ( g_str_equal(query, "(contains \"x-evolution-any-field\" \"\")"))
+		search_needed = FALSE;
+
+	card_sexp = e_book_backend_sexp_new (query);
+	if (!card_sexp) {
+		e_data_book_respond_get_contact_list (book, GNOME_Evolution_Addressbook_ContactNotFound,
+						      vcard_list);
+	}
+
+	status = e_gw_connection_get_items (egwb->priv->cnc, egwb->priv->container_id, NULL, &gw_items);
+	if (status != E_GW_CONNECTION_STATUS_OK) {
+		e_data_book_respond_get_contact_list (book, GNOME_Evolution_Addressbook_OtherError,
+						      NULL);
+		return;
+	}
+	for (; gw_items != NULL; gw_items = g_list_next(gw_items)) { 
+		contact = e_contact_new ();
+		fill_contact_from_gw_item (contact, E_GW_ITEM (gw_items->data));
+		if ( (!search_needed) || e_book_backend_sexp_match_contact (card_sexp, contact));
+		vcard_list = g_list_append (vcard_list, e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));
+		g_object_unref (contact);
+		g_object_unref (gw_items->data);
+    	}
+  
+	e_data_book_respond_get_contact_list (book, GNOME_Evolution_Addressbook_Success,
+					      vcard_list);
+  
+}
+
+ 
+static void
+e_book_backend_groupwise_start_book_view (EBookBackend  *backend,
+					  EDataBookView *book_view)
+{
+
+	GList *contact_list;
+	int status;
+	GList *gw_items;
+	EContact *contact;
+	EBookBackendGroupwise *gwb = E_BOOK_BACKEND_GROUPWISE (backend);
+	contact_list = NULL;
+	gw_items = NULL;
+    
+	status = e_gw_connection_get_items (gwb->priv->cnc, gwb->priv->container_id, NULL, &gw_items);
+    
+	if (status != E_GW_CONNECTION_STATUS_OK) {
+		e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_OtherError);
+		return;
+	}
+	for (; gw_items != NULL; gw_items = g_list_next(gw_items)) { 
+		contact = e_contact_new ();
+		fill_contact_from_gw_item (contact, E_GW_ITEM (gw_items->data));
+		contact_list = g_list_append (contact_list, contact);
+		e_data_book_view_notify_update (book_view, contact);
+		g_object_unref(contact);
+		g_object_unref (gw_items->data);
+      
+	}
+    
+	e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success);
+    
+}     
+  
+static void
+e_book_backend_groupwise_stop_book_view (EBookBackend  *backend,
+					 EDataBookView *book_view)
+{
+	/* FIXME : provide implmentation */
+}
+
+static void
+e_book_backend_groupwise_get_changes (EBookBackend *backend,
+				      EDataBook    *book,
+				      const char *change_id  )
+{
+
+	/* FIXME : provide implmentation */
+
+       
+}
+
+static void
+e_book_backend_groupwise_authenticate_user (EBookBackend *backend,
+					    EDataBook    *book,
+					    const char *user,
+					    const char *passwd,
+					    const char *auth_method)
+{
+	EBookBackendGroupwise *ebgw;
+	EBookBackendGroupwisePrivate *priv;
+	char *id;
+	int status;
+	gboolean is_writable;
+
+	ebgw = E_BOOK_BACKEND_GROUPWISE (backend);
+	priv = ebgw->priv;
+  
+	priv->cnc = e_gw_connection_new (priv->uri, user, passwd);
+	if (priv->cnc == NULL) {
+		e_data_book_respond_authenticate_user (book,  GNOME_Evolution_Addressbook_OtherError);
+		return;
+	}
+
+	id = NULL;
+	is_writable = FALSE;
+	status = e_gw_connection_get_address_book_id (priv->cnc,  priv->book_name, &id, &is_writable); 
+	if (status == E_GW_CONNECTION_STATUS_OK) {
+		if ( (id == NULL) && !priv->only_if_exists ) {
+      
+			status = e_gw_connection_create_book (priv->cnc, priv->book_name,  &id);
+			if (status != E_GW_CONNECTION_STATUS_OK ) {
+				e_data_book_respond_authenticate_user (book,  GNOME_Evolution_Addressbook_OtherError);
+				return;
+			}
+     
+		}
+
+	}
+	if (id != NULL) {
+		priv->container_id = g_strdup (id);
+		g_free(id);
+		e_book_backend_set_is_writable (backend, is_writable);
+		e_data_book_report_writable (book, is_writable);
+		e_data_book_respond_authenticate_user (book,  GNOME_Evolution_Addressbook_Success); 
+   
+	} else {
+		e_book_backend_set_is_loaded (backend, FALSE);
+		e_data_book_respond_authenticate_user (book,  GNOME_Evolution_Addressbook_OtherError);
+	}
+  
+}
+
+static void
+e_book_backend_groupwise_get_supported_fields (EBookBackend *backend,
+					       EDataBook    *book )
+{
+	GList *fields = NULL;
+	int i;
+  
+	for (i = 0; i < num_mappings ; i ++)
+		fields = g_list_append (fields, g_strdup (e_contact_field_name (mappings[i].field_id)));
+	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_EMAIL_2)));
+	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_EMAIL_3)));
+	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_ICQ)));
+	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_YAHOO)));
+	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_MSN)));
+	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_JABBER)));
+	fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_ADDRESS_WORK)));
+	e_data_book_respond_get_supported_fields (book,
+						  GNOME_Evolution_Addressbook_Success,
+						  fields);
+ 
+}
+  
+
+static GNOME_Evolution_Addressbook_CallStatus
+e_book_backend_groupwise_load_source (EBookBackend           *backend,
+				      ESource                *source,
+				      gboolean                only_if_exists)
+{
+	EBookBackendGroupwise *ebgw;
+	EBookBackendGroupwisePrivate *priv;
+	const char *book_name;
+  
+	ebgw = E_BOOK_BACKEND_GROUPWISE (backend);
+	priv = ebgw->priv;
+	priv->uri = e_source_get_uri (source);
+	if(priv->uri == NULL)
+		return  GNOME_Evolution_Addressbook_OtherError;
+	priv->only_if_exists = only_if_exists;
+	book_name = e_source_peek_name(source);
+	if(book_name == NULL)
+		return  GNOME_Evolution_Addressbook_OtherError;
+	priv->book_name = g_strdup (book_name);
+  
+	e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE);
+	e_book_backend_set_is_writable (E_BOOK_BACKEND(backend), FALSE);  
+	return GNOME_Evolution_Addressbook_Success;
+}
+
+static void
+e_book_backend_groupwise_remove (EBookBackend *backend,
+				 EDataBook        *book)
+{
+	EBookBackendGroupwise *ebgw;
+	int status;
+  
+	ebgw = E_BOOK_BACKEND_GROUPWISE (backend);
+	status = e_gw_connection_remove_item (ebgw->priv->cnc, NULL, ebgw->priv->container_id);
+	if (status == E_GW_CONNECTION_STATUS_OK) 
+		e_data_book_respond_remove (book,  GNOME_Evolution_Addressbook_Success);
+	else
+		e_data_book_respond_remove (book,  GNOME_Evolution_Addressbook_OtherError);
+    
+}
+
+
+static char *
+e_book_backend_groupwise_get_static_capabilities (EBookBackend *backend)
+{
+	return g_strdup("net,bulk-removes");
+}
+static void 
+e_book_backend_groupwise_get_supported_auth_methods (EBookBackend *backend, EDataBook *book)
+{
+	/*FIXME  provide implementation*/  
+}
+
+
+/**
+ * e_book_backend_groupwise_new:
+ */
+EBookBackend *
+e_book_backend_groupwise_new (void)
+{
+	EBookBackendGroupwise *backend;
+                                                                                                                             
+	backend = g_object_new (E_TYPE_BOOK_BACKEND_GROUPWISE, NULL);
+                                                                                                       
+	return E_BOOK_BACKEND (backend);
+}
+
+static void
+e_book_backend_groupwise_dispose (GObject *object)
+{
+	EBookBackendGroupwise *bgw;
+                                                                                                                             
+	bgw = E_BOOK_BACKEND_GROUPWISE (object);
+                                                                                                                             
+	if (bgw->priv) {
+		if (bgw->priv->uri) {
+			g_free (bgw->priv->uri);
+			bgw->priv->uri = NULL;
+		}
+		if (bgw->priv->cnc) {
+			g_object_unref (bgw->priv->cnc);
+			bgw->priv->cnc = NULL;
+		}
+		if (bgw->priv->container_id) {
+			g_free (bgw->priv->container_id);
+			bgw->priv->container_id = NULL;
+		}
+		if (bgw->priv->book_name) {
+			g_free (bgw->priv->book_name);
+			bgw->priv->book_name = NULL;
+		}
+		g_free (bgw->priv);
+		bgw->priv = NULL;
+	}
+                                                                                                                             
+	G_OBJECT_CLASS (e_book_backend_groupwise_parent_class)->dispose (object);
+}
+                                                                                                                            
+static void
+e_book_backend_groupwise_class_init (EBookBackendGroupwiseClass *klass)
+{
+  
+
+	GObjectClass  *object_class = G_OBJECT_CLASS (klass);
+	EBookBackendClass *parent_class;
+
+
+	e_book_backend_groupwise_parent_class = g_type_class_peek_parent (klass);
+
+	parent_class = E_BOOK_BACKEND_CLASS (klass);
+
+	/* Set the virtual methods. */
+	parent_class->load_source             = e_book_backend_groupwise_load_source;
+	parent_class->get_static_capabilities = e_book_backend_groupwise_get_static_capabilities;
+
+	parent_class->create_contact          = e_book_backend_groupwise_create_contact;
+	parent_class->remove_contacts         = e_book_backend_groupwise_remove_contacts;
+	parent_class->modify_contact          = e_book_backend_groupwise_modify_contact;
+	parent_class->get_contact             = e_book_backend_groupwise_get_contact;
+	parent_class->get_contact_list        = e_book_backend_groupwise_get_contact_list;
+	parent_class->start_book_view         = e_book_backend_groupwise_start_book_view;
+	parent_class->stop_book_view          = e_book_backend_groupwise_stop_book_view;
+	parent_class->get_changes             = e_book_backend_groupwise_get_changes;
+	parent_class->authenticate_user       = e_book_backend_groupwise_authenticate_user;
+	parent_class->get_supported_fields    = e_book_backend_groupwise_get_supported_fields;
+	parent_class->get_supported_auth_methods = e_book_backend_groupwise_get_supported_auth_methods;
+	parent_class->remove                  = e_book_backend_groupwise_remove;
+	object_class->dispose                 = e_book_backend_groupwise_dispose;
+}
+
+static void
+e_book_backend_groupwise_init (EBookBackendGroupwise *backend)
+{
+	EBookBackendGroupwisePrivate *priv;
+                                                                                                                             
+	priv= g_new0 (EBookBackendGroupwisePrivate, 1);
+                                                                                                                             
+	backend->priv = priv;
+}
+
+
+/**
+ * e_book_backend_groupwise_get_type:
+ */
+GType
+e_book_backend_groupwise_get_type (void)
+{
+	static GType type = 0;
+                                                                                                                             
+	if (! type) {
+		GTypeInfo info = {
+			sizeof (EBookBackendGroupwiseClass),
+			NULL, /* base_class_init */
+			NULL, /* base_class_finalize */
+			(GClassInitFunc)  e_book_backend_groupwise_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof (EBookBackendGroupwise),
+			0,    /* n_preallocs */
+			(GInstanceInitFunc) e_book_backend_groupwise_init
+		};
+                                                                                                                             
+		type = g_type_register_static (E_TYPE_BOOK_BACKEND, "EBookBackendGroupwise", &info, 0);
+	}
+                                                                                                                             
+	return type;
+}
+
+	
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/ChangeLog,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -r1.4 -r1.4.2.1
--- ChangeLog	6 Feb 2004 18:52:25 -0000	1.4
+++ ChangeLog	20 Feb 2004 14:57:57 -0000	1.4.2.1
@@ -1,3 +1,34 @@
+2004-02-20 Sivaiah Nallagatla <snallagatla novell com>
+
+	* e-gw-container.[ch] (e_gw_container_get_is_writable)
+	(e_gw_container_set_is_writable) : get and set functions
+	to used to get and set is_writable variable whcih indicates 
+	whether user can create items under this container or not 
+	
+	* e-gw-item.[ch] 
+	(e_gw_item_get_field_value), (e_gw_item_set_field_value)
+	(e_gw_item_get_email_list), (e_gw_item_set_email_list)
+	(e_gw_item_get_full_name), (e_gw_item_set_full_name)
+	(e_gw_item_get_member_list), (e_gw_item_set_member_list)
+	(e_gw_item_get_address), (e_gw_item_set_address)
+	(e_gw_item_get_im_list), (e_gw_item_set_im_list) : Added new varibles
+	to EGwItemPrivate structure , defined some new structes and added the above 
+	get and set functions for setting and getting contact related data into EGwItem 
+	
+	* e-gw-connection.[ch]
+	(e_gw_connection_create_item), (e_gw_connection_get_item)
+	(e_gw_connection_create_book), (e_gw_connection_remove_book)
+	(e_gw_connection_get_address_book_list), (e_gw_connection_get_address_book_id) :
+	added new functions required for groupwise address book backend 
+	
 2004-02-06  Rodrigo Moya <rodrigo ximian com>
 
 	* Makefile.am:
Index: e-gw-message.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-message.h,v
retrieving revision 1.3
diff -u -r1.3 e-gw-message.h
--- e-gw-message.h	5 Jan 2004 17:07:13 -0000	1.3
+++ e-gw-message.h	22 Feb 2004 13:37:52 -0000
@@ -31,6 +31,9 @@
 SoupSoapMessage *e_gw_message_new_with_header (const char *uri, const char *session_id, const char *method_name);
 void             e_gw_message_write_string_parameter (SoupSoapMessage *msg, const char *name,
 						      const char *prefix, const char *value);
+void e_gw_message_write_string_parameter_with_attribute (SoupSoapMessage *msg, const char *name, const char *prefix, const char *value, 
+							 char *attrubute_name, char*attribute_value);
+
 void             e_gw_message_write_footer (SoupSoapMessage *msg);
 
 G_END_DECLS
Index: e-gw-message.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-message.c,v
retrieving revision 1.12
diff -u -r1.12 e-gw-message.c
--- e-gw-message.c	5 Jan 2004 17:07:13 -0000	1.12
+++ e-gw-message.c	22 Feb 2004 13:37:52 -0000
@@ -119,6 +119,17 @@
 	soup_soap_message_end_element (msg);
 }
 
+void 
+e_gw_message_write_string_parameter_with_attribute (SoupSoapMessage *msg, const char *name, const char *prefix, const char *value, 
+						    char *attribute_name, char*attribute_value)
+{
+	soup_soap_message_start_element (msg, name, prefix, NULL);
+	soup_soap_message_add_attribute (msg, attribute_name, attribute_value, NULL, NULL);
+	soup_soap_message_write_string (msg, value);
+	soup_soap_message_end_element (msg);
+
+}
+
 void
 e_gw_message_write_footer (SoupSoapMessage *msg)
 {
Index: e-gw-container.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-container.h,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -u -r1.2 -r1.2.2.1
--- e-gw-container.h	6 Feb 2004 15:46:00 -0000	1.2
+++ e-gw-container.h	20 Feb 2004 14:57:57 -0000	1.2.2.1
@@ -55,6 +55,8 @@
 void          e_gw_container_set_name (EGwContainer *container, const char *new_name);
 const char   *e_gw_container_get_id (EGwContainer *container);
 void          e_gw_container_set_id (EGwContainer *container, const char *new_id);
+gboolean      e_gw_container_get_is_writable (EGwContainer *container);
+void          e_gw_container_set_is_writable (EGwContainer *container, gboolean writable);
 
 G_END_DECLS
 
Index: e-gw-container.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-container.c,v
retrieving revision 1.2
diff -u -r1.2 e-gw-container.c
--- e-gw-container.c	29 Jan 2004 18:49:55 -0000	1.2
+++ e-gw-container.c	22 Feb 2004 13:41:00 -0000
@@ -30,6 +30,7 @@
 struct _EGwContainerPrivate {
 	char *name;
 	char *id;
+	gboolean is_writable;
 };
 
 static GObjectClass *parent_class = NULL;
@@ -146,10 +147,6 @@
 	g_return_val_if_fail (E_IS_GW_CONTAINER (container), FALSE);
 	g_return_val_if_fail (param != NULL, FALSE);
 
-	if (strcmp (soup_soap_parameter_get_name (param), "folder") != 0) {
-		g_warning (G_STRLOC ": SOAP parameter is not a folder");
-		return FALSE;
-	}
 
 	/* retrieve the name */
 	subparam = soup_soap_parameter_get_first_child_by_name (param, "name");
@@ -221,3 +218,20 @@
 		g_free (priv->id);
 	priv->id = g_strdup (new_id);
 }
+
+gboolean 
+e_gw_container_get_is_writable (EGwContainer *container)
+{
+	g_return_if_fail (E_IS_GW_CONTAINER (container));
+	
+	return container->priv->is_writable;
+
+}
+
+void 
+e_gw_container_set_is_writable (EGwContainer *container, gboolean is_writable)
+{
+	g_return_if_fail (E_IS_GW_CONTAINER (container));
+	
+	container->priv->is_writable = is_writable;
+}
Index: e-gw-connection.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-connection.h,v
retrieving revision 1.23
diff -u -r1.23 e-gw-connection.h
--- e-gw-connection.h	6 Feb 2004 18:52:26 -0000	1.23
+++ e-gw-connection.h	22 Feb 2004 13:42:57 -0000
@@ -83,8 +83,17 @@
 const char         *e_gw_connection_get_user_email (EGwConnection *cnc);
 const char         *e_gw_connection_get_user_uuid (EGwConnection *cnc);
 
+
 time_t              e_gw_connection_get_date_from_string (const char *dtstring);
 
+EGwConnectionStatus e_gw_connection_create_item (EGwConnection *cnc, EGwItem *item, char** id);
+EGwConnectionStatus e_gw_connection_get_item (EGwConnection *cnc, const char *container, const char *id, EGwItem **item);
+EGwConnectionStatus e_gw_connection_modify_item (EGwConnection *cnc, const char *id, EGwItem *item);
+EGwConnectionStatus e_gw_connection_create_book (EGwConnection *cnc, char *book_name, char**id);
+EGwConnectionStatus e_gw_connection_remove_book (EGwConnection *cnc, char *book_uid);
+EGwConnectionStatus e_gw_connection_get_address_book_list (EGwConnection *cnc, GList **container_list);
+EGwConnectionStatus e_gw_connection_get_address_book_id ( EGwConnection *cnc, char *book_name, char**id , gboolean *is_writable);
+
 G_END_DECLS
 
 #endif
Index: e-gw-connection.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-connection.c,v
retrieving revision 1.54
diff -u -r1.54 e-gw-connection.c
--- e-gw-connection.c	6 Feb 2004 18:52:25 -0000	1.54
+++ e-gw-connection.c	22 Feb 2004 13:43:11 -0000
@@ -484,7 +484,7 @@
         }
 
         e_gw_message_write_string_parameter (msg, "container", NULL, container);
-        e_gw_message_write_string_parameter (msg, "view", NULL, "recipients");
+	//        e_gw_message_write_string_parameter (msg, "view", NULL, "recipients");
 	if (filter)
 		e_gw_message_write_string_parameter (msg, "Filter", NULL, filter);
 	e_gw_message_write_footer (msg);
@@ -699,6 +699,152 @@
 }
 
 EGwConnectionStatus
+e_gw_connection_create_item (EGwConnection *cnc, EGwItem *item, char** id)
+{
+	SoupSoapMessage *msg;
+	SoupSoapResponse *response;
+	SoupSoapParameter *param;
+	EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
+	
+	g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
+	g_return_val_if_fail (E_IS_GW_ITEM (item), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
+
+	/* compose SOAP message */
+	msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "createItemRequest");
+	if (!msg) {
+		g_warning (G_STRLOC ": Could not build SOAP message");
+		return E_GW_CONNECTION_STATUS_UNKNOWN;
+	}
+
+	if (!e_gw_item_append_to_soap_message (item, msg)) {
+		g_warning (G_STRLOC ": Could not append item to SOAP message");
+		g_object_unref (msg);
+		return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+	}
+
+	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_INVALID_RESPONSE;
+	}
+
+	status = e_gw_connection_parse_response_status (response);
+	if ( status == E_GW_CONNECTION_STATUS_OK) {
+		param = soup_soap_response_get_first_parameter_by_name (response, "id");
+		if (param != NULL) 
+			*id = g_strdup (soup_soap_parameter_get_string_value (param));
+	}
+	g_object_unref (msg);
+	g_object_unref (response);
+
+	return status;
+}
+
+EGwConnectionStatus 
+e_gw_connection_modify_item (EGwConnection *cnc, const char *id , EGwItem *item)
+{
+	SoupSoapMessage *msg;
+        SoupSoapResponse *response;
+        EGwConnectionStatus status;
+	
+	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, "modifyItemRequest");
+        if (!msg) {
+                g_warning (G_STRLOC ": Could not build SOAP message");
+                return E_GW_CONNECTION_STATUS_UNKNOWN;
+        }
+
+	e_gw_message_write_string_parameter (msg, "id", NULL, id);
+	soup_soap_message_start_element (msg, "updates", NULL, NULL);
+	soup_soap_message_start_element (msg, "update", NULL, NULL);
+	if (!e_gw_item_append_to_soap_message (item, msg)) {
+		g_warning (G_STRLOC ": Could not append item to SOAP message");
+		g_object_unref (msg);
+		return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+	}
+	soup_soap_message_end_element (msg);
+	soup_soap_message_end_element (msg);
+	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_INVALID_RESPONSE;
+	}
+
+	status = e_gw_connection_parse_response_status (response);
+	g_object_unref (msg);
+	g_object_unref (response);
+
+	return status;
+		
+}
+
+EGwConnectionStatus 
+e_gw_connection_get_item (EGwConnection *cnc, const char *container, const char *id, EGwItem **item)
+{
+
+	SoupSoapMessage *msg;
+        SoupSoapResponse *response;
+        EGwConnectionStatus status;
+        SoupSoapParameter *param;
+
+        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, "getItemRequest");
+        if (!msg) {
+                g_warning (G_STRLOC ": Could not build SOAP message");
+                return E_GW_CONNECTION_STATUS_UNKNOWN;
+        }
+      
+
+	e_gw_message_write_string_parameter (msg, "id", NULL, id);
+	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_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+        if (status != E_GW_CONNECTION_STATUS_OK) {
+		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, "item");
+        if (!param) {
+                g_object_unref (response);
+                g_object_unref (msg);
+                return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
+        }
+	
+       	*item = e_gw_item_new_from_soap_parameter (container, param);
+	
+               
+	/* free memory */
+        g_object_unref (response);
+	g_object_unref (msg);
+
+        return E_GW_CONNECTION_STATUS_OK;
+}
+
+
+
+
+
+EGwConnectionStatus
 e_gw_connection_remove_item (EGwConnection *cnc, const char *container, const char *id)
 {
 	SoupSoapMessage *msg;
@@ -832,3 +978,177 @@
 
         return t;
 }
+
+EGwConnectionStatus 
+e_gw_connection_create_book (EGwConnection *cnc, char *book_name, char**id)
+{
+	SoupSoapMessage *msg;
+	int status;
+	SoupSoapResponse *response;
+	SoupSoapParameter *param;
+	char *value;
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "createItemRequest");
+        soup_soap_message_start_element (msg, "book", NULL, NULL);
+	e_gw_message_write_string_parameter (msg, "name", NULL, book_name);
+	soup_soap_message_end_element (msg);
+	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_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+        if (status != E_GW_CONNECTION_STATUS_OK) {
+		printf ("connection status OK\n");
+		g_object_unref (response);
+                g_object_unref (msg);
+		return status;
+	}
+	value = NULL;
+	param = soup_soap_response_get_first_parameter_by_name (response, "id");
+	if (param)
+		value = soup_soap_parameter_get_string_value (param);
+	if (value)
+		*id = g_strdup (value);
+
+	status = E_GW_CONNECTION_STATUS_OK;	
+	return status;	
+} 
+
+EGwConnectionStatus 
+e_gw_connection_remove_book (EGwConnection *cnc, char *book_uid)
+{
+	SoupSoapMessage *msg;
+	int status;
+	SoupSoapResponse *response;
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "removeItemRequest");
+	e_gw_message_write_string_parameter (msg, "id", NULL,  book_uid);
+	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_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+        if (status != E_GW_CONNECTION_STATUS_OK) {
+		printf ("connection status OK\n");
+		g_object_unref (response);
+                g_object_unref (msg);
+		return status;
+	}
+
+	status = E_GW_CONNECTION_STATUS_OK;	
+	return status;	
+	
+}
+
+
+
+EGwConnectionStatus
+e_gw_connection_get_address_book_list (EGwConnection *cnc, GList **container_list)
+{
+	SoupSoapMessage *msg;
+	SoupSoapResponse *response;
+        EGwConnectionStatus status;
+	SoupSoapParameter *param;
+	SoupSoapParameter *is_personal_param;
+	char *value;
+	
+	g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
+	g_return_val_if_fail (container_list != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getAddressBookListRequest");
+        if (!msg) {
+                g_warning (G_STRLOC ": Could not build SOAP message");
+                return E_GW_CONNECTION_STATUS_UNKNOWN;
+        }
+
+       	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_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+        g_object_unref (msg);
+
+	if (status != E_GW_CONNECTION_STATUS_OK) {
+                g_object_unref (response);
+                return status;
+        }
+	
+	/* if status is OK - parse result. return the list */	
+	param = soup_soap_response_get_first_parameter_by_name (response, "books");	
+        if (!param) {
+                g_object_unref (response);
+                return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
+        } else {
+		SoupSoapParameter *subparam;
+		for (subparam = soup_soap_parameter_get_first_child_by_name (param, "book");
+		     subparam != NULL;
+		     subparam = soup_soap_parameter_get_next_child_by_name (subparam, "book")) {
+			EGwContainer *container;
+				       
+			container = e_gw_container_new_from_soap_parameter (subparam);
+			if (container) {
+				*container_list = g_list_append (*container_list, container);
+				is_personal_param = soup_soap_parameter_get_first_child_by_name (subparam, "isPersonal");
+				value = NULL;
+				if (is_personal_param)
+					value = soup_soap_parameter_get_string_value (is_personal_param);
+				if (value && g_str_equal(value , "1"))
+					e_gw_container_set_is_writable (container, TRUE);
+				else 
+					e_gw_container_set_is_writable (container, FALSE);
+					
+			}
+				     
+		}
+	}
+
+	g_object_unref (response);
+
+        return status;
+}
+
+
+EGwConnectionStatus 
+e_gw_connection_get_address_book_id ( EGwConnection *cnc, char *book_name, char**id , gboolean *is_writable)
+{
+	EGwConnectionStatus status;
+	GList *container_list = NULL, *l;
+
+	g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
+	g_return_val_if_fail (book_name != NULL, NULL);
+
+	status = e_gw_connection_get_address_book_list (cnc, &container_list);
+        if (status != E_GW_CONNECTION_STATUS_OK) {
+		e_gw_connection_free_container_list (container_list);
+                return status;
+        }
+
+	/* search the container in the list */
+	for (l = container_list; l != NULL; l = l->next) {
+		EGwContainer *container = E_GW_CONTAINER (l->data);
+		if (strcmp (e_gw_container_get_name (container), book_name) == 0) {
+			
+			*id = g_strdup (e_gw_container_get_id (container));
+			*is_writable = e_gw_container_get_is_writable (container);
+			break;
+		}
+	}
+
+	e_gw_connection_free_container_list (container_list);
+
+	return status;
+
+}
Index: e-gw-item.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-item.h,v
retrieving revision 1.6
diff -u -r1.6 e-gw-item.h
--- e-gw-item.h	6 Feb 2004 18:52:26 -0000	1.6
+++ e-gw-item.h	22 Feb 2004 13:45:23 -0000
@@ -42,7 +42,12 @@
 typedef enum {
 	E_GW_ITEM_TYPE_APPOINTMENT,
 	E_GW_ITEM_TYPE_TASK,
+	E_GW_ITEM_TYPE_CONTACT,
+	E_GW_ITEM_TYPE_GROUP,
+	E_GW_ITEM_TYPE_ORGANISATION,
+	E_GW_ITEM_TYPE_RESOURCE,
 	E_GW_ITEM_TYPE_UNKNOWN
+	
 } EGwItemType;
 
 struct _EGwItem {
@@ -54,6 +59,31 @@
 	GObjectClass parent_class;
 };
 
+/* structures defined to hold contact item fields */
+typedef struct {
+	char *name_prefix;
+	char *first_name;
+	char *middle_name;
+	char *last_name;
+	char *name_suffix;
+} FullName;
+
+typedef struct {
+	char *street_address;
+	char *location;
+	char *city;
+	char *state;
+	char *postal_code;
+	char *country;
+} PostalAddress;
+
+typedef struct {
+
+	char *service;
+	char *address;
+}IMAddress;
+
+
 GType       e_gw_item_get_type (void);
 EGwItem    *e_gw_item_new_empty (void);
 EGwItem    *e_gw_item_new_from_soap_parameter (const char *container, SoupSoapParameter *param);
@@ -80,6 +110,18 @@
 void        e_gw_item_set_place (EGwItem *item, const char *new_place);
 gboolean    e_gw_item_get_completed (EGwItem *item);
 void        e_gw_item_set_completed (EGwItem *item, gboolean new_completed);
+char*       e_gw_item_get_field_value (EGwItem *item, char *field_name);
+void        e_gw_item_set_field_value (EGwItem *item, char *field_name, char* field_value);
+GList*      e_gw_item_get_email_list (EGwItem *item);
+void        e_gw_item_set_email_list (EGwItem *item, GList *email_list);
+char*       e_gw_item_get_full_name (EGwItem *item);
+void        e_gw_item_set_full_name (EGwItem *item, FullName* full_name);
+GList*      e_gw_item_get_member_list (EGwItem *item);
+void        e_gw_item_set_member_list (EGwItem *item, GList *list);
+PostalAddress* e_gw_item_get_address (EGwItem *item, char *address_type);
+void        e_gw_item_set_address (EGwItem *item, char *addres_type, PostalAddress *address);
+GList*      e_gw_item_get_im_list (EGwItem *item);
+void        e_gw_item_set_im_list (EGwItem *item, GList *im_list);
 
 #define E_GW_ITEM_CLASSIFICATION_PUBLIC       "Public"
 #define E_GW_ITEM_CLASSIFICATION_PRIVATE      "Private"
@@ -111,6 +153,8 @@
 	} type;
 } EGwItemRecipient;
 
+
+
 gboolean    e_gw_item_append_to_soap_message (EGwItem *item, SoupSoapMessage *msg);
 
 G_END_DECLS
Index: e-gw-item.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/e-gw-item.c,v
retrieving revision 1.14
diff -u -r1.14 e-gw-item.c
--- e-gw-item.c	18 Feb 2004 15:05:00 -0000	1.14
+++ e-gw-item.c	22 Feb 2004 13:47:14 -0000
@@ -25,10 +25,15 @@
 #include <config.h>
 #endif
 #include <string.h>
+#include <glib.h>
+
 #include "e-gw-item.h"
 #include "e-gw-connection.h"
 #include "e-gw-message.h"
 
+
+
+
 struct _EGwItemPrivate {
 	EGwItemType item_type;
 	char *container;
@@ -47,6 +52,15 @@
 	char *priority;
 	char *place;
 	GSList *recipient_list;
+	
+	/*properties for contacts */
+	FullName *full_name;
+	GList *email_list;
+	GList *im_list;
+	GHashTable *simple_fields;
+	GList *member_list;
+	GHashTable *addresses;
+	
 };
 
 static GObjectClass *parent_class = NULL;
@@ -59,6 +73,35 @@
 	g_free (recipient);
 }
 
+static void 
+free_postal_address (PostalAddress *address)
+{
+	if (address) {
+		g_free (address->street_address);
+		g_free (address->location);
+		g_free(address->city);
+		g_free(address->country);
+		g_free(address->state);
+		g_free(address->postal_code);
+		g_free(address);
+	}
+}
+static void 
+free_string (char *s, gpointer data)
+{
+	if (s)
+		free (s);
+}
+
+static void 
+free_im_address (IMAddress *address, gpointer data)
+{
+	if (address) {
+		g_free (address->service);
+		g_free (address->address);
+		g_free (address);
+	}
+}
 static void
 e_gw_item_dispose (GObject *object)
 {
@@ -113,6 +156,37 @@
 			g_slist_foreach (priv->recipient_list, (GFunc) free_recipient, NULL);
 			priv->recipient_list = NULL;
 		}	
+		/*	if (priv->full_name) {
+			g_free (priv->full_name->name_prefix);
+			g_free (priv->full_name->first_name);
+			g_free (priv->full_name->first_name);
+			g_free (priv->full_name->last_name);
+			g_free (priv->full_name->name_suffix);
+			g_free (priv->full_name);
+			priv->full_name = NULL;
+			}*/
+		if (priv->simple_fields)
+			g_hash_table_destroy (priv->simple_fields);
+		if (priv->addresses)
+			g_hash_table_destroy (priv->addresses);
+		if (priv->email_list) {
+			g_list_foreach (priv->email_list,  free_string , NULL);
+			g_list_free (priv->email_list);
+			priv->email_list = NULL;
+		}
+		if (priv->member_list) {
+			g_list_foreach (priv->member_list,  free_string, NULL);
+			g_list_free (priv->member_list);
+			priv->member_list = NULL;
+		}
+
+		if (priv->im_list) {
+			g_list_foreach (priv->im_list, free_im_address, NULL);
+			g_list_free (priv->im_list);
+			priv->im_list = NULL;
+		}
+		
+		
 	}
 
 	if (parent_class->dispose)
@@ -160,8 +234,15 @@
 	priv->start_date = -1;
 	priv->end_date = -1;
 	priv->due_date = -1;
-
+	priv->im_list = NULL;
+	priv->email_list = NULL;
+	priv->member_list = NULL;
+	priv->simple_fields = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+	priv->full_name = g_new0(FullName, 1);
+	priv->addresses = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, free_postal_address);
 	item->priv = priv;
+	
+	
 }
 
 GType
@@ -234,11 +315,624 @@
         }        
 }
 
+char*
+e_gw_item_get_field_value (EGwItem *item, char *field_name)
+{
+	gpointer value;
+
+	g_return_val_if_fail (field_name != NULL, NULL);
+	g_return_val_if_fail (E_IS_GW_ITEM(item), NULL);
+	
+	if (item->priv->simple_fields == NULL)
+		return NULL;
+       
+	value =  (char *) g_hash_table_lookup (item->priv->simple_fields, field_name);
+	if (value)
+		return g_strdup (value);
+			
+	return NULL;
+}
+
+void 
+e_gw_item_set_field_value (EGwItem *item, char *field_name, char* field_value)
+{
+	g_return_if_fail (field_name != NULL);
+	g_return_if_fail (field_name != NULL);
+	g_return_if_fail (E_IS_GW_ITEM(item));
+	
+	if (item->priv->simple_fields != NULL)
+		g_hash_table_insert (item->priv->simple_fields, field_name, field_value);
+
+}
+
+GList * 
+e_gw_item_get_email_list (EGwItem *item)
+{
+	return item->priv->email_list;
+
+
+}
+
+void 
+e_gw_item_set_email_list (EGwItem *item, GList* email_list)     
+{
+	item->priv->email_list = email_list;
+}
+
+GList * 
+e_gw_item_get_im_list (EGwItem *item)
+
+{
+	return item->priv->im_list;
+}
+
+void 
+e_gw_item_set_im_list (EGwItem *item, GList *im_list)
+{
+	item->priv->im_list = im_list;
+}
+char *
+e_gw_item_get_full_name (EGwItem *item)
+{
+	char *name;
+	FullName *full_name = item->priv->full_name;
+	
+
+	name = g_strconcat ( (full_name->name_prefix == NULL) ? "\0" : full_name->name_prefix, " ",
+			    (full_name->first_name == NULL) ? "\0" :    full_name->first_name, " ",
+			    (full_name->middle_name == NULL) ? "\0" : full_name->middle_name, " ",
+			    full_name->last_name == NULL ? "\0" : full_name->last_name, " ",
+			    (full_name->name_suffix == NULL ) ? "\0" : full_name->name_suffix, NULL);
+	name = g_strchomp (name);
+	
+		
+	if (strcmp (name, "\0") == 0)
+		return NULL;
+	return name;
+}
+
+void 
+e_gw_item_set_full_name (EGwItem *item, FullName *full_name)
+{	
+	item->priv->full_name = full_name;
+}
+
+GList *
+e_gw_item_get_member_list (EGwItem *item)
+{
+	return item->priv->member_list;
+}
+
+void 
+e_gw_item_set_member_list (EGwItem *item, GList *list)
+{
+	item->priv->member_list = list;
+
+}
+
+void 
+e_gw_item_set_address (EGwItem *item, char *address_type, PostalAddress *address)
+{
+	if (address_type && address)
+		g_hash_table_insert (item->priv->addresses, address_type, address);
+
+}
+
+PostalAddress *e_gw_item_get_address (EGwItem *item, char *address_type)
+{
+	return (PostalAddress *) g_hash_table_lookup (item->priv->addresses, address_type);
+}
+
+static void 
+set_common_addressbook_item_fields_from_soap_parameter (EGwItem *item, SoupSoapParameter *param)
+{
+	SoupSoapParameter *subparam;
+	GHashTable *simple_fields;
+	char *value;
+	if (strcmp (soup_soap_parameter_get_name (param), "item") != 0) {
+		g_warning (G_STRLOC ": Invalid SOAP parameter %s", soup_soap_parameter_get_name (param));
+		return;
+	}
+	printf ("parsing saop \n");
+	simple_fields = item->priv->simple_fields;
+
+	subparam = soup_soap_parameter_get_first_child_by_name(param, "id");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		g_hash_table_insert (simple_fields, "id", g_strdup (value));
+		item->priv->id = g_strdup (value);
+	}
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "comment");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if (value)
+			g_hash_table_insert (simple_fields , "comment", g_strdup (value));
+	}
+	subparam = soup_soap_parameter_get_first_child_by_name(param, "name");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if (value)
+			g_hash_table_insert (simple_fields, "name", g_strdup (value));
+	}
+
+
+
+}
+
+static void 
+set_postal_address_from_soap_parameter (PostalAddress *address, SoupSoapParameter *param)
+{
+	SoupSoapParameter *subparam;
+	char *value;
+
+	subparam= soup_soap_parameter_get_first_child_by_name (param, "streetAddress");
+	if (subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if (value)
+			address->street_address = g_strdup (value);
+	}
+	
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "location");
+	if (subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		
+		if (value)
+			address->location = g_strdup (value);
+	}
+	
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "city");
+	if (subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if (value)
+			address->city = g_strdup (value);
+	}
+	
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "state");
+	if (subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if (value)
+			address->state = g_strdup (value);
+	}
+	
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "postalCode");
+	if (subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if (value)
+			address->postal_code = g_strdup (value);
+	}
+	
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "country");
+	if (subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if (value)
+			address->country = g_strdup (value);
+	}
+	
+}
+
+static void 
+set_contact_fields_from_soap_parameter (EGwItem *item, SoupSoapParameter *param)
+{
+	const char *value;
+	const char *type;
+	char *primary_email;
+
+	SoupSoapParameter *subparam;
+	SoupSoapParameter *temp;
+	SoupSoapParameter *second_level_child;
+	GHashTable *simple_fields;
+	FullName *full_name ;
+	PostalAddress *address;
+	value = NULL;
+	if (strcmp (soup_soap_parameter_get_name (param), "item") != 0) {
+		g_warning (G_STRLOC ": Invalid SOAP parameter %s", soup_soap_parameter_get_name (param));
+		return;
+	}
+	set_common_addressbook_item_fields_from_soap_parameter (item, param);
+	simple_fields = item->priv->simple_fields;
+	full_name = item->priv->full_name;
+	if (full_name) {
+		subparam = soup_soap_parameter_get_first_child_by_name (param, "fullName");
+		if (subparam) {
+			temp = soup_soap_parameter_get_first_child_by_name(subparam, "namePrefix"); 
+			if (temp)
+				full_name->name_prefix = g_strdup (soup_soap_parameter_get_string_value (temp));
+			
+			temp = soup_soap_parameter_get_first_child_by_name(subparam, "firstName"); 
+			if (temp)
+				full_name->first_name = g_strdup (soup_soap_parameter_get_string_value (temp));
+			
+			temp = soup_soap_parameter_get_first_child_by_name(subparam, "middleName"); 
+			if (temp)
+				full_name->middle_name = g_strdup (soup_soap_parameter_get_string_value (temp));
+			
+			temp = soup_soap_parameter_get_first_child_by_name(subparam, "lastName"); 
+			if (temp)
+				full_name->last_name = g_strdup (soup_soap_parameter_get_string_value (temp));
+			
+			temp = soup_soap_parameter_get_first_child_by_name(subparam, "nameSuffix"); 
+			if (temp)
+				full_name->name_suffix = g_strdup (soup_soap_parameter_get_string_value (temp));
+		}
+	}
+	subparam = soup_soap_parameter_get_first_child_by_name(param, "emailList"); 
+	if (subparam) {
+		primary_email = g_strdup (soup_soap_parameter_get_property(subparam, "primary"));
+		item->priv->email_list = g_list_append (item->priv->email_list, g_strdup (primary_email));
+		g_hash_table_insert (simple_fields, "primary_email", g_strdup (soup_soap_parameter_get_property(subparam, "primary")));
+	
+		for ( temp = soup_soap_parameter_get_first_child (subparam); temp != NULL; temp = soup_soap_parameter_get_next_child (temp)) {
+			value = soup_soap_parameter_get_string_value (temp);
+			if (value && strcmp (primary_email, value) != 0)
+				item->priv->email_list = g_list_append (item->priv->email_list, g_strdup(value));
+		}		
+	}
+	
+	subparam =  soup_soap_parameter_get_first_child_by_name(param, "imList");
+	if(subparam) {
+		for ( temp = soup_soap_parameter_get_first_child (subparam); temp != NULL; temp = soup_soap_parameter_get_next_child (temp))
+			{
+				IMAddress *im_address = g_new(IMAddress, 1);
+				second_level_child = soup_soap_parameter_get_first_child_by_name (temp, "service");
+				if (second_level_child)
+					value = soup_soap_parameter_get_string_value (second_level_child);
+				if (value )
+					im_address->service = g_strdup (value);
+				second_level_child = soup_soap_parameter_get_first_child_by_name (temp, "address");
+				if (second_level_child)
+					value = soup_soap_parameter_get_string_value (second_level_child);
+				if (value)
+					im_address->address = g_strdup (value);
+			
+				item->priv->im_list = g_list_append (item->priv->im_list, im_address);
+			}
+	}
+	
+	
+	subparam =  soup_soap_parameter_get_first_child_by_name(param, "phoneList");
+	if(subparam) {
+		g_hash_table_insert (simple_fields, "default_phone", g_strdup (soup_soap_parameter_get_property(subparam, "default")));
+		for ( temp = soup_soap_parameter_get_first_child (subparam); temp != NULL; temp = soup_soap_parameter_get_next_child (temp))
+			{
+				type =  soup_soap_parameter_get_property (temp, "type");
+				value = soup_soap_parameter_get_string_value (temp);
+				g_hash_table_insert (item->priv->simple_fields, g_strconcat("phone_", type, NULL) , g_strdup (value));
+				
+			}
+	}
+	subparam =  soup_soap_parameter_get_first_child_by_name(param, "personalInfo");
+	if(subparam) {
+		temp = soup_soap_parameter_get_first_child_by_name (subparam, "birthday");
+		if(temp)
+			g_hash_table_insert (simple_fields, "birthday", g_strdup (soup_soap_parameter_get_string_value (temp)));
+		temp = soup_soap_parameter_get_first_child_by_name (subparam, "website");
+		if(temp)
+			g_hash_table_insert (simple_fields, "website", g_strdup (soup_soap_parameter_get_string_value (temp)));
+	}
+	subparam =  soup_soap_parameter_get_first_child_by_name(param, "officeInfo");
+	if (subparam) {
+		temp = soup_soap_parameter_get_first_child_by_name (subparam, "organization");
+		if(temp) {
+			value = soup_soap_parameter_get_string_value (temp);
+			if(value)
+				g_hash_table_insert (simple_fields, "organization", g_strdup(value));
+			
+		}
+		temp = soup_soap_parameter_get_first_child_by_name (subparam, "department");
+		if(temp) {
+			value = soup_soap_parameter_get_string_value (temp);
+			if(value)
+				g_hash_table_insert (simple_fields, "department", g_strdup(value));
+		}
+		temp = soup_soap_parameter_get_first_child_by_name (subparam, "title");
+		if(temp) {
+			value = soup_soap_parameter_get_string_value (temp);
+			if(value)
+				g_hash_table_insert (simple_fields, "title", g_strdup(value));
+		}
+			
+	}
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "members");
+	if (subparam) {
+		for ( temp = soup_soap_parameter_get_first_child (subparam); temp != NULL; temp = soup_soap_parameter_get_next_child (temp)) {
+			second_level_child = soup_soap_parameter_get_first_child_by_name (temp, "email"); 
+			if (second_level_child)
+				value = soup_soap_parameter_get_string_value (second_level_child);
+			if (value) 
+				item->priv->member_list = g_list_append (item->priv->member_list, g_strdup (value));
+			
+		}
+	}
+
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "addressList");
+	if (subparam) {
+		for ( temp = soup_soap_parameter_get_first_child (subparam); temp != NULL; temp = soup_soap_parameter_get_next_child (temp)) {
+			
+			address = g_new0 (PostalAddress, 1);
+			set_postal_address_from_soap_parameter (address, temp);
+			value = soup_soap_parameter_get_property(temp, "type");
+			if (value)
+				g_hash_table_insert (item->priv->addresses, g_strdup (value), address);
+			 			
+			
+		}
+		
+	}
+	
+}
+static void 
+set_resource_fields_from_soap_parameter (EGwItem *item, SoupSoapParameter *param)
+{
+
+	char *value;
+	SoupSoapParameter *subparam;
+	GHashTable *simple_fields;
+	
+	if (strcmp (soup_soap_parameter_get_name (param), "item") != 0) {
+		g_warning (G_STRLOC ": Invalid SOAP parameter %s", soup_soap_parameter_get_name (param));
+		return;
+	}
+	printf ("setting resource fields \n");
+	set_common_addressbook_item_fields_from_soap_parameter (item, param);
+	simple_fields = item->priv->simple_fields;
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "phone");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if(value)
+			g_hash_table_insert (simple_fields, "default_phone", g_strdup (value));
+	}
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "email");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if(value)
+			item->priv->email_list = g_list_append (item->priv->email_list, g_strdup (value));
+	}
+	
+}
+
+static void 
+set_organization_fields_from_soap_parameter (EGwItem *item, SoupSoapParameter *param)
+{
+
+	char *value;
+	SoupSoapParameter *subparam;
+	PostalAddress *address;
+	GHashTable *simple_fields;
+	
+	if (strcmp (soup_soap_parameter_get_name (param), "item") != 0) {
+		g_warning (G_STRLOC ": Invalid SOAP parameter %s", soup_soap_parameter_get_name (param));
+		return;
+	}
+	printf ("setting resource fields \n");
+	set_common_addressbook_item_fields_from_soap_parameter (item, param);
+	simple_fields = item->priv->simple_fields;
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "phone");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if(value)
+			g_hash_table_insert (simple_fields, "default_phone", g_strdup (value));
+	}
+
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "fax");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if(value)
+			g_hash_table_insert (simple_fields, "phone_Fax", g_strdup (value));
+	}
+
+	subparam = soup_soap_parameter_get_first_child_by_name (param, "address");
+	if (subparam) {
+		address = g_new0 (PostalAddress, 1);
+		set_postal_address_from_soap_parameter (address, subparam);
+		g_hash_table_insert (item->priv->addresses, "Office", address);
+		
+	}
+
+       	subparam = soup_soap_parameter_get_first_child_by_name (param, "website");
+	if(subparam) {
+		value = soup_soap_parameter_get_string_value (subparam);
+		if(value)
+			g_hash_table_insert (simple_fields, "website", g_strdup (value));
+	}
+
+
+}
+
+static void 
+append_postal_address_to_soap_message (SoupSoapMessage *msg, PostalAddress *address, char *address_type)
+{
+	soup_soap_message_start_element (msg, "address", NULL, NULL);
+	soup_soap_message_add_attribute (msg, "type", address_type, NULL, NULL);
+	if (address->street_address)
+		e_gw_message_write_string_parameter (msg, "streetAddress", NULL, address->street_address);
+	if (address->location)
+		e_gw_message_write_string_parameter (msg, "location", NULL, address->location);
+	if (address->city)
+		e_gw_message_write_string_parameter (msg, "city", NULL, address->city);
+	if (address->state)
+		e_gw_message_write_string_parameter (msg, "state", NULL, address->state);
+	if (address->postal_code)
+		e_gw_message_write_string_parameter (msg, "postalCode", NULL, address->postal_code);
+	if (address->country)
+		e_gw_message_write_string_parameter (msg, "country", NULL, address->country);
+	soup_soap_message_end_element(msg);
+
+}
+
+static void
+append_common_addressbook_item_fields_to_soup_message (EGwItem* item, SoupSoapMessage *msg)
+{
+	char * value;
+	GHashTable *simple_fields;
+
+	simple_fields = item->priv->simple_fields;
+	value = g_hash_table_lookup (simple_fields, "id");
+	
+	if (value)
+		e_gw_message_write_string_parameter (msg, "id", NULL, value);
+	
+	if (item->priv->container)
+		e_gw_message_write_string_parameter (msg, "container", NULL, item->priv->container);
+	value =  g_hash_table_lookup (simple_fields, "name");
+	if (value)
+		e_gw_message_write_string_parameter (msg, "name", NULL, value);
+	value = g_hash_table_lookup (simple_fields, "comment");
+	if(value) 
+		e_gw_message_write_string_parameter (msg, "comment", NULL, value);
+
+}
+
+static void
+append_contact_fields_to_soap_message (EGwItem *item, SoupSoapMessage *msg)
+{
+	char * value;
+	GHashTable *simple_fields;
+	GList *ims;
+	IMAddress *address;
+	GList *list;
+	FullName *full_name;
+	PostalAddress *postal_address;
+
+	
+	append_common_addressbook_item_fields_to_soup_message (item, msg);
+	simple_fields = item->priv->simple_fields;
+	soup_soap_message_start_element (msg, "fullName", NULL, NULL);
+	value =  g_hash_table_lookup (simple_fields, "name");
+	if (value)
+		e_gw_message_write_string_parameter (msg, "displayName", NULL, value);
+
+	full_name = item->priv->full_name;
+	if (full_name->name_prefix)
+		e_gw_message_write_string_parameter (msg, "namePrefix", NULL, full_name->name_prefix);
+	if (full_name->first_name)
+		e_gw_message_write_string_parameter (msg, "firstName", NULL, full_name->first_name);
+       	if (full_name->middle_name)
+		e_gw_message_write_string_parameter (msg, "middleName", NULL, full_name->middle_name);
+	if (full_name->last_name)
+		e_gw_message_write_string_parameter (msg, "lastName", NULL, full_name->last_name) ;
+	if (full_name->name_suffix)
+		e_gw_message_write_string_parameter (msg, "nameSuffix", NULL, full_name->first_name);
+	soup_soap_message_end_element (msg);
+
+	if(item->priv->email_list) {
+		
+		list = g_list_copy (item->priv->email_list);
+		soup_soap_message_start_element (msg, "emailList", NULL, NULL);
+		
+		soup_soap_message_add_attribute (msg, "primary", list->data, NULL, NULL);
+		for (; list != NULL; list = g_list_next (list)) 
+			if(list->data) 
+				e_gw_message_write_string_parameter (msg, "email", NULL, list->data);
+		g_list_free (list);
+		
+		soup_soap_message_end_element (msg);
+			
+		}
+	
+	if (item->priv->im_list) {
+		ims = g_list_copy (item->priv->im_list);
+		soup_soap_message_start_element (msg, "imList", NULL, NULL);
+		for (; ims != NULL; ims = g_list_next (ims)) {
+		       	soup_soap_message_start_element (msg, "im", NULL, NULL);
+			address = (IMAddress *) ims->data;
+			e_gw_message_write_string_parameter (msg, "service", NULL, address->service);
+			e_gw_message_write_string_parameter (msg, "address", NULL, address->address);
+			soup_soap_message_end_element (msg);
+		}
+		soup_soap_message_end_element (msg);
+		g_list_free (ims);	
+	}
+	
+	
+	soup_soap_message_start_element (msg, "phoneList", NULL, NULL);
+	value = g_hash_table_lookup (simple_fields, "default_phone");
+	if (value) 
+		soup_soap_message_add_attribute (msg, "default", value, NULL, NULL);
+	value = g_hash_table_lookup (simple_fields, "phone_Office");
+	if (value) 
+		e_gw_message_write_string_parameter_with_attribute (msg, "phone", NULL, value, "type", "Office");
+	value = g_hash_table_lookup (simple_fields, "phone_Home");
+	if (value) 
+		e_gw_message_write_string_parameter_with_attribute (msg, "phone", NULL, value, "type", "Home");
+	value = g_hash_table_lookup (simple_fields, "phone_Pager");
+	if (value) 
+		e_gw_message_write_string_parameter_with_attribute (msg, "phone", NULL, value, "type", "Pager");
+	value = g_hash_table_lookup (simple_fields, "phone_Mobile");
+	if (value) 
+		e_gw_message_write_string_parameter_with_attribute (msg, "phone", NULL, value, "type", "Mobile");
+	value = g_hash_table_lookup (simple_fields, "phone_Fax");
+	if (value) 
+		e_gw_message_write_string_parameter_with_attribute (msg, "phone", NULL, value, "type", "Fax");
+	soup_soap_message_end_element (msg);
+		
+	soup_soap_message_start_element (msg, "addressList", NULL, NULL);
+	postal_address = g_hash_table_lookup (item->priv->addresses, "Home");
+	if (postal_address)
+		append_postal_address_to_soap_message (msg, postal_address, "Home");
+	postal_address = g_hash_table_lookup (item->priv->addresses, "Office");
+	if (postal_address)
+		append_postal_address_to_soap_message (msg, postal_address, "Office");
+	
+	soup_soap_message_end_element (msg);
+	
+        soup_soap_message_start_element (msg, "officeInfo", NULL, NULL);
+	value = g_hash_table_lookup (simple_fields, "department");
+	if (value)
+		e_gw_message_write_string_parameter (msg, "department", NULL, value);
+	
+		value = g_hash_table_lookup (simple_fields, "title");
+	if (value)
+		e_gw_message_write_string_parameter (msg, "title", NULL, value);
+
+	value = g_hash_table_lookup (simple_fields, "website");
+	if (value)
+		e_gw_message_write_string_parameter (msg, "website", NULL, value);
+	soup_soap_message_end_element (msg);
+
+	soup_soap_message_start_element (msg, "personalInfo", NULL, NULL);
+	value =  g_hash_table_lookup (simple_fields, "birthday");
+	if(value)
+		e_gw_message_write_string_parameter (msg, "birthday", NULL, value);
+	value =  g_hash_table_lookup (simple_fields, "website");
+	if(value)
+		e_gw_message_write_string_parameter (msg, "website",NULL,  value);
+	
+	soup_soap_message_end_element (msg);
+	soup_soap_message_end_element(msg); 	
+	
+
+}
+
+static void 
+append_group_fields_to_soap_message (EGwItem *item, SoupSoapMessage *msg)
+{
+	char * value;
+	GHashTable *simple_fields;
+	GList *members;
+
+	append_common_addressbook_item_fields_to_soup_message (item, msg);
+	simple_fields = item->priv->simple_fields;
+	soup_soap_message_start_element (msg, "members", NULL, NULL);
+	members = g_list_copy (item->priv->member_list);
+	for (; members != NULL; members = g_list_next (members)) {
+		
+		soup_soap_message_start_element (msg, "member", NULL, NULL);
+		soup_soap_message_set_element_type (msg, "Contact");
+		e_gw_message_write_string_parameter (msg, "email", NULL, members->data);
+		e_gw_message_write_string_parameter (msg, "distType", NULL, "TO");
+		soup_soap_message_end_element(msg);
+
+	}
+	soup_soap_message_end_element (msg);
+	
+}
+
+
 EGwItem *
 e_gw_item_new_from_soap_parameter (const char *container, SoupSoapParameter *param)
 {
 	EGwItem *item;
-	char *item_type;
+        char *item_type;
 	SoupSoapParameter *subparam, *child;
 	
 	g_return_val_if_fail (param != NULL, NULL);
@@ -254,6 +948,31 @@
 		item->priv->item_type = E_GW_ITEM_TYPE_APPOINTMENT;
 	else if (!g_ascii_strcasecmp (item_type, "Task"))
 		item->priv->item_type = E_GW_ITEM_TYPE_TASK;
+	else if (!g_ascii_strcasecmp (item_type, "Contact") ) {
+		item->priv->item_type = E_GW_ITEM_TYPE_CONTACT;
+		set_contact_fields_from_soap_parameter (item, param);
+		return item;
+	} 
+	else if (!g_ascii_strcasecmp (item_type, "Organization")) {
+
+		item->priv->item_type =  E_GW_ITEM_TYPE_CONTACT;
+		set_organization_fields_from_soap_parameter (item, param);
+		return item;
+	}
+		
+	else if (!g_ascii_strcasecmp (item_type, "Resource")) {
+		
+		item->priv->item_type = E_GW_ITEM_TYPE_CONTACT;
+		set_resource_fields_from_soap_parameter (item, param);
+		return item;
+	}
+		 
+	else if (!g_ascii_strcasecmp (item_type, "Group")) {
+		item->priv->item_type = E_GW_ITEM_TYPE_GROUP;
+		set_contact_fields_from_soap_parameter (item, param);
+		return item;
+	}
+			
 	else {
 		g_free (item_type);
 		g_object_unref (item);
@@ -637,6 +1356,14 @@
 
 		e_gw_message_write_string_parameter (msg, "priority", NULL, priv->priority ? priv->priority : "");
 		break;
+	case E_GW_ITEM_TYPE_CONTACT :
+		soup_soap_message_add_attribute (msg, "type", "Contact", "xsi", NULL);
+		append_contact_fields_to_soap_message (item, msg);
+		return TRUE;
+        case E_GW_ITEM_TYPE_GROUP :
+		soup_soap_message_add_attribute (msg, "type", "Group", "xsi", NULL);
+		append_group_fields_to_soap_message (item, msg);
+		return TRUE;
 	default :
 		g_warning (G_STRLOC ": Unknown type for item");
 		return FALSE;


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