From fd4379ff20fe9c9e3b4f4028095b9659687002ff Mon Sep 17 00:00:00 2001 From: Nat Friedman Date: Tue, 25 Jan 2000 05:28:18 +0000 Subject: More work. svn path=/trunk/; revision=1626 --- addressbook/backend/pas/Makefile.am | 29 +- addressbook/backend/pas/pas-backend-file.c | 272 ++++++++++++++ addressbook/backend/pas/pas-backend-file.h | 32 ++ addressbook/backend/pas/pas-backend.c | 96 ++--- addressbook/backend/pas/pas-backend.h | 41 +-- addressbook/backend/pas/pas-book-factory.c | 248 ++++++------- addressbook/backend/pas/pas-book-factory.h | 7 +- addressbook/backend/pas/pas-book.c | 573 +++++++++++++++++++++++++++++ addressbook/backend/pas/pas-book.h | 84 +++++ addressbook/backend/pas/pas.c | 54 +++ 10 files changed, 1203 insertions(+), 233 deletions(-) create mode 100644 addressbook/backend/pas/pas-backend-file.c create mode 100644 addressbook/backend/pas/pas-backend-file.h create mode 100644 addressbook/backend/pas/pas-book.c create mode 100644 addressbook/backend/pas/pas-book.h create mode 100644 addressbook/backend/pas/pas.c (limited to 'addressbook/backend/pas') diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am index 220888f431..36eeab0782 100644 --- a/addressbook/backend/pas/Makefile.am +++ b/addressbook/backend/pas/Makefile.am @@ -1,3 +1,6 @@ +bin_PROGRAMS = wombat +lib_LTLIBRARIES = libpas.la + corbadir = $(sysconfdir)/CORBA/servers CORBA_SOURCE = \ @@ -34,16 +37,36 @@ pas_libs = \ libpas.la \ $(gnome_libs) -lib_LTLIBRARIES = libpas.la libpas_la_SOURCES = \ $(CORBA_SOURCE) \ - pas-book-factory.c + pas-book.c \ + pas-book-factory.c \ + pas-backend.c \ + pas-backend-file.c libpasincludedir = $(includedir)/backend libpasinclude_HEADERS = \ - pas-book-factory.h + pas-book.h \ + pas-book-factory.h \ + pas-backend.h \ + pas-backend-file.h + +wombat_SOURCES = \ + pas.c + +wombat_LDADD = \ + $(GTK_LIBS) \ + $(GNOME_LIBDIR) \ + $(GNOMEGNORBA_LIBS) \ + $(INTLLIBS) \ + -lbonobo \ + $(pas_libs) + +gnorbadir = $(sysconfdir)/CORBA/servers +gnorba_DATA = wombat.gnorba BUILT_SOURCES = $(CORBA_SOURCE) CLEANFILES += $(BUILT_SOURCES) +EXTRA_DIST = $(gnorba_DATA) \ No newline at end of file diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c new file mode 100644 index 0000000000..f23b607efe --- /dev/null +++ b/addressbook/backend/pas/pas-backend-file.c @@ -0,0 +1,272 @@ +/* + * Author: + * Nat Friedman (nat@helixcode.com) + * + * Copyright 2000, Helix Code, Inc. + */ + +#include +#include + +#include +#include + +static PASBackendClass *pas_backend_file_parent_class; + +struct _PASBackendFilePrivate { + GList *clients; + gboolean loaded; +}; + +static void +pas_backend_file_process_create_card (PASBackend *backend, + PASBook *book, + PASRequest *req) +{ + pas_book_respond_create ( + book, Evolution_BookListener_Success); + + g_free (req->vcard); +} + +static void +pas_backend_file_process_remove_card (PASBackend *backend, + PASBook *book, + PASRequest *req) +{ + pas_book_respond_remove ( + book, Evolution_BookListener_Success); + + g_free (req->id); +} + +static void +pas_backend_file_process_modify_card (PASBackend *backend, + PASBook *book, + PASRequest *req) +{ + pas_book_respond_modify ( + book, Evolution_BookListener_Success); + + g_free (req->vcard); +} + +static void +pas_backend_file_process_check_connection (PASBackend *backend, + PASBook *book, + PASRequest *req) +{ + pas_book_report_connection (book, TRUE); +} + +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, req); + break; + + case RemoveCard: + pas_backend_file_process_remove_card (backend, book, req); + break; + + case ModifyCard: + pas_backend_file_process_modify_card (backend, book, req); + + case CheckConnection: + pas_backend_file_process_check_connection (backend, book, req); + break; + } + + g_free (req); +} + +static void +pas_backend_file_book_destroy_cb (PASBook *book) +{ + PASBackendFile *backend; + + backend = PAS_BACKEND_FILE (pas_book_get_backend (book)); + + pas_backend_remove_client (PAS_BACKEND (backend), book); +} + +static char * +pas_backend_file_get_vcard (PASBook *book, const char *id) +{ + return g_strdup ("blah blah blah"); +} + +static char * +pas_backend_file_extract_path_from_uri (const char *uri) +{ + g_assert (strncasecmp (uri, "file:", 5) == 0); + + return g_strdup (uri + 5); +} + +static void +pas_backend_file_load_uri (PASBackend *backend, + const char *uri) +{ + PASBackendFile *bf = PAS_BACKEND_FILE (backend); + char *filename; + + g_assert (PAS_BACKEND_FILE (backend)->priv->loaded == FALSE); + + filename = pas_backend_file_extract_path_from_uri (uri); +} + +static void +pas_backend_file_add_client (PASBackend *backend, + Evolution_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, + pas_backend_file_get_vcard); + + g_assert (book != NULL); + + gtk_signal_connect (GTK_OBJECT (book), "destroy", + pas_backend_file_book_destroy_cb, NULL); + + gtk_signal_connect (GTK_OBJECT (book), "requests_queued", + 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, Evolution_BookListener_Success); + } else { + /* Open the book. */ + pas_book_respond_open ( + book, Evolution_BookListener_Success); + } +} + +static void +pas_backend_file_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_warning ("pas_backend_file_remove_client: Unimplemented!\n"); +} + +static gboolean +pas_backend_file_construct (PASBackendFile *backend) +{ + g_assert (backend != NULL); + g_assert (PAS_IS_BACKEND_FILE (backend)); + + if (! pas_backend_construct (PAS_BACKEND (backend))) + return FALSE; + + return TRUE; +} + +/** + * pas_backend_file_new: + */ +PASBackend * +pas_backend_file_new (void) +{ + PASBackendFile *backend; + + backend = gtk_type_new (pas_backend_file_get_type ()); + + if (! pas_backend_file_construct (backend)) { + gtk_object_unref (GTK_OBJECT (backend)); + + return NULL; + } + + return PAS_BACKEND (backend); +} + +static void +pas_backend_file_destroy (GtkObject *object) +{ + PASBackendFile *backend = PAS_BACKEND_FILE (object); + + GTK_OBJECT_CLASS (pas_backend_file_parent_class)->destroy (object); +} + +static void +pas_backend_file_class_init (PASBackendFileClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *) klass; + PASBackendClass *parent_class; + + pas_backend_file_parent_class = gtk_type_class (pas_backend_get_type ()); + + parent_class = PAS_BACKEND_CLASS (klass); + + /* Set the virtual methods. */ + parent_class->load_uri = pas_backend_file_load_uri; + parent_class->add_client = pas_backend_file_add_client; + parent_class->remove_client = pas_backend_file_remove_client; + + object_class->destroy = pas_backend_file_destroy; +} + +static void +pas_backend_file_init (PASBackendFile *backend) +{ + PASBackendFilePrivate *priv; + + priv = g_new0 (PASBackendFilePrivate, 1); + priv->loaded = FALSE; + priv->clients = NULL; + + backend->priv = priv; +} + +/** + * pas_backend_file_get_type: + */ +GtkType +pas_backend_file_get_type (void) +{ + static GtkType type = 0; + + if (! type) { + GtkTypeInfo info = { + "PASBackendFile", + sizeof (PASBackendFile), + sizeof (PASBackendFileClass), + (GtkClassInitFunc) pas_backend_file_class_init, + (GtkObjectInitFunc) pas_backend_file_init, + NULL, /* reserved 1 */ + NULL, /* reserved 2 */ + (GtkClassInitFunc) NULL + }; + + type = gtk_type_unique (pas_backend_get_type (), &info); + } + + return type; +} diff --git a/addressbook/backend/pas/pas-backend-file.h b/addressbook/backend/pas/pas-backend-file.h new file mode 100644 index 0000000000..a56626014b --- /dev/null +++ b/addressbook/backend/pas/pas-backend-file.h @@ -0,0 +1,32 @@ +/* + * Copyright 2000, Helix Code, Inc. + */ + +#ifndef __PAS_BACKEND_FILE_H__ +#define __PAS_BACKEND_FILE_H__ + +#include +#include + +typedef struct _PASBackendFilePrivate PASBackendFilePrivate; + +typedef struct { + PASBackend parent_object; + PASBackendFilePrivate *priv; +} PASBackendFile; + +typedef struct { + PASBackendClass parent_class; +} PASBackendFileClass; + +PASBackend *pas_backend_file_new (void); +GtkType pas_backend_file_get_type (void); + +#define PAS_BACKEND_FILE_TYPE (pas_backend_file_get_type ()) +#define PAS_BACKEND_FILE(o) (GTK_CHECK_CAST ((o), PAS_BACKEND_FILE_TYPE, PASBackendFile)) +#define PAS_BACKEND_FILE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendFileClass)) +#define PAS_IS_BACKEND_FILE(o) (GTK_CHECK_TYPE ((o), PAS_BACKEND_FILE_TYPE)) +#define PAS_IS_BACKEND_FILE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BACKEND_FILE_TYPE)) + +#endif /* ! __PAS_BACKEND_FILE_H__ */ + diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c index 291b101ce6..364204c3c2 100644 --- a/addressbook/backend/pas/pas-backend.c +++ b/addressbook/backend/pas/pas-backend.c @@ -1,37 +1,32 @@ /* + * Author: + * Nat Friedman (nat@helixcode.com) + * * Copyright 2000, Helix Code, Inc. */ #include #include -typedef struct { - Evolution_BookListener listener; -} PASClient; +#define CLASS(o) PAS_BACKEND_CLASS (GTK_OBJECT (o)->klass) -struct _PASBackendPrivate { - gboolean book_loaded; - GList *clients; - GList *response_queue; -}; - -PASBackend * -pas_backend_new (void) +gboolean +pas_backend_construct (PASBackend *backend) { - PASBackend *backend; - - backend = gtk_type_new (pas_backend_get_type ()); - - return backend; + return TRUE; } void pas_backend_load_uri (PASBackend *backend, - char *uri) + const char *uri) { g_return_if_fail (backend != NULL); g_return_if_fail (PAS_IS_BACKEND (backend)); g_return_if_fail (uri != NULL); + + g_assert (CLASS (backend)->load_uri != NULL); + + CLASS (backend)->load_uri (backend, uri); } /** @@ -43,77 +38,32 @@ void pas_backend_add_client (PASBackend *backend, Evolution_BookListener listener) { - PASClient *client; - g_return_if_fail (backend != NULL); g_return_if_fail (PAS_IS_BACKEND (backend)); g_return_if_fail (listener != CORBA_OBJECT_NIL); - client = g_new0 (PASClient, 1); - - client->listener = listener; - - if (backend->priv->book_loaded) { - - } -} - - -void -pas_backend_remove_client (PASBackend *backend, - Evolution_BookListener listener) -{ -} - -/* Synchronous operations. */ -char * -pas_backend_get_vcard (PASBackend *backend, - PASBook *book, - char *id) -{ -} - -/* Asynchronous operations. */ + g_assert (CLASS (backend)->add_client != NULL); -/** - * pas_backend_queue_remove_card: - */ -void -pas_backend_queue_create_card (PASBackend *backend, - PASBook *book, - char *vcard) -{ + CLASS (backend)->add_client (backend, listener); } -/** - * pas_backend_queue_remove_card: - */ void -pas_backend_queue_remove_card (PASBackend *backend, - PASBook *book, - char *id) +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 (CLASS (backend)->remove_client != NULL); -/** - * pas_backend_queue_modify_card: - */ -void -pas_backend_queue_modify_card (PASBackend *backend, - PASBook *book, - char *id, - char *vcard) -{ + CLASS (backend)->remove_client (backend, book); } static void pas_backend_init (PASBackend *backend) { - PASBackendPrivate *priv; - - priv = g_new0 (PASBackendPrivate, 1); - priv->book_loaded = FALSE; - priv->clients = NULL; } static void diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h index fca4ef7d8d..62822619ac 100644 --- a/addressbook/backend/pas/pas-backend.h +++ b/addressbook/backend/pas/pas-backend.h @@ -21,41 +21,38 @@ #ifndef __PAS_BACKEND_H__ #define __PAS_BACKEND_H__ +#include +#include +#include + +typedef struct _PASBackend PASBackend; typedef struct _PASBackendPrivate PASBackendPrivate; -typedef struct { +#include + +struct _PASBackend { GtkObject parent_object; PASBackendPrivate *priv; -} PASBackend; +}; typedef struct { GtkObjectClass parent_class; + + /* Virtual methods */ + void (*load_uri) (PASBackend *backend, const char *uri); + void (*add_client) (PASBackend *backend, Evolution_BookListener listener); + void (*remove_client) (PASBackend *backend, PASBook *book); } PASBackendClass; -PASBackend *pas_backend_new (void); +typedef PASBackend * (*PASBackendFactoryFn) (void); + +gboolean pas_backend_construct (PASBackend *backend); void pas_backend_load_uri (PASBackend *backend, - char *uri); + const char *uri); void pas_backend_add_client (PASBackend *backend, Evolution_BookListener listener); void pas_backend_remove_client (PASBackend *backend, - Evolution_BookListener listener); - -/* Synchronous operations. */ -char *pas_backend_get_vcard (PASBackend *backend, - PASBook *book, - char *id); - -/* Asynchronous operations. */ -void pas_backend_queue_create_card (PASBackend *backend, - PASBook *book, - char *vcard); -void pas_backend_queue_remove_card (PASBackend *backend, - PASBook *book, - char *id); -void pas_backend_queue_modify_card (PASBackend *backend, - PASBook *book, - char *id, - char *vcard); + PASBook *book); GtkType pas_backend_get_type (void); diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c index 55b67f4e7e..6f01ed8053 100644 --- a/addressbook/backend/pas/pas-book-factory.c +++ b/addressbook/backend/pas/pas-book-factory.c @@ -6,43 +6,34 @@ * Copyright 2000, Helix Code, Inc. */ +#include +#include #include #include +#define PAS_BOOK_FACTORY_GOAD_ID "evolution:card-server" + static GnomeObjectClass *pas_book_factory_parent_class; POA_Evolution_BookFactory__vepv pas_book_factory_vepv; -typedef struct { - Evolution_BookListener listener; - Evolution_BookListener_CallStatus status; -} PASBookFactoryQueuedResponse; - typedef struct { char *uri; Evolution_BookListener listener; } PASBookFactoryQueuedRequest; struct _PASBookFactoryPrivate { + gint idle_id; GHashTable *backends; GHashTable *active_server_map; - GList *queued_responses; GList *queued_requests; }; static char * pas_book_factory_canonicalize_uri (const char *uri) { - char *canon; - char *p; - /* FIXME: What do I do here? */ - canon = g_strdup (uri); - - for (p = canon; *p != '\0'; p ++) - *p = toupper (*p); - - return canon; + return g_strdup (uri); } static char * @@ -70,15 +61,17 @@ pas_book_factory_extract_proto_from_uri (const char *uri) * @backend: */ void -pas_book_factory_register_backend (PASBookFactory *factory, - const char *proto, - PASBookFactoryBackendFactory backend) +pas_book_factory_register_backend (PASBookFactory *factory, + const char *proto, + PASBackendFactoryFn backend) { g_return_if_fail (factory != NULL); g_return_if_fail (PAS_IS_BOOK_FACTORY (factory)); g_return_if_fail (proto != NULL); g_return_if_fail (backend != NULL); + + if (g_hash_table_lookup (factory->priv->backends, proto) != NULL) { g_warning ("pas_book_factory_register_backend: " "Proto \"%s\" already registered!\n", proto); @@ -88,13 +81,13 @@ pas_book_factory_register_backend (PASBookFactory *factory, g_strdup (proto), backend); } -static PASBookFactoryBackendFactory +static PASBackendFactoryFn pas_book_factory_lookup_backend_factory (PASBookFactory *factory, const char *uri) { - PASBookFactoryBackendFactory backend; - char *proto; - char *canonical_uri; + PASBackendFactoryFn backend; + char *proto; + char *canonical_uri; g_assert (factory != NULL); g_assert (PAS_IS_BOOK_FACTORY (factory)); @@ -118,64 +111,61 @@ pas_book_factory_lookup_backend_factory (PASBookFactory *factory, return backend; } -static void -pas_book_factory_process_request (PASBookFactory *factory, - PASBookFactoryQueuedRequest *request) +static PASBackend * +pas_book_factory_launch_backend (PASBookFactory *factory, + PASBookFactoryQueuedRequest *request) { - request = factory->priv->queued_requests->data; + PASBackendFactoryFn backend_factory; + PASBackend *backend; - /* - * Check to see if there is already a running backend for this - * URI. - */ - - - backend = pas_book_factory_lookup_backend_factory ( + backend_factory = pas_book_factory_lookup_backend_factory ( factory, request->uri); + g_assert (backend_factory != NULL); + + backend = (backend_factory) (); g_assert (backend != NULL); - (backend) (factory, request->uri, request->listener); -} + g_hash_table_insert (factory->priv->active_server_map, + g_strdup (request->uri), + backend); + return backend; +} static void -pas_book_factory_process_response (PASBookFactory *factory, - PASBookFactoryQueuedResponse *response) +pas_book_factory_process_request (PASBookFactory *factory, + PASBookFactoryQueuedRequest *request) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); + PASBackend *backend; - Evolution_BookListener_respond_open_book ( - response->listener, response->status, - CORBA_OBJECT_NIL, &ev); + request = factory->priv->queued_requests->data; - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("PASBookFactory: Exception while sending " - "response to BookListener!\n"); + backend = g_hash_table_lookup (factory->priv->active_server_map, request->uri); - CORBA_exception_free (&ev); - CORBA_exception_init (&ev); - } + if (backend == NULL) { - CORBA_Object_release (response->listener, &ev); + backend = pas_book_factory_launch_backend (factory, request); + pas_backend_add_client (backend, request->listener); + pas_backend_load_uri (backend, request->uri); + g_free (request->uri); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("PASBookFactory: Exception releasing " - "BookListener!\n"); + return; } - CORBA_exception_free (&ev); -} + g_free (request->uri); + pas_backend_add_client (backend, request->listener); +} static gboolean -pas_book_factory_process_queues (PASBookFactory *factory) +pas_book_factory_process_queue (PASBookFactory *factory) { /* Process pending Book-creation requests. */ - while (factory->priv->queued_requests != NULL) { + if (factory->priv->queued_requests != NULL) { PASBookFactoryQueuedRequest *request; + request = factory->priv->queued_requests->data; + pas_book_factory_process_request (factory, request); factory->priv->queued_requests = g_list_remove ( @@ -184,51 +174,15 @@ pas_book_factory_process_queues (PASBookFactory *factory) g_free (request); } - /* Flush the outgoing error queue. */ - while (factory->priv->queued_responses != NULL) { - PASBookFactoryQueuedResponse *response; - - response = factory->priv->queued_responses->data; - - pas_book_factory_process_response (factory, response); - factory->priv->queued_responses = g_list_remove ( - factory->priv->queued_responses, response); + if (factory->priv->queued_requests == NULL) { - g_free (response); + factory->priv->idle_id = 0; + return FALSE; } return TRUE; } -static void -pas_book_factory_queue_response (PASBookFactory *factory, - const Evolution_BookListener listener, - Evolution_BookListener_CallStatus status) -{ - PASBookFactoryQueuedResponse *response; - Evolution_BookListener listener_copy; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - listener_copy = CORBA_Object_duplicate (listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("PASBookFactory: Could not duplicate BookListener!\n"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - response = g_new0 (PASBookFactoryQueuedResponse, 1); - response->listener = listener_copy; - response->status = status; - - factory->priv->queued_responses = - g_list_prepend (factory->priv->queued_responses, response); -} - static void pas_book_factory_queue_request (PASBookFactory *factory, const char *uri, @@ -256,27 +210,32 @@ pas_book_factory_queue_request (PASBookFactory *factory, factory->priv->queued_requests = g_list_prepend (factory->priv->queued_requests, request); + + if (! factory->priv->idle_id) { + factory->priv->idle_id = + g_idle_add ((GSourceFunc) pas_book_factory_process_queue, factory); + } } + static void impl_Evolution_BookFactory_open_book (PortableServer_Servant servant, const CORBA_char *uri, const Evolution_BookListener listener, CORBA_Environment *ev) { - PASBookFactory *factory = + PASBookFactory *factory = PAS_BOOK_FACTORY (gnome_object_from_servant (servant)); + PASBackendFactoryFn backend_factory; - PASBookFactoryBackendFactory backend; - - backend = pas_book_factory_lookup_backend_factory (factory, uri); + backend_factory = pas_book_factory_lookup_backend_factory (factory, uri); - if (backend == NULL) { + if (backend_factory == NULL) { g_warning ("PASBookFactory: No backend found for uri: %s\n", uri); - pas_book_factory_queue_response ( - factory, listener, - Evolution_BookListener_ProtocolNotSupported); + CORBA_exception_set ( + ev, CORBA_USER_EXCEPTION, + ex_Evolution_BookFactory_ProtocolNotSupported, NULL); return; } @@ -284,7 +243,7 @@ impl_Evolution_BookFactory_open_book (PortableServer_Servant servant, pas_book_factory_queue_request (factory, uri, listener); } -static PASBookFactory * +static gboolean pas_book_factory_construct (PASBookFactory *factory) { POA_Evolution_BookFactory *servant; @@ -304,7 +263,7 @@ pas_book_factory_construct (PASBookFactory *factory) g_free (servant); CORBA_exception_free (&ev); - return NULL; + return FALSE; } CORBA_exception_free (&ev); @@ -313,12 +272,12 @@ pas_book_factory_construct (PASBookFactory *factory) if (obj == CORBA_OBJECT_NIL) { g_free (servant); - return NULL; + return FALSE; } gnome_object_construct (GNOME_OBJECT (factory), obj); - return factory; + return TRUE; } /** @@ -328,22 +287,65 @@ PASBookFactory * pas_book_factory_new (void) { PASBookFactory *factory; - PASBookFactory *retval; - factory = gtk_type_new (PAS_BOOK_FACTORY_TYPE); + factory = gtk_type_new (pas_book_factory_get_type ()); - retval = pas_book_factory_construct (factory); - - if (retval == NULL) { - g_warning ("pas_book_factoy_new: Could not construct PASBookFactory!\n"); + if (! pas_book_factory_construct (factory)) { + g_warning ("pas_book_factory_new: Could not construct PASBookFactory!\n"); gtk_object_unref (GTK_OBJECT (factory)); return NULL; } - return retval; + return factory; +} + +/** + * pas_book_factory_activate: + */ +void +pas_book_factory_activate (PASBookFactory *factory) +{ + CORBA_Environment ev; + int ret; + + g_return_if_fail (factory != NULL); + g_return_if_fail (PAS_IS_BOOK_FACTORY (factory)); + + CORBA_exception_init (&ev); + + ret = goad_server_register ( + NULL, + gnome_object_corba_objref (GNOME_OBJECT (factory)), + PAS_BOOK_FACTORY_GOAD_ID, "server", + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("pas_book_factory_construct: Exception " + "registering PASBookFactory!\n"); + CORBA_exception_free (&ev); + return; + } + + CORBA_exception_free (&ev); + + if (ret == -1) { + g_message ("pas_book_factory_construct: Error " + "registering PASBookFactory!\n"); + return; + } + + if (ret == -2) { + g_message ("pas_book_factory_construct: Another " + "PASBookFactory is already running.\n"); + return; + + } + + return; } + static void pas_book_factory_init (PASBookFactory *factory) { @@ -352,9 +354,6 @@ pas_book_factory_init (PASBookFactory *factory) factory->priv->active_server_map = g_hash_table_new (g_str_hash, g_str_equal); factory->priv->backends = g_hash_table_new (g_str_hash, g_str_equal); factory->priv->queued_requests = NULL; - factory->priv->queued_responses = NULL; - - g_idle_add ((GSourceFunc) pas_book_factory_process_queues, factory); } static gboolean @@ -401,19 +400,6 @@ pas_book_factory_destroy (GtkObject *object) g_list_free (factory->priv->queued_requests); factory->priv->queued_requests = NULL; - for (l = factory->priv->queued_responses; l != NULL; l = l->next) { - PASBookFactoryQueuedResponse *response = l->data; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - CORBA_Object_release (response->listener, &ev); - CORBA_exception_free (&ev); - - g_free (response); - } - g_list_free (factory->priv->queued_responses); - factory->priv->queued_responses = NULL; - g_hash_table_foreach_remove (factory->priv->active_server_map, pas_book_factory_remove_asm_entry, NULL); diff --git a/addressbook/backend/pas/pas-book-factory.h b/addressbook/backend/pas/pas-book-factory.h index f10444e48c..6e72b90062 100644 --- a/addressbook/backend/pas/pas-book-factory.h +++ b/addressbook/backend/pas/pas-book-factory.h @@ -5,6 +5,8 @@ #include #include +#include + #ifndef __PAS_BOOK_FACTORY_H__ #define __PAS_BOOK_FACTORY_H__ @@ -21,14 +23,11 @@ typedef struct { GnomeObjectClass parent_class; } PASBookFactoryClass; -typedef void (*PASBookFactoryBackendFactory) ( - PASBookFactory *factory, char *uri, Evolution_BookListener listener); - PASBookFactory *pas_book_factory_new (void); void pas_book_factory_register_backend (PASBookFactory *factory, const char *proto, - PASBookFactoryBackendFactory backend); + PASBackendFactoryFn backend_factory); void pas_book_factory_activate (PASBookFactory *factory); diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c new file mode 100644 index 0000000000..adac2fd806 --- /dev/null +++ b/addressbook/backend/pas/pas-book.c @@ -0,0 +1,573 @@ +/* + * pas-book.c + * + * Copyright 2000, Helix Code, Inc. + */ + +#include +#include + +static GnomeObjectClass *pas_book_parent_class; +POA_Evolution_Book__vepv pas_book_vepv; + +enum { + REQUESTS_QUEUED, + LAST_SIGNAL +}; + +static guint pas_book_signals [LAST_SIGNAL]; + +struct _PASBookPrivate { + PASBackend *backend; + Evolution_BookListener listener; + PASBookGetVCardFn get_vcard; + + GList *request_queue; + gint idle_id; +}; + +static gboolean +pas_book_check_queue (PASBook *book) +{ + if (book->priv->request_queue != NULL) { + gtk_signal_emit (GTK_OBJECT (book), + pas_book_signals [REQUESTS_QUEUED]); + } + + if (book->priv->request_queue == NULL) { + book->priv->idle_id = 0; + return FALSE; + } + + return TRUE; +} + +static void +pas_book_queue_request (PASBook *book, PASRequest *req) +{ + book->priv->request_queue = + g_list_append (book->priv->request_queue, req); + + if (book->priv->idle_id == 0) { + book->priv->idle_id = g_idle_add ((GSourceFunc) pas_book_check_queue, book); + } +} + +static void +pas_book_queue_create_card (PASBook *book, const char *vcard) +{ + PASRequest *req; + + req = g_new0 (PASRequest, 1); + req->op = CreateCard; + req->vcard = g_strdup (vcard); + + pas_book_queue_request (book, req); +} + +static void +pas_book_queue_remove_card (PASBook *book, const char *id) +{ + PASRequest *req; + + req = g_new0 (PASRequest, 1); + req->op = RemoveCard; + req->id = g_strdup (id); + + pas_book_queue_request (book, req); +} + +static void +pas_book_queue_modify_card (PASBook *book, const char *vcard) +{ + PASRequest *req; + + req = g_new0 (PASRequest, 1); + req->op = ModifyCard; + req->vcard = g_strdup (vcard); + + pas_book_queue_request (book, req); +} + +static void +pas_book_queue_check_connection (PASBook *book) +{ + PASRequest *req; + + req = g_new0 (PASRequest, 1); + req->op = CheckConnection; + + pas_book_queue_request (book, req); +} + +static CORBA_char * +impl_Evolution_Book_get_vcard (PortableServer_Servant servant, + const Evolution_CardId id, + CORBA_Environment *ev) +{ + PASBook *book = PAS_BOOK (gnome_object_from_servant (servant)); + char *vcard; + CORBA_char *retval; + + vcard = (book->priv->get_vcard) (book, (const char *) id); + retval = CORBA_string_dup (vcard); + g_free (vcard); + + return retval; +} + +static void +impl_Evolution_Book_create_card (PortableServer_Servant servant, + const CORBA_char *vcard, + CORBA_Environment *ev) +{ + PASBook *book = PAS_BOOK (gnome_object_from_servant (servant)); + + pas_book_queue_create_card (book, vcard); +} + +static void +impl_Evolution_Book_remove_card (PortableServer_Servant servant, + const Evolution_CardId id, + CORBA_Environment *ev) +{ + PASBook *book = PAS_BOOK (gnome_object_from_servant (servant)); + + pas_book_queue_remove_card (book, (const char *) id); +} + +static void +impl_Evolution_Book_modify_card (PortableServer_Servant servant, + const CORBA_char *vcard, + CORBA_Environment *ev) +{ + PASBook *book = PAS_BOOK (gnome_object_from_servant (servant)); + + pas_book_queue_modify_card (book, vcard); +} + +static void +impl_Evolution_Book_check_connection (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + PASBook *book = PAS_BOOK (gnome_object_from_servant (servant)); + + pas_book_queue_check_connection (book); +} + +/** + * pas_book_get_backend: + */ +PASBackend * +pas_book_get_backend (PASBook *book) +{ + g_return_val_if_fail (book != NULL, NULL); + g_return_val_if_fail (PAS_IS_BOOK (book), NULL); + + return book->priv->backend; +} + +/** + * pas_book_get_listener: + */ +Evolution_BookListener +pas_book_get_listener (PASBook *book) +{ + g_return_val_if_fail (book != NULL, CORBA_OBJECT_NIL); + g_return_val_if_fail (PAS_IS_BOOK (book), CORBA_OBJECT_NIL); + + return book->priv->listener; +} + +/** + * pas_book_check_pending + */ +gint +pas_book_check_pending (PASBook *book) +{ + g_return_val_if_fail (book != NULL, -1); + g_return_val_if_fail (PAS_IS_BOOK (book), -1); + + return g_list_length (book->priv->request_queue); +} + +/** + * pas_book_pop_request: + */ +PASRequest * +pas_book_pop_request (PASBook *book) +{ + GList *popped; + PASRequest *req; + + g_return_val_if_fail (book != NULL, NULL); + g_return_val_if_fail (PAS_IS_BOOK (book), NULL); + + if (book->priv->request_queue == NULL) + return NULL; + + req = book->priv->request_queue->data; + + popped = book->priv->request_queue; + book->priv->request_queue = + g_list_remove_link (book->priv->request_queue, popped); + + g_list_free_1 (popped); + + return req; +} + +/** + * pas_book_respond_open: + */ +void +pas_book_respond_open (PASBook *book, + Evolution_BookListener_CallStatus status) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + if (status == Evolution_BookListener_Success) { + Evolution_BookListener_respond_open_book ( + book->priv->listener, status, + gnome_object_corba_objref (GNOME_OBJECT (book)), + &ev); + } else { + Evolution_BookListener_respond_open_book ( + book->priv->listener, status, + CORBA_OBJECT_NIL, &ev); + } + + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_respond_open: Exception " + "responding to BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + +/** + * pas_book_respond_create: + */ +void +pas_book_respond_create (PASBook *book, + Evolution_BookListener_CallStatus status) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + Evolution_BookListener_respond_create_card ( + book->priv->listener, status, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_respond_create: Exception " + "responding to BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + +/** + * pas_book_respond_remove: + */ +void +pas_book_respond_remove (PASBook *book, + Evolution_BookListener_CallStatus status) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + Evolution_BookListener_respond_remove_card ( + book->priv->listener, status, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_respond_remove: Exception " + "responding to BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + +/** + * pas_book_respond_modify: + */ +void +pas_book_respond_modify (PASBook *book, + Evolution_BookListener_CallStatus status) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + Evolution_BookListener_respond_modify_card ( + book->priv->listener, status, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_respond_modify: Exception " + "responding to BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + +/** + * pas_book_report_connection: + */ +void +pas_book_report_connection (PASBook *book, + gboolean connected) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + Evolution_BookListener_report_connection_status ( + book->priv->listener, (CORBA_boolean) connected, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_report_connection: Exception " + "responding to BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + + +/** + * pas_book_notify_change: + */ +void +pas_book_notify_change (PASBook *book, + const char *id) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + Evolution_BookListener_signal_card_changed ( + book->priv->listener, (Evolution_CardId) id, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_notify_change: Exception signaling BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + +/** + * pas_book_notify_remove: + */ +void +pas_book_notify_remove (PASBook *book, + const char *id) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + Evolution_BookListener_signal_card_removed ( + book->priv->listener, (Evolution_CardId) id, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_notify_remove: Exception signaling BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + +/** + * pas_book_notify_add: + */ +void +pas_book_notify_add (PASBook *book, + const char *id) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + Evolution_BookListener_signal_card_added ( + book->priv->listener, (Evolution_CardId) id, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_notify_add: Exception signaling BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + +static gboolean +pas_book_construct (PASBook *book, + PASBackend *backend, + Evolution_BookListener listener, + PASBookGetVCardFn get_vcard) +{ + POA_Evolution_Book *servant; + CORBA_Environment ev; + CORBA_Object obj; + + g_assert (book != NULL); + g_assert (PAS_IS_BOOK (book)); + g_assert (listener != CORBA_OBJECT_NIL); + g_assert (get_vcard != NULL); + + servant = (POA_Evolution_Book *) g_new0 (GnomeObjectServant, 1); + servant->vepv = &pas_book_vepv; + + CORBA_exception_init (&ev); + + POA_Evolution_Book__init ((PortableServer_Servant) servant, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_free (servant); + CORBA_exception_free (&ev); + + return FALSE; + } + + CORBA_exception_free (&ev); + + obj = gnome_object_activate_servant (GNOME_OBJECT (book), servant); + if (obj == CORBA_OBJECT_NIL) { + g_free (servant); + + return FALSE; + } + + gnome_object_construct (GNOME_OBJECT (book), obj); + + book->priv->listener = listener; + book->priv->get_vcard = get_vcard; + book->priv->backend = backend; + + return TRUE; +} + +/** + * pas_book_new: + */ +PASBook * +pas_book_new (PASBackend *backend, + Evolution_BookListener listener, + PASBookGetVCardFn get_vcard) +{ + PASBook *book; + PASBook *retval; + + g_return_val_if_fail (listener != CORBA_OBJECT_NIL, NULL); + g_return_val_if_fail (get_vcard != NULL, NULL); + + book = gtk_type_new (pas_book_get_type ()); + + if (! pas_book_construct (book, backend, listener, get_vcard)) { + gtk_object_unref (GTK_OBJECT (book)); + + return NULL; + } + + return book; +} + +static void +pas_book_destroy (GtkObject *object) +{ + PASBook *book = PAS_BOOK (object); + GList *l; + + for (l = book->priv->request_queue; l != NULL; l = l->next) { + PASRequest *req = l->data; + + g_free (req->id); + g_free (req->vcard); + g_free (req); + } + g_list_free (book->priv->request_queue); + + g_free (book->priv); + + GTK_OBJECT_CLASS (pas_book_parent_class)->destroy (object); +} + +static POA_Evolution_Book__epv * +pas_book_get_epv (void) +{ + POA_Evolution_Book__epv *epv; + + epv = g_new0 (POA_Evolution_Book__epv, 1); + + epv->get_vcard = impl_Evolution_Book_get_vcard; + epv->create_card = impl_Evolution_Book_create_card; + epv->remove_card = impl_Evolution_Book_remove_card; + epv->modify_card = impl_Evolution_Book_modify_card; + epv->check_connection = impl_Evolution_Book_check_connection; + + return epv; + +} + +static void +pas_book_corba_class_init (void) +{ + pas_book_vepv.GNOME_Unknown_epv = gnome_object_get_epv (); + pas_book_vepv.Evolution_Book_epv = pas_book_get_epv (); +} + +static void +pas_book_class_init (PASBookClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *) klass; + + pas_book_parent_class = gtk_type_class (gnome_object_get_type ()); + + pas_book_signals [REQUESTS_QUEUED] = + gtk_signal_new ("requests_queued", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (PASBookClass, requests_queued), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, pas_book_signals, LAST_SIGNAL); + + object_class->destroy = pas_book_destroy; + + pas_book_corba_class_init (); +} + +static void +pas_book_init (PASBook *book) +{ + book->priv = g_new0 (PASBookPrivate, 1); + book->priv->idle_id = 0; + book->priv->request_queue = NULL; +} + +/** + * pas_book_get_type: + */ +GtkType +pas_book_get_type (void) +{ + static GtkType type = 0; + + if (! type) { + GtkTypeInfo info = { + "PASBook", + sizeof (PASBook), + sizeof (PASBookClass), + (GtkClassInitFunc) pas_book_class_init, + (GtkObjectInitFunc) pas_book_init, + NULL, /* reserved 1 */ + NULL, /* reserved 2 */ + (GtkClassInitFunc) NULL + }; + + type = gtk_type_unique (gnome_object_get_type (), &info); + } + + return type; +} + diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h new file mode 100644 index 0000000000..e929916ceb --- /dev/null +++ b/addressbook/backend/pas/pas-book.h @@ -0,0 +1,84 @@ +/* + * A wrapper object which exports the Evolution_Book CORBA interface + * and which maintains a request queue. + * + * Author: + * Nat Friedman (nat@helixcode.com) + * + * Copyright 2000, Helix Code, Inc. + */ + +#ifndef __PAS_BOOK_H__ +#define __PAS_BOOK_H__ + +#include +#include +#include + +typedef struct _PASBook PASBook; +typedef struct _PASBookPrivate PASBookPrivate; + +#include + +typedef enum { + CreateCard, + RemoveCard, + ModifyCard, + CheckConnection +} PASOperation; + +typedef struct { + PASOperation op; + char *id; + char *vcard; +} PASRequest; + +struct _PASBook { + GnomeObject parent_object; + PASBookPrivate *priv; +}; + +typedef struct { + GnomeObjectClass parent_class; + + /* Signals */ + void (*requests_queued) (void); +} PASBookClass; + +typedef char * (*PASBookGetVCardFn) (PASBook *book, const char *id); + +PASBook *pas_book_new (PASBackend *backend, + Evolution_BookListener listener, + PASBookGetVCardFn get_vcard); +PASBackend *pas_book_get_backend (PASBook *book); +Evolution_BookListener pas_book_get_listener (PASBook *book); +int pas_book_check_pending (PASBook *book); +PASRequest *pas_book_pop_request (PASBook *book); + +void pas_book_respond_open (PASBook *book, + Evolution_BookListener_CallStatus status); +void pas_book_respond_create (PASBook *book, + Evolution_BookListener_CallStatus status); +void pas_book_respond_remove (PASBook *book, + Evolution_BookListener_CallStatus status); +void pas_book_respond_modify (PASBook *book, + Evolution_BookListener_CallStatus status); +void pas_book_report_connection (PASBook *book, + gboolean connected); + +void pas_book_notify_change (PASBook *book, + const char *id); +void pas_book_notify_remove (PASBook *book, + const char *id); +void pas_book_notify_add (PASBook *book, + const char *id); + +GtkType pas_book_get_type (void); + +#define PAS_BOOK_TYPE (pas_book_get_type ()) +#define PAS_BOOK(o) (GTK_CHECK_CAST ((o), PAS_BOOK_TYPE, PASBook)) +#define PAS_BOOK_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BOOK_FACTORY_TYPE, PASBookClass)) +#define PAS_IS_BOOK(o) (GTK_CHECK_TYPE ((o), PAS_BOOK_TYPE)) +#define PAS_IS_BOOK_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BOOK_TYPE)) + +#endif /* ! __PAS_BOOK_H__ */ diff --git a/addressbook/backend/pas/pas.c b/addressbook/backend/pas/pas.c new file mode 100644 index 0000000000..07d6d5c757 --- /dev/null +++ b/addressbook/backend/pas/pas.c @@ -0,0 +1,54 @@ +/* + * Author: + * Nat Friedman (nat@helixcode.com) + * + * Copyright 2000, Helix Code, Inc. + */ +#include +#include + +#include +#include + +CORBA_Environment ev; +CORBA_ORB orb; + +static void +init_bonobo (int argc, char **argv) +{ + + gnome_CORBA_init_with_popt_table ( + "Personal Addressbook Server", "0.0", + &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev); + + orb = gnome_CORBA_ORB (); + + if (bonobo_init (orb, NULL, NULL) == FALSE) + g_error (_("Could not initialize Bonobo")); +} + +int +main (int argc, char **argv) +{ + PASBookFactory *factory; + + CORBA_exception_init (&ev); + + + init_bonobo (argc, argv); + + /* + * Create the factory and register the local-file backend with + * it. + */ + factory = pas_book_factory_new (); + + pas_book_factory_register_backend ( + factory, "file", pas_backend_file_new); + + pas_book_factory_activate (factory); + + bonobo_main (); + + return 0; +} -- cgit v1.2.3