aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend/pas/pas-book-factory.c
diff options
context:
space:
mode:
authorNat Friedman <nat@src.gnome.org>2000-01-18 11:31:07 +0800
committerNat Friedman <nat@src.gnome.org>2000-01-18 11:31:07 +0800
commit2f1705c6c0d747e708a34b089c4b6ebfc7832022 (patch)
tree1b94d61159ccf0ec4108f98214680850cc5ac350 /addressbook/backend/pas/pas-book-factory.c
parente63f053c3e341251c123c72587e930228b781c67 (diff)
downloadgsoc2013-evolution-2f1705c6c0d747e708a34b089c4b6ebfc7832022.tar
gsoc2013-evolution-2f1705c6c0d747e708a34b089c4b6ebfc7832022.tar.gz
gsoc2013-evolution-2f1705c6c0d747e708a34b089c4b6ebfc7832022.tar.bz2
gsoc2013-evolution-2f1705c6c0d747e708a34b089c4b6ebfc7832022.tar.lz
gsoc2013-evolution-2f1705c6c0d747e708a34b089c4b6ebfc7832022.tar.xz
gsoc2013-evolution-2f1705c6c0d747e708a34b089c4b6ebfc7832022.tar.zst
gsoc2013-evolution-2f1705c6c0d747e708a34b089c4b6ebfc7832022.zip
A precommit so Federico can see.
svn path=/trunk/; revision=1584
Diffstat (limited to 'addressbook/backend/pas/pas-book-factory.c')
-rw-r--r--addressbook/backend/pas/pas-book-factory.c488
1 files changed, 488 insertions, 0 deletions
diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c
new file mode 100644
index 0000000000..55b67f4e7e
--- /dev/null
+++ b/addressbook/backend/pas/pas-book-factory.c
@@ -0,0 +1,488 @@
+/*
+ *
+ * Author:
+ * Nat Friedman (nat@helixcode.com)
+ *
+ * Copyright 2000, Helix Code, Inc.
+ */
+
+#include <addressbook.h>
+#include <pas-book-factory.h>
+
+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 {
+ 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;
+}
+
+static char *
+pas_book_factory_extract_proto_from_uri (const char *uri)
+{
+ char *proto;
+ char *p;
+
+ p = strchr (uri, ':');
+
+ if (p == NULL)
+ return NULL;
+
+ proto = g_malloc0 (p - uri + 1);
+
+ strncpy (proto, uri, p - uri);
+
+ return proto;
+}
+
+/**
+ * pas_book_factory_register_backend:
+ * @factory:
+ * @proto:
+ * @backend:
+ */
+void
+pas_book_factory_register_backend (PASBookFactory *factory,
+ const char *proto,
+ PASBookFactoryBackendFactory 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);
+ }
+
+ g_hash_table_insert (factory->priv->backends,
+ g_strdup (proto), backend);
+}
+
+static PASBookFactoryBackendFactory
+pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
+ const char *uri)
+{
+ PASBookFactoryBackendFactory backend;
+ char *proto;
+ char *canonical_uri;
+
+ g_assert (factory != NULL);
+ g_assert (PAS_IS_BOOK_FACTORY (factory));
+ g_assert (uri != NULL);
+
+ canonical_uri = pas_book_factory_canonicalize_uri (uri);
+ if (canonical_uri == NULL)
+ return NULL;
+
+ proto = pas_book_factory_extract_proto_from_uri (canonical_uri);
+ if (proto == NULL) {
+ g_free (canonical_uri);
+ return NULL;
+ }
+
+ backend = g_hash_table_lookup (factory->priv->backends, proto);
+
+ g_free (proto);
+ g_free (canonical_uri);
+
+ return backend;
+}
+
+static void
+pas_book_factory_process_request (PASBookFactory *factory,
+ PASBookFactoryQueuedRequest *request)
+{
+ request = factory->priv->queued_requests->data;
+
+ /*
+ * Check to see if there is already a running backend for this
+ * URI.
+ */
+
+
+ backend = pas_book_factory_lookup_backend_factory (
+ factory, request->uri);
+ g_assert (backend != NULL);
+
+ (backend) (factory, request->uri, request->listener);
+}
+
+
+static void
+pas_book_factory_process_response (PASBookFactory *factory,
+ PASBookFactoryQueuedResponse *response)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_respond_open_book (
+ response->listener, response->status,
+ CORBA_OBJECT_NIL, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("PASBookFactory: Exception while sending "
+ "response to BookListener!\n");
+
+ CORBA_exception_free (&ev);
+ CORBA_exception_init (&ev);
+ }
+
+ CORBA_Object_release (response->listener, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("PASBookFactory: Exception releasing "
+ "BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+
+static gboolean
+pas_book_factory_process_queues (PASBookFactory *factory)
+{
+ /* Process pending Book-creation requests. */
+ while (factory->priv->queued_requests != NULL) {
+ PASBookFactoryQueuedRequest *request;
+
+ pas_book_factory_process_request (factory, request);
+
+ factory->priv->queued_requests = g_list_remove (
+ factory->priv->queued_requests, request);
+
+ 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);
+
+ g_free (response);
+ }
+
+ 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,
+ const Evolution_BookListener listener)
+{
+ PASBookFactoryQueuedRequest *request;
+ 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);
+
+ request = g_new0 (PASBookFactoryQueuedRequest, 1);
+ request->listener = listener_copy;
+ request->uri = g_strdup (uri);
+
+ factory->priv->queued_requests =
+ g_list_prepend (factory->priv->queued_requests, request);
+}
+
+static void
+impl_Evolution_BookFactory_open_book (PortableServer_Servant servant,
+ const CORBA_char *uri,
+ const Evolution_BookListener listener,
+ CORBA_Environment *ev)
+{
+ PASBookFactory *factory =
+ PAS_BOOK_FACTORY (gnome_object_from_servant (servant));
+
+ PASBookFactoryBackendFactory backend;
+
+ backend = pas_book_factory_lookup_backend_factory (factory, uri);
+
+ if (backend == NULL) {
+ g_warning ("PASBookFactory: No backend found for uri: %s\n", uri);
+
+ pas_book_factory_queue_response (
+ factory, listener,
+ Evolution_BookListener_ProtocolNotSupported);
+
+ return;
+ }
+
+ pas_book_factory_queue_request (factory, uri, listener);
+}
+
+static PASBookFactory *
+pas_book_factory_construct (PASBookFactory *factory)
+{
+ POA_Evolution_BookFactory *servant;
+ CORBA_Environment ev;
+ CORBA_Object obj;
+
+ g_assert (factory != NULL);
+ g_assert (PAS_IS_BOOK_FACTORY (factory));
+
+ servant = (POA_Evolution_BookFactory *) g_new0 (GnomeObjectServant, 1);
+ servant->vepv = &pas_book_factory_vepv;
+
+ CORBA_exception_init (&ev);
+
+ POA_Evolution_BookFactory__init ((PortableServer_Servant) servant, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_free (servant);
+ CORBA_exception_free (&ev);
+
+ return NULL;
+ }
+
+ CORBA_exception_free (&ev);
+
+ obj = gnome_object_activate_servant (GNOME_OBJECT (factory), servant);
+ if (obj == CORBA_OBJECT_NIL) {
+ g_free (servant);
+
+ return NULL;
+ }
+
+ gnome_object_construct (GNOME_OBJECT (factory), obj);
+
+ return factory;
+}
+
+/**
+ * pas_book_factory_new:
+ */
+PASBookFactory *
+pas_book_factory_new (void)
+{
+ PASBookFactory *factory;
+ PASBookFactory *retval;
+
+ factory = gtk_type_new (PAS_BOOK_FACTORY_TYPE);
+
+ retval = pas_book_factory_construct (factory);
+
+ if (retval == NULL) {
+ g_warning ("pas_book_factoy_new: Could not construct PASBookFactory!\n");
+ gtk_object_unref (GTK_OBJECT (factory));
+
+ return NULL;
+ }
+
+ return retval;
+}
+
+static void
+pas_book_factory_init (PASBookFactory *factory)
+{
+ factory->priv = g_new0 (PASBookFactoryPrivate, 1);
+
+ 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
+pas_book_factory_remove_asm_entry (gpointer key, gpointer value,
+ gpointer data)
+{
+ CORBA_Environment ev;
+
+ g_free (key);
+
+ CORBA_exception_init (&ev);
+ CORBA_Object_release ((CORBA_Object) value, &ev);
+ CORBA_exception_free (&ev);
+
+ return TRUE;
+}
+
+static gboolean
+pas_book_factory_remove_backend_entry (gpointer key, gpointer value,
+ gpointer data)
+{
+ g_free (key);
+ return TRUE;
+}
+
+static void
+pas_book_factory_destroy (GtkObject *object)
+{
+ PASBookFactory *factory = PAS_BOOK_FACTORY (object);
+ GList *l;
+
+ for (l = factory->priv->queued_requests; l != NULL; l = l->next) {
+ PASBookFactoryQueuedRequest *request = l->data;
+ CORBA_Environment ev;
+
+ g_free (request->uri);
+
+ CORBA_exception_init (&ev);
+ CORBA_Object_release (request->listener, &ev);
+ CORBA_exception_free (&ev);
+
+ g_free (request);
+ }
+ 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);
+ g_hash_table_destroy (factory->priv->active_server_map);
+
+ g_hash_table_foreach_remove (factory->priv->backends,
+ pas_book_factory_remove_backend_entry,
+ NULL);
+ g_hash_table_destroy (factory->priv->backends);
+
+ g_free (factory->priv);
+
+ GTK_OBJECT_CLASS (pas_book_factory_parent_class)->destroy (object);
+}
+
+static POA_Evolution_BookFactory__epv *
+pas_book_factory_get_epv (void)
+{
+ POA_Evolution_BookFactory__epv *epv;
+
+ epv = g_new0 (POA_Evolution_BookFactory__epv, 1);
+
+ epv->open_book = impl_Evolution_BookFactory_open_book;
+
+ return epv;
+
+}
+
+static void
+pas_book_factory_corba_class_init (void)
+{
+ pas_book_factory_vepv.GNOME_Unknown_epv = gnome_object_get_epv ();
+ pas_book_factory_vepv.Evolution_BookFactory_epv = pas_book_factory_get_epv ();
+}
+
+static void
+pas_book_factory_class_init (PASBookFactoryClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *) klass;
+
+ pas_book_factory_parent_class = gtk_type_class (gnome_object_get_type ());
+
+ object_class->destroy = pas_book_factory_destroy;
+
+ pas_book_factory_corba_class_init ();
+}
+
+/**
+ * pas_book_factory_get_type:
+ */
+GtkType
+pas_book_factory_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (! type) {
+ GtkTypeInfo info = {
+ "PASBookFactory",
+ sizeof (PASBookFactory),
+ sizeof (PASBookFactoryClass),
+ (GtkClassInitFunc) pas_book_factory_class_init,
+ (GtkObjectInitFunc) pas_book_factory_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (gnome_object_get_type (), &info);
+ }
+
+ return type;
+}