source: trunk/third/evolution/shell/e-corba-storage-registry.c @ 18142

Revision 18142, 15.1 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18141, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* e-corba-storage-registry.c
3 *
4 * Copyright (C) 2000  Ximian, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Ettore Perazzoli
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include "e-local-storage.h"
28#include "e-corba-storage.h"
29#include "e-corba-storage-registry.h"
30#include "e-shell-constants.h"
31
32#include "e-util/e-corba-utils.h"
33
34#include <bonobo/bonobo-exception.h>
35#include <gal/util/e-util.h>
36
37
38#define PARENT_TYPE BONOBO_OBJECT_TYPE
39static BonoboObjectClass *parent_class = NULL;
40
41struct _ECorbaStorageRegistryPrivate {
42        EStorageSet *storage_set;
43
44        GSList *listeners;
45};
46
47
48/* CORBA interface implementation.  */
49
50static POA_GNOME_Evolution_StorageRegistry__vepv storage_registry_vepv;
51
52static POA_GNOME_Evolution_StorageRegistry *
53create_servant (void)
54{
55        POA_GNOME_Evolution_StorageRegistry *servant;
56        CORBA_Environment ev;
57
58        servant = (POA_GNOME_Evolution_StorageRegistry *) g_new0 (BonoboObjectServant, 1);
59        servant->vepv = &storage_registry_vepv;
60
61        CORBA_exception_init (&ev);
62
63        POA_GNOME_Evolution_StorageRegistry__init ((PortableServer_Servant) servant, &ev);
64        if (ev._major != CORBA_NO_EXCEPTION) {
65                g_free (servant);
66                CORBA_exception_free (&ev);
67                return NULL;
68        }
69
70        CORBA_exception_free (&ev);
71
72        return servant;
73}
74
75static void
76listener_notify (Bonobo_Listener listener,
77                 GNOME_Evolution_StorageRegistry_MessageType type,
78                 const char *name)
79{
80        CORBA_any any;
81        GNOME_Evolution_StorageRegistry_NotifyResult nr;
82        CORBA_Environment ev;
83       
84        nr.type = type;
85        nr.name = CORBA_string_dup (name ? name : "");
86
87        any._type = (CORBA_TypeCode) TC_GNOME_Evolution_StorageRegistry_NotifyResult;
88        any._value = &nr;
89
90        CORBA_exception_init (&ev);
91        Bonobo_Listener_event (listener,
92                               "Evolution::StorageRegistry::NotifyResult",
93                               &any, &ev);
94        if (BONOBO_EX (&ev)) {
95                g_warning ("Could not send notify event for %s\n%s", name,
96                           CORBA_exception_id (&ev));
97        }
98
99        CORBA_free (nr.name);
100
101        CORBA_exception_free (&ev);
102}
103
104static GNOME_Evolution_StorageListener
105impl_StorageRegistry_addStorage (PortableServer_Servant servant,
106                                 const GNOME_Evolution_Storage storage_interface,
107                                 const CORBA_char *name,
108                                 CORBA_Environment *ev)
109{
110        BonoboObject *bonobo_object;
111        ECorbaStorageRegistry *storage_registry;
112        ECorbaStorageRegistryPrivate *priv;
113        EStorage *storage;
114        GNOME_Evolution_StorageListener listener_interface;
115        GSList *iter;
116       
117        bonobo_object = bonobo_object_from_servant (servant);
118        storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
119        priv = storage_registry->priv;
120
121        storage = e_corba_storage_new (storage_interface, name);
122
123        if (! e_storage_set_add_storage (priv->storage_set, storage)) {
124                CORBA_exception_set (ev,
125                                     CORBA_USER_EXCEPTION,
126                                     ex_GNOME_Evolution_StorageRegistry_Exists,
127                                     NULL);
128                return CORBA_OBJECT_NIL;
129        }
130
131        gtk_object_unref (GTK_OBJECT (storage));
132
133
134       /* FIXME: if we remove a listener while looping through the list we can
135        * crash. Yay CORBA reentrancy. */
136        for (iter = priv->listeners; iter; iter = iter->next) {
137                listener_notify (iter->data,
138                                 GNOME_Evolution_StorageRegistry_STORAGE_CREATED,
139                                 name);
140        }
141       
142        listener_interface = CORBA_Object_duplicate (e_corba_storage_get_StorageListener
143                                                     (E_CORBA_STORAGE (storage)), ev);
144
145        return listener_interface;
146}
147
148static GNOME_Evolution_StorageRegistry_StorageList *
149impl_StorageRegistry_getStorageList (PortableServer_Servant servant,
150                                     CORBA_Environment *ev)
151{
152        BonoboObject *bonobo_object;
153        ECorbaStorageRegistry *storage_registry;
154        ECorbaStorageRegistryPrivate *priv;
155        GNOME_Evolution_StorageRegistry_StorageList *storage_list;
156        GList *sl, *l;
157       
158        bonobo_object = bonobo_object_from_servant (servant);
159        storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
160        priv = storage_registry->priv;
161
162        sl = e_storage_set_get_storage_list (priv->storage_set);
163       
164        storage_list = GNOME_Evolution_StorageRegistry_StorageList__alloc ();
165        storage_list->_maximum = g_list_length (sl);
166        storage_list->_length = 0;
167        storage_list->_buffer = CORBA_sequence_GNOME_Evolution_Storage_allocbuf (storage_list->_maximum);
168        for (l = sl; l != NULL; l = l->next) {
169                EStorage *storage;
170                GNOME_Evolution_Storage corba_storage;
171                CORBA_Environment ev2;
172               
173                CORBA_exception_init (&ev2);
174               
175                storage = l->data;
176                if (E_IS_LOCAL_STORAGE (storage)) {
177                        corba_storage = e_local_storage_get_corba_interface (E_LOCAL_STORAGE (storage));
178                } else if (E_IS_CORBA_STORAGE (storage)) {
179                        corba_storage = e_corba_storage_get_corba_objref (E_CORBA_STORAGE (storage));
180                } else {
181                        continue;                       
182                }
183               
184                corba_storage = CORBA_Object_duplicate (corba_storage, &ev2);
185                if (BONOBO_EX (&ev2)) {
186                        CORBA_exception_free (&ev2);                   
187                        continue;
188                }               
189                storage_list->_buffer[storage_list->_length] = corba_storage;
190                storage_list->_length++;               
191        }
192
193        CORBA_sequence_set_release (storage_list, TRUE);
194
195        return storage_list;   
196}
197
198static GNOME_Evolution_Storage
199impl_StorageRegistry_getStorageByName (PortableServer_Servant servant,
200                                       const CORBA_char *name,
201                                       CORBA_Environment *ev)
202{
203        BonoboObject *bonobo_object;
204        ECorbaStorageRegistry *storage_registry;
205        ECorbaStorageRegistryPrivate *priv;
206        GNOME_Evolution_Storage corba_storage;
207        EStorage *storage;
208
209        bonobo_object = bonobo_object_from_servant (servant);
210        storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
211        priv = storage_registry->priv;
212
213        storage = e_storage_set_get_storage (priv->storage_set, name);
214        if (storage == NULL) {
215                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
216                                     ex_GNOME_Evolution_StorageRegistry_NotFound,
217                                     NULL);
218                return CORBA_OBJECT_NIL;
219        }
220
221        corba_storage = CORBA_Object_duplicate (e_corba_storage_get_corba_objref
222                                                (E_CORBA_STORAGE (storage)), ev);
223
224        return corba_storage;
225}
226
227static void
228impl_StorageRegistry_removeStorageByName (PortableServer_Servant servant,
229                                          const CORBA_char *name,
230                                          CORBA_Environment *ev)
231{
232        BonoboObject *bonobo_object;
233        ECorbaStorageRegistry *storage_registry;
234        ECorbaStorageRegistryPrivate *priv;
235        EStorage *storage;
236
237        bonobo_object = bonobo_object_from_servant (servant);
238        storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
239        priv = storage_registry->priv;
240
241        storage = e_storage_set_get_storage (priv->storage_set, name);
242        if (storage == NULL) {
243                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
244                                     ex_GNOME_Evolution_StorageRegistry_NotFound,
245                                     NULL);
246                return;
247        }
248
249        /* FIXME: Yucky to get the storage by name and then remove it.  */
250        /* FIXME: Check failure.  */
251        e_storage_set_remove_storage (priv->storage_set, storage);
252}
253
254static void
255storage_set_foreach (EStorageSet *set,
256                     Bonobo_Listener listener)
257{
258        GList *storage_list, *p;
259
260        storage_list = e_storage_set_get_storage_list (set);
261        for (p = storage_list; p; p = p->next) {
262                const char *name;
263
264                name = e_storage_get_name (E_STORAGE (p->data));
265
266                listener_notify (listener, GNOME_Evolution_StorageRegistry_STORAGE_CREATED, name);
267                gtk_object_unref (GTK_OBJECT (p->data));
268        }
269       
270        g_list_free (storage_list);
271}
272
273static GSList *
274find_listener (GSList *p,
275               Bonobo_Listener listener)
276{
277        CORBA_Environment ev;
278
279        CORBA_exception_init (&ev);
280        for (; p; p = p->next) {
281                if (CORBA_Object_is_equivalent (p->data, listener, &ev) == TRUE) {
282                        CORBA_exception_free (&ev);
283                        return p;
284                }
285        }
286
287        CORBA_exception_free (&ev);
288        return NULL;
289}
290
291static void
292impl_StorageRegistry_addListener (PortableServer_Servant servant,
293                                  Bonobo_Listener listener,
294                                  CORBA_Environment *ev)
295{
296        BonoboObject *bonobo_object;
297        ECorbaStorageRegistry *storage_registry;
298        ECorbaStorageRegistryPrivate *priv;
299        Bonobo_Listener listener_copy;
300        CORBA_Environment ev2;
301       
302        bonobo_object = bonobo_object_from_servant (servant);
303        storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
304        priv = storage_registry->priv;
305
306        if (find_listener (priv->listeners, listener) != NULL) {
307                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
308                                     ex_GNOME_Evolution_StorageRegistry_AlreadyListening,
309                                     NULL);
310                return;
311        }
312
313        CORBA_exception_init (&ev2);
314        listener_copy = CORBA_Object_duplicate ((CORBA_Object) listener, &ev2);
315        if (BONOBO_EX (&ev2)) {
316                g_warning ("EvolutionStorageRegistry -- Cannot duplicate listener.");
317                CORBA_exception_free (&ev2);
318                return;
319        }
320
321        CORBA_exception_free (&ev2);
322        priv->listeners = g_slist_prepend (priv->listeners, listener_copy);
323        storage_set_foreach (priv->storage_set, listener_copy);
324}
325
326static void
327impl_StorageRegistry_removeListener (PortableServer_Servant servant,
328                                     Bonobo_Listener listener,
329                                     CORBA_Environment *ev)
330{
331        BonoboObject *bonobo_object;
332        ECorbaStorageRegistry *storage_registry;
333        ECorbaStorageRegistryPrivate *priv;
334        CORBA_Environment ev2;
335        GSList *p;
336
337        bonobo_object = bonobo_object_from_servant (servant);
338        storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
339        priv = storage_registry->priv;
340
341        p = find_listener (priv->listeners, listener);
342        if (p == NULL) {
343                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
344                                     ex_GNOME_Evolution_StorageRegistry_NotFound,
345                                     NULL);
346                return;
347        }
348
349        CORBA_exception_init (&ev2);
350        CORBA_Object_release ((CORBA_Object) p->data, &ev2);
351        CORBA_exception_free (&ev2);
352       
353        priv->listeners = g_slist_remove_link (priv->listeners, p);
354        g_slist_free (p);
355}
356
357static GNOME_Evolution_Folder *
358impl_StorageRegistry_getFolderByUri (PortableServer_Servant servant,
359                                     const CORBA_char *uri,
360                                     CORBA_Environment *ev)
361{
362        BonoboObject *bonobo_object;
363        ECorbaStorageRegistry *storage_registry;
364        GNOME_Evolution_Folder *corba_folder;
365        EStorageSet *storage_set;
366        EFolder *folder;
367        char *path;
368        CORBA_char *corba_evolution_uri;
369
370        bonobo_object = bonobo_object_from_servant (servant);
371        storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object);
372        storage_set = storage_registry->priv->storage_set;
373
374        if (!strncmp (uri, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN)) {
375                corba_evolution_uri = CORBA_string_dup (uri);
376                path = (char *)uri + E_SHELL_URI_PREFIX_LEN;
377                folder = e_storage_set_get_folder (storage_set, path);
378        } else {
379                path = e_storage_set_get_path_for_physical_uri (storage_set, uri);
380                if (path) {
381                        corba_evolution_uri = CORBA_string_alloc (strlen (path) + E_SHELL_URI_PREFIX_LEN + 1);
382                        strcpy (corba_evolution_uri, E_SHELL_URI_PREFIX);
383                        strcat (corba_evolution_uri, path);
384                        folder = e_storage_set_get_folder (storage_set, path);
385                        g_free (path);
386                } else {
387                        corba_evolution_uri = NULL;
388                        folder = NULL;
389                }
390        }
391
392        if (!folder) {
393                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
394                                     ex_GNOME_Evolution_StorageRegistry_NotFound,
395                                     NULL);
396                return CORBA_OBJECT_NIL;
397        }
398
399        corba_folder = GNOME_Evolution_Folder__alloc ();
400
401        corba_folder->displayName = CORBA_string_dup (e_folder_get_name (folder));
402
403        corba_folder->description     = CORBA_string_dup (e_safe_corba_string (e_folder_get_description (folder)));
404        corba_folder->type            = CORBA_string_dup (e_folder_get_type_string (folder));
405        corba_folder->physicalUri     = CORBA_string_dup (e_safe_corba_string (e_folder_get_physical_uri (folder)));
406        corba_folder->customIconName  = CORBA_string_dup (e_safe_corba_string (e_folder_get_custom_icon_name (folder)));
407        corba_folder->evolutionUri    = corba_evolution_uri;
408        corba_folder->unreadCount     = e_folder_get_unread_count (folder);
409        corba_folder->sortingPriority = e_folder_get_sorting_priority (folder);
410
411        return corba_folder;
412}
413
414
415/* GtkObject methods.  */
416
417static void
418destroy (GtkObject *object)
419{
420        ECorbaStorageRegistry *corba_storage_registry;
421        ECorbaStorageRegistryPrivate *priv;
422
423        corba_storage_registry = E_CORBA_STORAGE_REGISTRY (object);
424        priv = corba_storage_registry->priv;
425
426        if (priv->storage_set != NULL)
427                gtk_object_unref (GTK_OBJECT (priv->storage_set));
428        g_free (priv);
429
430        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
431}
432
433
434/* Initialization.  */
435
436static void
437corba_class_init (void)
438{
439        POA_GNOME_Evolution_StorageRegistry__vepv *vepv;
440        POA_GNOME_Evolution_StorageRegistry__epv *epv;
441        PortableServer_ServantBase__epv *base_epv;
442
443        base_epv = g_new0 (PortableServer_ServantBase__epv, 1);
444        base_epv->_private    = NULL;
445        base_epv->finalize    = NULL;
446        base_epv->default_POA = NULL;
447
448        epv = g_new0 (POA_GNOME_Evolution_StorageRegistry__epv, 1);
449        epv->addStorage          = impl_StorageRegistry_addStorage;
450        epv->getStorageList      = impl_StorageRegistry_getStorageList;
451        epv->getStorageByName    = impl_StorageRegistry_getStorageByName;
452        epv->removeStorageByName = impl_StorageRegistry_removeStorageByName;
453        epv->addListener         = impl_StorageRegistry_addListener;
454        epv->removeListener      = impl_StorageRegistry_removeListener;
455        epv->getFolderByUri      = impl_StorageRegistry_getFolderByUri;
456
457        vepv = &storage_registry_vepv;
458        vepv->_base_epv                     = base_epv;
459        vepv->Bonobo_Unknown_epv            = bonobo_object_get_epv ();
460        vepv->GNOME_Evolution_StorageRegistry_epv = epv;
461}
462
463static void
464class_init (ECorbaStorageRegistryClass *klass)
465{
466        GtkObjectClass *object_class;
467
468        object_class = GTK_OBJECT_CLASS (klass);
469        object_class->destroy = destroy;
470
471        parent_class = gtk_type_class (PARENT_TYPE);
472
473        corba_class_init ();
474}
475
476static void
477init (ECorbaStorageRegistry *corba_storage_registry)
478{
479        ECorbaStorageRegistryPrivate *priv;
480
481        priv = g_new (ECorbaStorageRegistryPrivate, 1);
482        priv->storage_set = NULL;
483        priv->listeners = NULL;
484       
485        corba_storage_registry->priv = priv;
486}
487
488
489void
490e_corba_storage_registry_construct (ECorbaStorageRegistry *corba_storage_registry,
491                                    GNOME_Evolution_StorageRegistry corba_object,
492                                    EStorageSet *storage_set)
493{
494        ECorbaStorageRegistryPrivate *priv;
495
496        g_return_if_fail (corba_storage_registry != NULL);
497        g_return_if_fail (E_IS_CORBA_STORAGE_REGISTRY (corba_storage_registry));
498        g_return_if_fail (corba_object != CORBA_OBJECT_NIL);
499
500        bonobo_object_construct (BONOBO_OBJECT (corba_storage_registry), corba_object);
501
502        priv = corba_storage_registry->priv;
503
504        gtk_object_ref (GTK_OBJECT (storage_set));
505        priv->storage_set = storage_set;
506}
507
508ECorbaStorageRegistry *
509e_corba_storage_registry_new (EStorageSet *storage_set)
510{
511        ECorbaStorageRegistry *corba_storage_registry;
512        POA_GNOME_Evolution_StorageRegistry *servant;
513        GNOME_Evolution_StorageRegistry corba_object;
514
515        g_return_val_if_fail (storage_set != NULL, NULL);
516        g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL);
517
518        servant = create_servant ();
519        if (servant == NULL)
520                return NULL;
521
522        corba_storage_registry = gtk_type_new (e_corba_storage_registry_get_type ());
523
524        corba_object = bonobo_object_activate_servant (BONOBO_OBJECT (corba_storage_registry),
525                                                       servant);
526
527        e_corba_storage_registry_construct (corba_storage_registry, corba_object, storage_set);
528
529        return corba_storage_registry;
530}
531
532
533E_MAKE_TYPE (e_corba_storage_registry, "ECorbaStorageRegistry", ECorbaStorageRegistry, class_init, init, PARENT_TYPE)
Note: See TracBrowser for help on using the repository browser.