diff options
-rw-r--r-- | addressbook/ChangeLog | 41 | ||||
-rw-r--r-- | addressbook/backend/pas/pas-backend-file.c | 207 | ||||
-rw-r--r-- | addressbook/backend/pas/pas-backend-ldap.c | 282 | ||||
-rw-r--r-- | addressbook/backend/pas/pas-backend.c | 362 | ||||
-rw-r--r-- | addressbook/backend/pas/pas-backend.h | 62 |
5 files changed, 559 insertions, 395 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index da045a84db..87b410baf2 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,44 @@ +2002-01-08 Dan Winship <danw@ximian.com> + + Move PASBook request handling into PASBackend itself since all + existing backends do it exactly the same way. (Part of 32866). + + * backend/pas/pas-backend.h (PASBackendClass): add new methods for + the various pas book requests. + + * backend/pas/pas-backend.c: Add a clients list to + PASBackendPrivate. + (pas_backend_create_card, etc): Add these to invoke the new + methods. + (process_client_requests, book_destroy_cb): Moved here and + slightly rewritten from pas-backend-file. + (last_client_gone): Now static. + (add_client, remove_client): Default implementations, based on + pas-backend-file, that add the client to/remove it from the + backend's clients list and connect to its requests_queued signal. + (pas_backend_init, pas_backend_dispose): Deal with the clients + list. + + * backend/pas/pas-backend-file.c (struct _PASBackendFilePrivate): + Remove GList *clients. + (pas_backend_file_process_client_requests, + pas_backend_file_book_destroy_db, pas_backend_file_add_client, + pas_backend_file_remove_client): Gone. + (pas_backend_file_class_init): Remove add_client/remove_client + method initializations, add initializations for processing the + various book requests. + + * backend/pas/pas-backend-ldap.c (struct _PASBackendLDAPPrivate): + Remove GList *clients. + (pas_backend_ldap_process_create_card, etc): Make these take the + specific PAS*Request types rather than a generic PASRequest. + (pas_backend_ldap_process_client_requests, + pas_backend_ldap_book_destroy_db, pas_backend_ldap_add_client, + pas_backend_ldap_remove_client): Gone. + (pas_backend_ldap_class_init): Remove add_client/remove_client + method initializations, add initializations for processing the + various book requests. + 2003-01-07 Chris Toshok <toshok@ximian.com> * backend/pas/evolutionperson.schema: fix the SYNTAX for the diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c index c5c8251ad9..852352191d 100644 --- a/addressbook/backend/pas/pas-backend-file.c +++ b/addressbook/backend/pas/pas-backend-file.c @@ -51,13 +51,10 @@ typedef struct _PASBackendFileSearchContext PASBackendFileSearchContext; typedef struct _PasBackendFileChangeContext PASBackendFileChangeContext; struct _PASBackendFilePrivate { - GList *clients; - gboolean loaded; char *uri; char *filename; DB *file_db; EList *book_views; - gboolean writable; GHashTable *address_lists; PASBackendSummary *summary; }; @@ -349,9 +346,6 @@ pas_backend_file_search (PASBackendFile *bf, PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview; gboolean search_needed; - if (!bf->priv->loaded) - return; - search_needed = TRUE; if ( ! strcmp (view->search, "(contains \"x-evolution-any-field\" \"\")")) @@ -487,9 +481,6 @@ pas_backend_file_changes (PASBackendFile *bf, memset (&id_dbt, 0, sizeof (id_dbt)); memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - if (!bf->priv->loaded) - return; - /* Find the changed ids */ dirname = g_strdup (bf->priv->filename); slash = strrchr (dirname, '/'); @@ -991,8 +982,6 @@ pas_backend_file_process_get_book_view (PASBackend *backend, PASBackendFileBookView view; EIterator *iterator; - g_return_if_fail (req->listener != NULL); - bonobo_object_ref(BONOBO_OBJECT(book)); book_view = pas_book_view_new (req->listener); @@ -1013,6 +1002,9 @@ pas_backend_file_process_get_book_view (PASBackend *backend, : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */), book_view); + if (!pas_backend_is_loaded (backend)) + return; + iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_last(iterator); pas_backend_file_search (bf, book, e_iterator_get(iterator), FALSE); @@ -1029,8 +1021,6 @@ pas_backend_file_process_get_completion_view (PASBackend *backend, PASBackendFileBookView view; EIterator *iterator; - g_return_if_fail (req->listener != NULL); - bonobo_object_ref(BONOBO_OBJECT(book)); book_view = pas_book_view_new (req->listener); @@ -1051,6 +1041,9 @@ pas_backend_file_process_get_completion_view (PASBackend *backend, : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */), book_view); + if (!pas_backend_is_loaded (backend)) + return; + iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_last(iterator); pas_backend_file_search (bf, book, e_iterator_get(iterator), TRUE); @@ -1068,8 +1061,6 @@ pas_backend_file_process_get_changes (PASBackend *backend, PASBackendFileChangeContext ctx; EIterator *iterator; - g_return_if_fail (req->listener != NULL); - bonobo_object_ref(BONOBO_OBJECT(book)); book_view = pas_book_view_new (req->listener); @@ -1096,6 +1087,9 @@ pas_backend_file_process_get_changes (PASBackend *backend, e_list_append(bf->priv->book_views, &view); + if (!pas_backend_is_loaded (backend)) + return; + iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_last(iterator); pas_backend_file_changes (bf, book, e_iterator_get(iterator)); @@ -1156,75 +1150,6 @@ pas_backend_file_process_get_supported_fields (PASBackend *backend, fields); } -static void -pas_backend_file_process_client_requests (PASBook *book) -{ - PASBackend *backend; - PASRequest *req; - - backend = pas_book_get_backend (book); - - req = pas_book_pop_request (book); - if (req == NULL) - return; - - switch (req->op) { - case CreateCard: - pas_backend_file_process_create_card (backend, book, (PASCreateCardRequest*)req); - break; - - case RemoveCard: - pas_backend_file_process_remove_card (backend, book, (PASRemoveCardRequest*)req); - break; - - case ModifyCard: - pas_backend_file_process_modify_card (backend, book, (PASModifyCardRequest*)req); - break; - - case CheckConnection: - pas_backend_file_process_check_connection (backend, book, (PASCheckConnectionRequest*)req); - break; - - case GetVCard: - pas_backend_file_process_get_vcard (backend, book, (PASGetVCardRequest*)req); - break; - - case GetCursor: - pas_backend_file_process_get_cursor (backend, book, (PASGetCursorRequest*)req); - break; - - case GetBookView: - pas_backend_file_process_get_book_view (backend, book, (PASGetBookViewRequest*)req); - break; - - case GetCompletionView: - pas_backend_file_process_get_completion_view (backend, book, (PASGetCompletionViewRequest*)req); - break; - - case GetChanges: - pas_backend_file_process_get_changes (backend, book, (PASGetChangesRequest*)req); - break; - - case AuthenticateUser: - pas_backend_file_process_authenticate_user (backend, book, (PASAuthenticateUserRequest*)req); - break; - - case GetSupportedFields: - pas_backend_file_process_get_supported_fields (backend, book, (PASGetSupportedFieldsRequest*)req); - break; - } - - pas_book_free_request (req); -} - -static void -pas_backend_file_book_destroy_cb (gpointer data, GObject *where_book_was) -{ - PASBackendFile *backend = PAS_BACKEND_FILE (data); - - pas_backend_remove_client (PAS_BACKEND (backend), (PASBook*)where_book_was); -} - /* ** versions: ** @@ -1377,8 +1302,6 @@ pas_backend_file_load_uri (PASBackend *backend, struct stat sb; char *summary_filename; - g_assert (bf->priv->loaded == FALSE); - db_version (&major, &minor, &patch); if (major != 3 || @@ -1445,14 +1368,9 @@ pas_backend_file_load_uri (PASBackend *backend, return GNOME_Evolution_Addressbook_BookListener_OtherError; } - bf->priv->writable = writable; - - if (pas_backend_file_maybe_upgrade_db (bf)) - bf->priv->loaded = TRUE; - else { + if (!pas_backend_file_maybe_upgrade_db (bf)) { db->close (db, 0); bf->priv->file_db = NULL; - bf->priv->writable = FALSE; return GNOME_Evolution_Addressbook_BookListener_OtherError; } @@ -1465,7 +1383,6 @@ pas_backend_file_load_uri (PASBackend *backend, if (stat (bf->priv->filename, &sb) == -1) { db->close (db, 0); bf->priv->file_db = NULL; - bf->priv->writable = FALSE; return GNOME_Evolution_Addressbook_BookListener_OtherError; } db_mtime = sb.st_mtime; @@ -1479,6 +1396,8 @@ pas_backend_file_load_uri (PASBackend *backend, build_summary (bf->priv); } + pas_backend_set_is_loaded (backend, TRUE); + pas_backend_set_is_writable (backend, writable); return GNOME_Evolution_Addressbook_BookListener_Success; } @@ -1490,96 +1409,13 @@ pas_backend_file_get_uri (PASBackend *backend) bf = PAS_BACKEND_FILE (backend); - g_return_val_if_fail (bf->priv->loaded, NULL); g_assert (bf->priv->uri != NULL); return bf->priv->uri; } -static gboolean -pas_backend_file_add_client (PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBackendFile *bf; - PASBook *book; - - g_assert (backend != NULL); - g_assert (PAS_IS_BACKEND_FILE (backend)); - - bf = PAS_BACKEND_FILE (backend); - - book = pas_book_new (backend, listener); - - if (!book) { - if (!bf->priv->clients) - pas_backend_last_client_gone (backend); - - return FALSE; - } - - g_object_weak_ref (G_OBJECT (book), pas_backend_file_book_destroy_cb, backend); - - g_signal_connect (book, "requests_queued", - G_CALLBACK (pas_backend_file_process_client_requests), NULL); - - bf->priv->clients = g_list_prepend ( - bf->priv->clients, book); - - if (bf->priv->loaded) { - pas_book_respond_open ( - book, GNOME_Evolution_Addressbook_BookListener_Success); - if (bf->priv->writable) - pas_book_report_writable (book, bf->priv->writable); - } else { - pas_book_respond_open ( - book, GNOME_Evolution_Addressbook_BookListener_OtherError); - } - - bonobo_object_unref (BONOBO_OBJECT (book)); - - return TRUE; -} - -static void -pas_backend_file_remove_client (PASBackend *backend, - PASBook *book) -{ - PASBackendFile *bf; - GList *l; - PASBook *lbook; - - g_return_if_fail (backend != NULL); - g_return_if_fail (PAS_IS_BACKEND_FILE (backend)); - g_return_if_fail (book != NULL); - g_return_if_fail (PAS_IS_BOOK (book)); - - bf = PAS_BACKEND_FILE (backend); - - /* Find the book in the list of clients */ - - for (l = bf->priv->clients; l; l = l->next) { - lbook = PAS_BOOK (l->data); - - if (lbook == book) - break; - } - - g_assert (l != NULL); - - /* Disconnect */ - - bf->priv->clients = g_list_remove_link (bf->priv->clients, l); - g_list_free_1 (l); - - /* When all clients go away, notify the parent factory about it so that - * it may decide whether to kill the backend or not. - */ - if (!bf->priv->clients) - pas_backend_last_client_gone (backend); -} - static char * -pas_backend_file_get_static_capabilities (PASBackend *backend) +pas_backend_file_get_static_capabilities (PASBackend *backend) { return g_strdup("local,do-initial-query,cache-completions"); } @@ -1648,10 +1484,20 @@ pas_backend_file_class_init (PASBackendFileClass *klass) /* Set the virtual methods. */ parent_class->load_uri = pas_backend_file_load_uri; parent_class->get_uri = pas_backend_file_get_uri; - parent_class->add_client = pas_backend_file_add_client; - parent_class->remove_client = pas_backend_file_remove_client; parent_class->get_static_capabilities = pas_backend_file_get_static_capabilities; + parent_class->create_card = pas_backend_file_process_create_card; + parent_class->remove_card = pas_backend_file_process_remove_card; + parent_class->modify_card = pas_backend_file_process_modify_card; + parent_class->check_connection = pas_backend_file_process_check_connection; + parent_class->get_vcard = pas_backend_file_process_get_vcard; + parent_class->get_cursor = pas_backend_file_process_get_cursor; + parent_class->get_book_view = pas_backend_file_process_get_book_view; + parent_class->get_completion_view = pas_backend_file_process_get_completion_view; + parent_class->get_changes = pas_backend_file_process_get_changes; + parent_class->authenticate_user = pas_backend_file_process_authenticate_user; + parent_class->get_supported_fields = pas_backend_file_process_get_supported_fields; + object_class->dispose = pas_backend_file_dispose; } @@ -1661,11 +1507,8 @@ pas_backend_file_init (PASBackendFile *backend) PASBackendFilePrivate *priv; priv = g_new0 (PASBackendFilePrivate, 1); - priv->loaded = FALSE; - priv->clients = NULL; priv->book_views = e_list_new((EListCopyFunc) pas_backend_file_book_view_copy, (EListFreeFunc) pas_backend_file_book_view_free, NULL); priv->uri = NULL; - priv->writable = FALSE; backend->priv = priv; } diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c index c09495fb22..0a609450ab 100644 --- a/addressbook/backend/pas/pas-backend-ldap.c +++ b/addressbook/backend/pas/pas-backend-ldap.c @@ -85,7 +85,6 @@ typedef struct LDAPOp LDAPOp; struct _PASBackendLDAPPrivate { char *uri; gboolean connected; - GList *clients; gchar *ldap_host; /* the hostname of the server */ int ldap_port; /* the port of the server */ @@ -117,8 +116,6 @@ struct _PASBackendLDAPPrivate { gboolean calEntrySupported; gboolean evolutionPersonChecked; - gboolean writable; - /* our operations */ GHashTable *id_to_op; int active_ops; @@ -485,7 +482,7 @@ check_schema_support (PASBackendLDAP *bl) of draconian acl's that keep subschema reads from working until the user is authed. */ - if (!bl->priv->writable) { + if (!pas_backend_is_writable (PAS_BACKEND (bl)) { g_warning ("subschema read returned nothing before successful auth"); bl->priv->evolutionPersonChecked = FALSE; } @@ -691,6 +688,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl) if (!bl->priv->evolutionPersonChecked) check_schema_support (bl); + pas_backend_set_is_loaded (PAS_BACKEND (bl), TRUE); return GNOME_Evolution_Addressbook_BookListener_Success; } else @@ -1167,7 +1165,7 @@ create_card_dtor (LDAPOp *op) static void pas_backend_ldap_process_create_card (PASBackend *backend, PASBook *book, - PASRequest *req) + PASCreateCardRequest *req) { LDAPCreateOp *create_op = g_new (LDAPCreateOp, 1); PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); @@ -1182,9 +1180,9 @@ pas_backend_ldap_process_create_card (PASBackend *backend, book_view = find_book_view (bl); - printf ("vcard = %s\n", req->create.vcard); + printf ("vcard = %s\n", req->vcard); - new_ecard = e_card_new (req->create.vcard); + new_ecard = e_card_new (req->vcard); create_op->new_card = e_card_simple_new (new_ecard); create_op->dn = create_dn_from_ecard (create_op->new_card, bl->priv->ldap_rootdn); @@ -1350,7 +1348,7 @@ remove_card_dtor (LDAPOp *op) static void pas_backend_ldap_process_remove_card (PASBackend *backend, PASBook *book, - PASRequest *req) + PASRemoveCardRequest *req) { LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1); PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); @@ -1360,7 +1358,7 @@ pas_backend_ldap_process_remove_card (PASBackend *backend, book_view = find_book_view (bl); - remove_op->id = g_strdup (req->remove.id); + remove_op->id = g_strdup (req->id); do { book_view_notify_status (book_view, _("Removing card from LDAP server...")); @@ -1579,7 +1577,7 @@ modify_card_dtor (LDAPOp *op) static void pas_backend_ldap_process_modify_card (PASBackend *backend, PASBook *book, - PASRequest *req) + PASModifyCardRequest *req) { LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1); PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); @@ -1591,7 +1589,7 @@ pas_backend_ldap_process_modify_card (PASBackend *backend, book_view = find_book_view (bl); - modify_op->vcard = g_strdup (req->modify.vcard); + modify_op->vcard = g_strdup (req->vcard); new_ecard = e_card_new (modify_op->vcard); modify_op->card = e_card_simple_new (new_ecard); g_object_unref (new_ecard); @@ -1691,7 +1689,7 @@ get_vcard_dtor (LDAPOp *op) static void pas_backend_ldap_process_get_vcard (PASBackend *backend, PASBook *book, - PASRequest *req) + PASGetVCardRequest *req) { LDAPGetVCardOp *get_vcard_op = g_new0 (LDAPGetVCardOp, 1); PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); @@ -1703,7 +1701,7 @@ pas_backend_ldap_process_get_vcard (PASBackend *backend, book_view = find_book_view (bl); do { - ldap_error = ldap_search_ext (ldap, req->get_vcard.id, + ldap_error = ldap_search_ext (ldap, req->id, LDAP_SCOPE_BASE, "(objectclass=*)", NULL, 0, NULL, NULL, @@ -1851,7 +1849,7 @@ get_cursor_dtor (LDAPOp *op) static void pas_backend_ldap_process_get_cursor (PASBackend *backend, PASBook *book, - PASRequest *req) + PASGetCursorRequest *req) { PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); LDAP *ldap = bl->priv->ldap; @@ -2743,7 +2741,7 @@ build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasse struct prop_info *info = NULL; char **values; - if (existing_objectclasses && !strcasecmp (attr, "objectclass")) { + if (existing_objectclasses && !g_ascii_strcasecmp (attr, "objectclass")) { values = ldap_get_values (ldap, e, attr); for (i = 0; values[i]; i ++) *existing_objectclasses = g_list_append (*existing_objectclasses, g_strdup (values[i])); @@ -3056,33 +3054,27 @@ pas_backend_ldap_search (PASBackendLDAP *bl, } static void -pas_backend_ldap_process_get_book_view (PASBackend *backend, - PASBook *book, - PASRequest *req) +ldap_get_view (PASBackend *backend, + PASBook *book, + const char *search, + GNOME_Evolution_Addressbook_BookViewListener listener, + int limit) { PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); PASBookView *book_view; PASBackendLDAPBookView *view; - g_return_if_fail (req->get_book_view.listener != NULL); - - book_view = pas_book_view_new (req->get_book_view.listener); + book_view = pas_book_view_new (listener); bonobo_object_ref(BONOBO_OBJECT(book)); g_object_weak_ref (G_OBJECT (book_view), view_destroy, book); view = g_new0(PASBackendLDAPBookView, 1); view->book_view = book_view; - view->search = g_strdup(req->get_book_view.search); + view->search = g_strdup(search); view->card_sexp = pas_backend_card_sexp_new (view->search); view->blpriv = bl->priv; - - if (req->op == GetCompletionView) { - view->limit = MIN (bl->priv->ldap_limit, 100); - } - else { - view->limit = bl->priv->ldap_limit; - } + view->limit = limit; e_list_append(bl->priv->book_views, view); @@ -3098,9 +3090,39 @@ pas_backend_ldap_process_get_book_view (PASBackend *backend, } static void +pas_backend_ldap_process_get_book_view (PASBackend *backend, + PASBook *book, + PASGetBookViewRequest *req) +{ + PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); + + ldap_get_view (backend, book, req->search, req->listener, + bl->priv->ldap_limit); +} + +static void +pas_backend_ldap_process_get_completion_view (PASBackend *backend, + PASBook *book, + PASGetCompletionViewRequest *req) +{ + PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); + + ldap_get_view (backend, book, req->search, req->listener, + MIN (bl->priv->ldap_limit, 100)); +} + +static void +pas_backend_ldap_process_get_changes (PASBackend *backend, + PASBook *book, + PASGetChangesRequest *req) +{ + /* FIXME: implement */ +} + +static void pas_backend_ldap_process_check_connection (PASBackend *backend, PASBook *book, - PASRequest *req) + PASCheckConnectionRequest *req) { PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); @@ -3110,15 +3132,15 @@ pas_backend_ldap_process_check_connection (PASBackend *backend, static void pas_backend_ldap_process_authenticate_user (PASBackend *backend, PASBook *book, - PASRequest *req) + PASAuthenticateUserRequest *req) { PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); int ldap_error; char *dn = NULL; - if (!strcmp (req->auth_user.auth_method, "ldap/simple-email")) { + if (!strcmp (req->auth_method, "ldap/simple-email")) { LDAPMessage *res, *e; - char *query = g_strdup_printf ("(mail=%s)", req->auth_user.user); + char *query = g_strdup_printf ("(mail=%s)", req->user); ldap_error = ldap_search_s (bl->priv->ldap, bl->priv->ldap_rootdn, @@ -3144,46 +3166,49 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend, return; } } - else if (!strcmp (req->auth_user.auth_method, "ldap/simple-binddn")) { - dn = g_strdup (req->auth_user.user); + else if (!strcmp (req->auth_method, "ldap/simple-binddn")) { + dn = g_strdup (req->user); } /* now authenticate against the DN we were either supplied or queried for */ printf ("authenticating as %s\n", dn); ldap_error = ldap_simple_bind_s(bl->priv->ldap, dn, - req->auth_user.passwd); + req->passwd); bl->priv->auth_dn = dn; - bl->priv->auth_passwd = g_strdup (req->auth_user.passwd); + bl->priv->auth_passwd = g_strdup (req->passwd); pas_book_respond_authenticate_user (book, ldap_error_to_response (ldap_error)); - bl->priv->writable = (ldap_error == LDAP_SUCCESS); - - /* if the bind was successful we force a requery on the root - dse since some ldap servers are set up such that they don't - report anything (including the schema DN) until the user is - authenticated */ - if (!bl->priv->evolutionPersonChecked && ldap_error == LDAP_SUCCESS) { - ldap_error = query_ldap_root_dse (bl); - - if (LDAP_SUCCESS == ldap_error) { - if (!bl->priv->evolutionPersonChecked) - check_schema_support (bl); + if (ldap_error == LDAP_SUCCESS) { + pas_backend_set_writable (backend, TRUE); + + /* force a requery on the root dse since some ldap + servers are set up such that they don't report + anything (including the schema DN) until the user + is authenticated */ + if (!bl->priv->evolutionPersonChecked) { + ldap_error = query_ldap_root_dse (bl); + + if (LDAP_SUCCESS == ldap_error) { + if (!bl->priv->evolutionPersonChecked) + check_schema_support (bl); + } + else + g_warning ("Failed to perform root dse query after authenticating, (ldap_error 0x%02x)", ldap_error); } - else - g_warning ("Failed to perform root dse query after authenticating, (ldap_error 0x%02x)", ldap_error); + + pas_book_report_writable (book, TRUE); } - pas_book_report_writable (book, bl->priv->writable); } static void pas_backend_ldap_process_get_supported_fields (PASBackend *backend, PASBook *book, - PASRequest *req) + PASGetSupportedFieldsRequest *req) { PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); @@ -3193,76 +3218,6 @@ pas_backend_ldap_process_get_supported_fields (PASBackend *backend, bl->priv->supported_fields); } -static void -pas_backend_ldap_process_client_requests (PASBook *book) -{ - PASBackend *backend; - PASRequest *req; - - backend = pas_book_get_backend (book); - - req = pas_book_pop_request (book); - if (req == NULL) - return; - - switch (req->op) { - case CreateCard: - pas_backend_ldap_process_create_card (backend, book, req); - break; - - case RemoveCard: - pas_backend_ldap_process_remove_card (backend, book, req); - break; - - case ModifyCard: - pas_backend_ldap_process_modify_card (backend, book, req); - break; - - case CheckConnection: - pas_backend_ldap_process_check_connection (backend, book, req); - break; - - case GetVCard: - pas_backend_ldap_process_get_vcard (backend, book, req); - break; - - case GetCursor: - pas_backend_ldap_process_get_cursor (backend, book, req); - break; - - case GetBookView: - pas_backend_ldap_process_get_book_view (backend, book, req); - break; - - case GetCompletionView: - /* we don't support summaries so completion view requests are the same as book view requests */ - pas_backend_ldap_process_get_book_view (backend, book, req); - break; - - case GetChanges: - /* FIXME: Code this. */ - break; - - case AuthenticateUser: - pas_backend_ldap_process_authenticate_user (backend, book, req); - break; - - case GetSupportedFields: - pas_backend_ldap_process_get_supported_fields (backend, book, req); - break; - } - - pas_book_free_request (req); -} - -static void -pas_backend_ldap_book_destroy_cb (gpointer data, GObject *where_book_was) -{ - PASBackendLDAP *backend = PAS_BACKEND_LDAP (data); - - pas_backend_remove_client (PAS_BACKEND (backend), (PASBook*)where_book_was); -} - static GNOME_Evolution_Addressbook_BookListener_CallStatus pas_backend_ldap_load_uri (PASBackend *backend, const char *uri) @@ -3354,73 +3309,6 @@ pas_backend_ldap_get_uri (PASBackend *backend) return bl->priv->uri; } -static gboolean -pas_backend_ldap_add_client (PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBackendLDAP *bl; - PASBook *book; - - g_assert (backend != NULL); - g_assert (PAS_IS_BACKEND_LDAP (backend)); - - bl = PAS_BACKEND_LDAP (backend); - - book = pas_book_new (backend, listener); - - if (!book) { - if (!bl->priv->clients) - pas_backend_last_client_gone (backend); - - return FALSE; - } - - g_object_weak_ref (G_OBJECT (book), pas_backend_ldap_book_destroy_cb, backend); - - g_signal_connect (book, "requests_queued", - G_CALLBACK (pas_backend_ldap_process_client_requests), NULL); - - bl->priv->clients = g_list_prepend ( - bl->priv->clients, book); - - if (bl->priv->connected) { - pas_book_respond_open ( - book, GNOME_Evolution_Addressbook_BookListener_Success); - } else { - pas_book_respond_open ( - book, GNOME_Evolution_Addressbook_BookListener_OtherError); - } - - pas_book_report_writable (book, bl->priv->writable); - - bonobo_object_unref (BONOBO_OBJECT (book)); - - return TRUE; -} - -static void -pas_backend_ldap_remove_client (PASBackend *backend, - PASBook *book) -{ - PASBackendLDAP *bl; - - g_return_if_fail (backend != NULL); - g_return_if_fail (PAS_IS_BACKEND_LDAP (backend)); - g_return_if_fail (book != NULL); - g_return_if_fail (PAS_IS_BOOK (book)); - - bl = PAS_BACKEND_LDAP (backend); - - /* Disconnect */ - bl->priv->clients = g_list_remove (bl->priv->clients, book); - - /* When all clients go away, notify the parent factory about it so that - * it may decide whether to kill the backend or not. - */ - if (!bl->priv->clients) - pas_backend_last_client_gone (backend); -} - static char * pas_backend_ldap_get_static_capabilities (PASBackend *backend) { @@ -3515,10 +3403,20 @@ pas_backend_ldap_class_init (PASBackendLDAPClass *klass) /* Set the virtual methods. */ parent_class->load_uri = pas_backend_ldap_load_uri; parent_class->get_uri = pas_backend_ldap_get_uri; - parent_class->add_client = pas_backend_ldap_add_client; - parent_class->remove_client = pas_backend_ldap_remove_client; parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities; + parent_class->create_card = pas_backend_ldap_process_create_card; + parent_class->remove_card = pas_backend_ldap_process_remove_card; + parent_class->modify_card = pas_backend_ldap_process_modify_card; + parent_class->check_connection = pas_backend_ldap_process_check_connection; + parent_class->get_vcard = pas_backend_ldap_process_get_vcard; + parent_class->get_cursor = pas_backend_ldap_process_get_cursor; + parent_class->get_book_view = pas_backend_ldap_process_get_book_view; + parent_class->get_completion_view = pas_backend_ldap_process_get_completion_view; + parent_class->get_changes = pas_backend_ldap_process_get_changes; + parent_class->authenticate_user = pas_backend_ldap_process_authenticate_user; + parent_class->get_supported_fields = pas_backend_ldap_process_get_supported_fields; + object_class->dispose = pas_backend_ldap_dispose; } diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c index 6d64ba938b..513632c909 100644 --- a/addressbook/backend/pas/pas-backend.c +++ b/addressbook/backend/pas/pas-backend.c @@ -10,6 +10,11 @@ #include "pas-backend.h" #include "pas-marshal.h" +struct _PASBackendPrivate { + GList *clients; + gboolean loaded, writable; +}; + /* Signal IDs */ enum { LAST_CLIENT_GONE, @@ -18,6 +23,7 @@ enum { static guint pas_backend_signals[LAST_SIGNAL]; +static GObjectClass *parent_class; gboolean pas_backend_construct (PASBackend *backend) @@ -32,6 +38,7 @@ pas_backend_load_uri (PASBackend *backend, g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (backend->priv->loaded == FALSE, FALSE); g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri != NULL); @@ -51,12 +58,279 @@ pas_backend_get_uri (PASBackend *backend) { g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL); + g_return_val_if_fail (backend->priv->loaded, NULL); g_assert (PAS_BACKEND_GET_CLASS (backend)->get_uri != NULL); return (* PAS_BACKEND_GET_CLASS (backend)->get_uri) (backend); } + +void +pas_backend_create_card (PASBackend *backend, + PASBook *book, + PASCreateCardRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->vcard != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->create_card != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->create_card) (backend, book, req); +} + +void +pas_backend_remove_card (PASBackend *backend, + PASBook *book, + PASRemoveCardRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->id != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_card != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->remove_card) (backend, book, req); +} + +void +pas_backend_modify_card (PASBackend *backend, + PASBook *book, + PASModifyCardRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->vcard != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_card != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->modify_card) (backend, book, req); +} + +void +pas_backend_check_connection (PASBackend *backend, + PASBook *book, + PASCheckConnectionRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->check_connection != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->check_connection) (backend, book, req); +} + +void +pas_backend_get_vcard (PASBackend *backend, + PASBook *book, + PASGetVCardRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->id != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->get_vcard != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->get_vcard) (backend, book, req); +} + +void +pas_backend_get_cursor (PASBackend *backend, + PASBook *book, + PASGetCursorRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->search != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->get_cursor != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->get_cursor) (backend, book, req); +} + +void +pas_backend_get_book_view (PASBackend *backend, + PASBook *book, + PASGetBookViewRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->get_book_view != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->get_book_view) (backend, book, req); +} + +void +pas_backend_get_completion_view (PASBackend *backend, + PASBook *book, + PASGetCompletionViewRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->get_completion_view != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->get_completion_view) (backend, book, req); +} + +void +pas_backend_get_changes (PASBackend *backend, + PASBook *book, + PASGetChangesRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL && req->change_id != NULL && req->listener != CORBA_OBJECT_NIL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, req); +} + +void +pas_backend_authenticate_user (PASBackend *backend, + PASBook *book, + PASAuthenticateUserRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, req); +} + +void +pas_backend_get_supported_fields (PASBackend *backend, + PASBook *book, + PASGetSupportedFieldsRequest *req) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + g_return_if_fail (PAS_IS_BOOK (book)); + g_return_if_fail (req != NULL); + + g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields != NULL); + + return (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book, req); +} + +static void +process_client_requests (PASBook *book, gpointer user_data) +{ + PASBackend *backend; + PASRequest *req; + + backend = PAS_BACKEND (user_data); + + req = pas_book_pop_request (book); + if (req == NULL) + return; + + switch (req->op) { + case CreateCard: + pas_backend_create_card (backend, book, &req->create); + break; + + case RemoveCard: + pas_backend_remove_card (backend, book, &req->remove); + break; + + case ModifyCard: + pas_backend_modify_card (backend, book, &req->modify); + break; + + case CheckConnection: + pas_backend_check_connection (backend, book, &req->check_connection); + break; + + case GetVCard: + pas_backend_get_vcard (backend, book, &req->get_vcard); + break; + + case GetCursor: + pas_backend_get_cursor (backend, book, &req->get_cursor); + break; + + case GetBookView: + pas_backend_get_book_view (backend, book, &req->get_book_view); + break; + + case GetCompletionView: + pas_backend_get_completion_view (backend, book, &req->get_completion_view); + break; + + case GetChanges: + pas_backend_get_changes (backend, book, &req->get_changes); + break; + + case AuthenticateUser: + pas_backend_authenticate_user (backend, book, &req->auth_user); + break; + + case GetSupportedFields: + pas_backend_get_supported_fields (backend, book, &req->get_supported_fields); + break; + } + + pas_book_free_request (req); +} + +static void +book_destroy_cb (gpointer data, GObject *where_book_was) +{ + PASBackend *backend = PAS_BACKEND (data); + + pas_backend_remove_client (backend, (PASBook *)where_book_was); +} + +static void +last_client_gone (PASBackend *backend) +{ + g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0); +} + +static gboolean +add_client (PASBackend *backend, + GNOME_Evolution_Addressbook_BookListener listener) +{ + PASBook *book; + + book = pas_book_new (backend, listener); + if (!book) { + if (!backend->priv->clients) + last_client_gone (backend); + + return FALSE; + } + + g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend); + + g_signal_connect (book, "requests_queued", + G_CALLBACK (process_client_requests), backend); + + backend->priv->clients = g_list_prepend (backend->priv->clients, book); + + if (backend->priv->loaded) { + pas_book_respond_open ( + book, GNOME_Evolution_Addressbook_BookListener_Success); + } else { + pas_book_respond_open ( + book, GNOME_Evolution_Addressbook_BookListener_OtherError); + } + + pas_book_report_writable (book, backend->priv->writable); + + bonobo_object_unref (BONOBO_OBJECT (book)); + + return TRUE; +} + /** * pas_backend_add_client: * @backend: An addressbook backend. @@ -67,10 +341,9 @@ pas_backend_get_uri (PASBackend *backend) * Return value: TRUE on success, FALSE on failure to add the client. */ gboolean -pas_backend_add_client (PASBackend *backend, +pas_backend_add_client (PASBackend *backend, GNOME_Evolution_Addressbook_BookListener listener) { - g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); g_return_val_if_fail (listener != CORBA_OBJECT_NIL, FALSE); @@ -79,13 +352,25 @@ pas_backend_add_client (PASBackend *backend, return PAS_BACKEND_GET_CLASS (backend)->add_client (backend, listener); } +static void +remove_client (PASBackend *backend, + PASBook *book) +{ + /* Disconnect */ + backend->priv->clients = g_list_remove (backend->priv->clients, book); + + /* When all clients go away, notify the parent factory about it so that + * it may decide whether to kill the backend or not. + */ + if (!backend->priv->clients) + last_client_gone (backend); +} + void pas_backend_remove_client (PASBackend *backend, PASBook *book) { - g_return_if_fail (backend != NULL); g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (book != NULL); g_return_if_fail (PAS_IS_BOOK (book)); g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_client != NULL); @@ -104,26 +389,64 @@ pas_backend_get_static_capabilities (PASBackend *backend) return PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities (backend); } -/** - * pas_backend_last_client_gone: - * @backend: An addressbook backend. - * - * Emits the "last_client_gone" signal for the specified backend. Should - * only be called from backend implementations if the backend really does - * not have any more clients. - **/ +gboolean +pas_backend_is_loaded (PASBackend *backend) +{ + g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); + + return backend->priv->loaded; +} + void -pas_backend_last_client_gone (PASBackend *backend) +pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded) { - g_return_if_fail (backend != NULL); g_return_if_fail (PAS_IS_BACKEND (backend)); - g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0); + backend->priv->loaded = is_loaded; +} + +gboolean +pas_backend_is_writable (PASBackend *backend) +{ + g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); + + return backend->priv->writable; +} + +void +pas_backend_set_is_writable (PASBackend *backend, gboolean is_writable) +{ + g_return_if_fail (PAS_IS_BACKEND (backend)); + + backend->priv->writable = is_writable; } static void pas_backend_init (PASBackend *backend) { + PASBackendPrivate *priv; + + priv = g_new0 (PASBackendPrivate, 1); + priv->clients = NULL; + + backend->priv = priv; +} + +static void +pas_backend_dispose (GObject *object) +{ + PASBackend *backend; + + backend = PAS_BACKEND (object); + + if (backend->priv) { + g_list_free (backend->priv->clients); + g_free (backend->priv); + + backend->priv = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); } static void @@ -131,11 +454,14 @@ pas_backend_class_init (PASBackendClass *klass) { GObjectClass *object_class; + parent_class = g_type_class_peek_parent (klass); + object_class = (GObjectClass *) klass; - klass->add_client = NULL; - klass->remove_client = NULL; - klass->get_static_capabilities = NULL; + klass->add_client = add_client; + klass->remove_client = remove_client; + + object_class->dispose = pas_backend_dispose; pas_backend_signals[LAST_CLIENT_GONE] = g_signal_new ("last_client_gone", diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h index d1d5705b0f..8c3cab2c60 100644 --- a/addressbook/backend/pas/pas-backend.h +++ b/addressbook/backend/pas/pas-backend.h @@ -53,6 +53,18 @@ typedef struct { void (*remove_client) (PASBackend *backend, PASBook *book); char *(*get_static_capabilities) (PASBackend *backend); + void (*create_card) (PASBackend *backend, PASBook *book, PASCreateCardRequest *req); + void (*remove_card) (PASBackend *backend, PASBook *book, PASRemoveCardRequest *req); + void (*modify_card) (PASBackend *backend, PASBook *book, PASModifyCardRequest *req); + void (*check_connection) (PASBackend *backend, PASBook *book, PASCheckConnectionRequest *req); + void (*get_vcard) (PASBackend *backend, PASBook *book, PASGetVCardRequest *req); + void (*get_cursor) (PASBackend *backend, PASBook *book, PASGetCursorRequest *req); + void (*get_book_view) (PASBackend *backend, PASBook *book, PASGetBookViewRequest *req); + void (*get_completion_view) (PASBackend *backend, PASBook *book, PASGetCompletionViewRequest *req); + void (*get_changes) (PASBackend *backend, PASBook *book, PASGetChangesRequest *req); + void (*authenticate_user) (PASBackend *backend, PASBook *book, PASAuthenticateUserRequest *req); + void (*get_supported_fields) (PASBackend *backend, PASBook *book, PASGetSupportedFieldsRequest *req); + /* Notification signals */ void (* last_client_gone) (PASBackend *backend); } PASBackendClass; @@ -72,9 +84,53 @@ void pas_backend_remove_client (PASBackend *backen PASBook *book); char *pas_backend_get_static_capabilities (PASBackend *backend); -void pas_backend_last_client_gone (PASBackend *backend); - -GType pas_backend_get_type (void); +gboolean pas_backend_is_loaded (PASBackend *backend); + +gboolean pas_backend_is_writable (PASBackend *backend); + +void pas_backend_create_card (PASBackend *backend, + PASBook *book, + PASCreateCardRequest *req); +void pas_backend_remove_card (PASBackend *backend, + PASBook *book, + PASRemoveCardRequest *req); +void pas_backend_modify_card (PASBackend *backend, + PASBook *book, + PASModifyCardRequest *req); +void pas_backend_check_connection (PASBackend *backend, + PASBook *book, + PASCheckConnectionRequest *req); +void pas_backend_get_vcard (PASBackend *backend, + PASBook *book, + PASGetVCardRequest *req); +void pas_backend_get_cursor (PASBackend *backend, + PASBook *book, + PASGetCursorRequest *req); +void pas_backend_get_book_view (PASBackend *backend, + PASBook *book, + PASGetBookViewRequest *req); +void pas_backend_get_completion_view (PASBackend *backend, + PASBook *book, + PASGetCompletionViewRequest *req); +void pas_backend_get_changes (PASBackend *backend, + PASBook *book, + PASGetChangesRequest *req); +void pas_backend_authenticate_user (PASBackend *backend, + PASBook *book, + PASAuthenticateUserRequest *req); +void pas_backend_get_supported_fields (PASBackend *backend, + PASBook *book, + PASGetSupportedFieldsRequest *req); + + +GType pas_backend_get_type (void); + + +/* protected functions for subclasses */ +void pas_backend_set_is_loaded (PASBackend *backend, + gboolean is_loaded); +void pas_backend_set_is_writable (PASBackend *backend, + gboolean is_writable); #endif /* ! __PAS_BACKEND_H__ */ |