~ubuntu-branches/ubuntu/wily/evolution-data-server/wily

« back to all changes in this revision

Viewing changes to addressbook/libedata-book/e-data-book-factory.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2015-07-20 13:34:59 UTC
  • mfrom: (1.1.126) (1.2.48 sid)
  • Revision ID: package-import@ubuntu.com-20150720133459-g6y46hnu5ewtoz08
Tags: 3.16.4-0ubuntu2
debian/patches/0001-Bug-752373-Monthly-events-do-not-recur-correctly.patch:
Cherry-pick patch from upstream to fix events not recurring correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 * Copyright (C) 2006 OpenedHand Ltd
5
5
 * Copyright (C) 2009 Intel Corporation
6
6
 *
7
 
 * This library is free software; you can redistribute it and/or modify it
 
7
 * This library is free software: you can redistribute it and/or modify it
8
8
 * under the terms of the GNU Lesser General Public License as published by
9
9
 * the Free Software Foundation.
10
10
 *
11
11
 * This library is distributed in the hope that it will be useful, but
12
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
13
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14
14
 * for more details.
15
15
 *
16
16
 * You should have received a copy of the GNU Lesser General Public License
17
 
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 
17
 * along with this library. If not, see <http://www.gnu.org/licenses/>.
18
18
 *
19
 
 * Author: Ross Burton <ross@linux.intel.com>
 
19
 * Authors: Ross Burton <ross@linux.intel.com>
20
20
 */
21
21
 
22
22
/**
42
42
#include "e-book-backend-factory.h"
43
43
#include "e-data-book.h"
44
44
#include "e-data-book-factory.h"
45
 
#include "e-dbus-localed.h"
46
45
 
47
46
#define d(x)
48
47
 
51
50
        ((obj), E_TYPE_DATA_BOOK_FACTORY, EDataBookFactoryPrivate))
52
51
 
53
52
struct _EDataBookFactoryPrivate {
54
 
        ESourceRegistry *registry;
55
53
        EDBusAddressBookFactory *dbus_factory;
56
 
 
57
 
        /* This is a hash table of client bus names to an array of
58
 
         * EBookBackend references; one for every connection opened. */
59
 
        GHashTable *connections;
60
 
        GMutex connections_lock;
61
 
 
62
 
        /* This is a hash table of client bus names being watched.
63
 
         * The value is the watcher ID for g_bus_unwatch_name(). */
64
 
        GHashTable *watched_names;
65
 
        GMutex watched_names_lock;
66
 
 
67
 
        /* Watching "org.freedesktop.locale1" for locale changes */
68
 
        guint localed_watch_id;
69
 
        EDBusLocale1 *localed_proxy;
70
 
        GCancellable *localed_cancel;
71
 
        gchar *locale;
72
 
};
73
 
 
74
 
enum {
75
 
        PROP_0,
76
 
        PROP_REGISTRY
77
54
};
78
55
 
79
56
/* Forward Declarations */
88
65
                G_TYPE_INITABLE,
89
66
                e_data_book_factory_initable_init))
90
67
 
91
 
static void
92
 
watched_names_value_free (gpointer value)
93
 
{
94
 
        g_bus_unwatch_name (GPOINTER_TO_UINT (value));
95
 
}
96
 
 
97
 
static void
98
 
data_book_factory_toggle_notify_cb (gpointer data,
99
 
                                    GObject *backend,
100
 
                                    gboolean is_last_ref)
101
 
{
102
 
        if (is_last_ref) {
103
 
                /* Take a strong reference before removing the
104
 
                 * toggle reference, to keep the backend alive. */
105
 
                g_object_ref (backend);
106
 
 
107
 
                g_object_remove_toggle_ref (
108
 
                        backend, data_book_factory_toggle_notify_cb, data);
109
 
 
110
 
                g_signal_emit_by_name (backend, "shutdown");
111
 
 
112
 
                g_object_unref (backend);
113
 
        }
114
 
}
115
 
 
116
 
static void
117
 
data_book_factory_connections_add (EDataBookFactory *factory,
118
 
                                   const gchar *name,
119
 
                                   EBookBackend *backend)
120
 
{
121
 
        GHashTable *connections;
122
 
        GPtrArray *array;
123
 
 
124
 
        g_return_if_fail (name != NULL);
125
 
        g_return_if_fail (backend != NULL);
126
 
 
127
 
        g_mutex_lock (&factory->priv->connections_lock);
128
 
 
129
 
        connections = factory->priv->connections;
130
 
 
131
 
        if (g_hash_table_size (connections) == 0)
132
 
                e_dbus_server_hold (E_DBUS_SERVER (factory));
133
 
 
134
 
        array = g_hash_table_lookup (connections, name);
135
 
 
136
 
        if (array == NULL) {
137
 
                array = g_ptr_array_new_with_free_func (
138
 
                        (GDestroyNotify) g_object_unref);
139
 
                g_hash_table_insert (
140
 
                        connections, g_strdup (name), array);
141
 
        }
142
 
 
143
 
        g_ptr_array_add (array, g_object_ref (backend));
144
 
 
145
 
        g_mutex_unlock (&factory->priv->connections_lock);
146
 
}
147
 
 
148
 
static gboolean
149
 
data_book_factory_connections_remove (EDataBookFactory *factory,
150
 
                                      const gchar *name,
151
 
                                      EBookBackend *backend)
152
 
{
153
 
        GHashTable *connections;
154
 
        GPtrArray *array;
155
 
        gboolean removed = FALSE;
156
 
 
157
 
        /* If backend is NULL, we remove all backends for name. */
158
 
        g_return_val_if_fail (name != NULL, FALSE);
159
 
 
160
 
        g_mutex_lock (&factory->priv->connections_lock);
161
 
 
162
 
        connections = factory->priv->connections;
163
 
        array = g_hash_table_lookup (connections, name);
164
 
 
165
 
        if (array != NULL) {
166
 
                if (backend != NULL) {
167
 
                        removed = g_ptr_array_remove_fast (array, backend);
168
 
                } else if (array->len > 0) {
169
 
                        g_ptr_array_set_size (array, 0);
170
 
                        removed = TRUE;
171
 
                }
172
 
 
173
 
                if (array->len == 0)
174
 
                        g_hash_table_remove (connections, name);
175
 
 
176
 
                if (g_hash_table_size (connections) == 0)
177
 
                        e_dbus_server_release (E_DBUS_SERVER (factory));
178
 
        }
179
 
 
180
 
        g_mutex_unlock (&factory->priv->connections_lock);
181
 
 
182
 
        return removed;
183
 
}
184
 
 
185
 
static void
186
 
data_book_factory_connections_remove_all (EDataBookFactory *factory)
187
 
{
188
 
        GHashTable *connections;
189
 
 
190
 
        g_mutex_lock (&factory->priv->connections_lock);
191
 
 
192
 
        connections = factory->priv->connections;
193
 
 
194
 
        if (g_hash_table_size (connections) > 0) {
195
 
                g_hash_table_remove_all (connections);
196
 
                e_dbus_server_release (E_DBUS_SERVER (factory));
197
 
        }
198
 
 
199
 
        g_mutex_unlock (&factory->priv->connections_lock);
200
 
}
201
 
 
202
 
static void
203
 
data_book_factory_name_vanished_cb (GDBusConnection *connection,
204
 
                                    const gchar *name,
205
 
                                    gpointer user_data)
206
 
{
207
 
        GWeakRef *weak_ref = user_data;
 
68
static GDBusInterfaceSkeleton *
 
69
data_book_factory_get_dbus_interface_skeleton (EDBusServer *server)
 
70
{
208
71
        EDataBookFactory *factory;
209
72
 
210
 
        factory = g_weak_ref_get (weak_ref);
211
 
 
212
 
        if (factory != NULL) {
213
 
                data_book_factory_connections_remove (factory, name, NULL);
214
 
 
215
 
                /* Unwatching the bus name from here will corrupt the
216
 
                 * 'name' argument, and possibly also the 'user_data'.
217
 
                 *
218
 
                 * This is a GDBus bug.  Work around it by unwatching
219
 
                 * the bus name last.
220
 
                 *
221
 
                 * See: https://bugzilla.gnome.org/706088
222
 
                 */
223
 
                g_mutex_lock (&factory->priv->watched_names_lock);
224
 
                g_hash_table_remove (factory->priv->watched_names, name);
225
 
                g_mutex_unlock (&factory->priv->watched_names_lock);
226
 
 
227
 
                g_object_unref (factory);
228
 
        }
229
 
}
230
 
 
231
 
static void
232
 
data_book_factory_watched_names_add (EDataBookFactory *factory,
233
 
                                     GDBusConnection *connection,
234
 
                                     const gchar *name)
235
 
{
236
 
        GHashTable *watched_names;
237
 
 
238
 
        g_return_if_fail (name != NULL);
239
 
 
240
 
        g_mutex_lock (&factory->priv->watched_names_lock);
241
 
 
242
 
        watched_names = factory->priv->watched_names;
243
 
 
244
 
        if (!g_hash_table_contains (watched_names, name)) {
245
 
                guint watcher_id;
246
 
 
247
 
                /* The g_bus_watch_name() documentation says one of the two
248
 
                 * callbacks are guaranteed to be invoked after calling the
249
 
                 * function.  But which one is determined asynchronously so
250
 
                 * there should be no chance of the name vanished callback
251
 
                 * deadlocking with us when it tries to acquire the lock. */
252
 
                watcher_id = g_bus_watch_name_on_connection (
253
 
                        connection, name,
254
 
                        G_BUS_NAME_WATCHER_FLAGS_NONE,
255
 
                        (GBusNameAppearedCallback) NULL,
256
 
                        data_book_factory_name_vanished_cb,
257
 
                        e_weak_ref_new (factory),
258
 
                        (GDestroyNotify) e_weak_ref_free);
259
 
 
260
 
                g_hash_table_insert (
261
 
                        watched_names, g_strdup (name),
262
 
                        GUINT_TO_POINTER (watcher_id));
263
 
        }
264
 
 
265
 
        g_mutex_unlock (&factory->priv->watched_names_lock);
266
 
}
267
 
 
268
 
static EBackend *
269
 
data_book_factory_ref_backend (EDataFactory *factory,
270
 
                               ESource *source,
271
 
                               GError **error)
272
 
{
273
 
        EBackend *backend;
274
 
        ESourceBackend *extension;
275
 
        const gchar *extension_name;
276
 
        gchar *backend_name;
277
 
 
278
 
        /* For address books the hash key is simply the backend name.
279
 
         * (cf. calendar hash keys, which are slightly more complex) */
280
 
 
281
 
        extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
282
 
        extension = e_source_get_extension (source, extension_name);
283
 
        backend_name = e_source_backend_dup_backend_name (extension);
284
 
 
285
 
        if (backend_name == NULL || *backend_name == '\0') {
286
 
                g_set_error (
287
 
                        error, E_DATA_BOOK_ERROR,
288
 
                        E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
289
 
                        _("No backend name in source '%s'"),
290
 
                        e_source_get_display_name (source));
291
 
                g_free (backend_name);
292
 
                return NULL;
293
 
        }
294
 
 
295
 
        backend = e_data_factory_ref_initable_backend (
296
 
                factory, backend_name, source, NULL, error);
297
 
 
298
 
        g_free (backend_name);
299
 
 
300
 
        return backend;
301
 
}
302
 
 
303
 
static gchar *
304
 
construct_book_factory_path (void)
305
 
{
306
 
        static volatile gint counter = 1;
307
 
 
308
 
        g_atomic_int_inc (&counter);
309
 
 
310
 
        return g_strdup_printf (
311
 
                "/org/gnome/evolution/dataserver/AddressBook/%d/%u",
312
 
                getpid (), counter);
313
 
}
314
 
 
315
 
static void
316
 
data_book_factory_closed_cb (EBookBackend *backend,
317
 
                             const gchar *sender,
318
 
                             EDataBookFactory *factory)
319
 
{
320
 
        data_book_factory_connections_remove (factory, sender, backend);
321
 
}
322
 
 
323
 
/* This is totally backwards, for some insane reason we holding
324
 
 * references to the EBookBackends and then fetching the EDataBook
325
 
 * via e_book_backend_ref_data_book(), the whole scheme should
326
 
 * be reversed and this function probably removed.
327
 
 */
328
 
static GList *
329
 
data_book_factory_list_books (EDataBookFactory *factory)
330
 
{
331
 
        GList *books = NULL;
332
 
        GHashTable *connections;
333
 
        GHashTableIter iter;
334
 
        gpointer key, value;
335
 
 
336
 
        g_mutex_lock (&factory->priv->connections_lock);
337
 
 
338
 
        connections = factory->priv->connections;
339
 
 
340
 
        g_hash_table_iter_init (&iter, connections);
341
 
        while (g_hash_table_iter_next (&iter, &key, &value)) {
342
 
                GPtrArray *array = (GPtrArray *) value;
343
 
                gint i;
344
 
 
345
 
                for (i = 0; i < array->len; i++) {
346
 
                        EBookBackend *backend = g_ptr_array_index (array, i);
347
 
                        EDataBook *book = e_book_backend_ref_data_book (backend);
348
 
 
349
 
                        if (g_list_find (books, book) == NULL)
350
 
                                books = g_list_prepend (books, book);
351
 
                        else
352
 
                                g_object_unref (book);
353
 
                }
354
 
        }
355
 
        g_mutex_unlock (&factory->priv->connections_lock);
356
 
 
357
 
        return books;
358
 
}
359
 
 
360
 
static gchar *
361
 
data_book_factory_open (EDataBookFactory *factory,
362
 
                        GDBusConnection *connection,
363
 
                        const gchar *sender,
364
 
                        const gchar *uid,
365
 
                        GError **error)
366
 
{
367
 
        EDataBook *data_book;
368
 
        EBackend *backend;
369
 
        ESourceRegistry *registry;
370
 
        ESource *source;
371
 
        gchar *object_path;
372
 
 
373
 
        if (uid == NULL || *uid == '\0') {
374
 
                g_set_error (
375
 
                        error, E_DATA_BOOK_ERROR,
376
 
                        E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
377
 
                        _("Missing source UID"));
378
 
                return NULL;
379
 
        }
380
 
 
381
 
        registry = e_data_book_factory_get_registry (factory);
382
 
        source = e_source_registry_ref_source (registry, uid);
383
 
 
384
 
        if (source == NULL) {
385
 
                g_set_error (
386
 
                        error, E_DATA_BOOK_ERROR,
387
 
                        E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
388
 
                        _("No such source for UID '%s'"), uid);
389
 
                return NULL;
390
 
        }
391
 
 
392
 
        backend = data_book_factory_ref_backend (
393
 
                E_DATA_FACTORY (factory), source, error);
394
 
 
395
 
        g_object_unref (source);
396
 
 
397
 
        if (backend == NULL)
398
 
                return NULL;
399
 
 
400
 
        /* If the backend already has an EDataBook installed, return its
401
 
         * object path.  Otherwise we need to install a new EDataBook. */
402
 
 
403
 
        data_book = e_book_backend_ref_data_book (E_BOOK_BACKEND (backend));
404
 
 
405
 
        if (data_book != NULL) {
406
 
                object_path = g_strdup (
407
 
                        e_data_book_get_object_path (data_book));
408
 
        } else {
409
 
                object_path = construct_book_factory_path ();
410
 
 
411
 
                /* The EDataBook will attach itself to EBookBackend,
412
 
                 * so no need to call e_book_backend_set_data_book(). */
413
 
                data_book = e_data_book_new (
414
 
                        E_BOOK_BACKEND (backend),
415
 
                        connection, object_path, error);
416
 
 
417
 
                if (data_book != NULL) {
418
 
                        /* Install a toggle reference on the backend
419
 
                         * so we can signal it to shut down once all
420
 
                         * client connections are closed. */
421
 
                        g_object_add_toggle_ref (
422
 
                                G_OBJECT (backend),
423
 
                                data_book_factory_toggle_notify_cb,
424
 
                                NULL);
425
 
 
426
 
                        g_signal_connect_object (
427
 
                                backend, "closed",
428
 
                                G_CALLBACK (data_book_factory_closed_cb),
429
 
                                factory, 0);
430
 
 
431
 
                        /* Don't set the locale on a new book if we have not
432
 
                         * yet received a notification of a locale change
433
 
                         */
434
 
                        if (factory->priv->locale)
435
 
                                e_data_book_set_locale (
436
 
                                        data_book,
437
 
                                        factory->priv->locale,
438
 
                                        NULL, NULL);
439
 
                } else {
440
 
                        g_free (object_path);
441
 
                        object_path = NULL;
442
 
                }
443
 
        }
444
 
 
445
 
        if (data_book != NULL) {
446
 
                /* Watch the sender's bus name so we can clean
447
 
                 * up its connections if the bus name vanishes. */
448
 
                data_book_factory_watched_names_add (
449
 
                        factory, connection, sender);
450
 
 
451
 
                /* A client may create multiple EClient instances for the
452
 
                 * same ESource, each of which calls close() individually.
453
 
                 * So we must track each and every connection made. */
454
 
                data_book_factory_connections_add (
455
 
                        factory, sender, E_BOOK_BACKEND (backend));
456
 
        }
457
 
 
458
 
        g_clear_object (&data_book);
459
 
        g_clear_object (&backend);
460
 
 
461
 
        return object_path;
 
73
        factory = E_DATA_BOOK_FACTORY (server);
 
74
 
 
75
        return G_DBUS_INTERFACE_SKELETON (factory->priv->dbus_factory);
 
76
}
 
77
 
 
78
static const gchar *
 
79
data_book_get_factory_name (EBackendFactory *backend_factory)
 
80
{
 
81
        EBookBackendFactoryClass *class;
 
82
 
 
83
        class = E_BOOK_BACKEND_FACTORY_GET_CLASS (E_BOOK_BACKEND_FACTORY (backend_factory));
 
84
 
 
85
        return class->factory_name;
 
86
}
 
87
 
 
88
static void
 
89
data_book_complete_open (EDataFactory *data_factory,
 
90
                         GDBusMethodInvocation *invocation,
 
91
                         const gchar *object_path,
 
92
                         const gchar *bus_name,
 
93
                         const gchar *extension_name)
 
94
{
 
95
        EDataBookFactory *data_book_factory = E_DATA_BOOK_FACTORY (data_factory);
 
96
 
 
97
        e_dbus_address_book_factory_complete_open_address_book (
 
98
                data_book_factory->priv->dbus_factory, invocation, object_path, bus_name);
462
99
}
463
100
 
464
101
static gboolean
467
104
                                               const gchar *uid,
468
105
                                               EDataBookFactory *factory)
469
106
{
470
 
        GDBusConnection *connection;
471
 
        const gchar *sender;
472
 
        gchar *object_path;
473
 
        GError *error = NULL;
474
 
 
475
 
        connection = g_dbus_method_invocation_get_connection (invocation);
476
 
        sender = g_dbus_method_invocation_get_sender (invocation);
477
 
 
478
 
        object_path = data_book_factory_open (
479
 
                factory, connection, sender, uid, &error);
480
 
 
481
 
        if (object_path != NULL) {
482
 
                e_dbus_address_book_factory_complete_open_address_book (
483
 
                        iface, invocation, object_path);
484
 
                g_free (object_path);
485
 
        } else {
486
 
                g_return_val_if_fail (error != NULL, FALSE);
487
 
                g_dbus_method_invocation_take_error (invocation, error);
488
 
        }
 
107
        EDataFactory *data_factory = E_DATA_FACTORY (factory);
 
108
 
 
109
        e_data_factory_spawn_subprocess_backend (
 
110
                data_factory, invocation, uid, E_SOURCE_EXTENSION_ADDRESS_BOOK, SUBPROCESS_BOOK_BACKEND_PATH);
489
111
 
490
112
        return TRUE;
491
113
}
492
114
 
493
115
static void
494
 
data_book_factory_get_property (GObject *object,
495
 
                                guint property_id,
496
 
                                GValue *value,
497
 
                                GParamSpec *pspec)
498
 
{
499
 
        switch (property_id) {
500
 
                case PROP_REGISTRY:
501
 
                        g_value_set_object (
502
 
                                value,
503
 
                                e_data_book_factory_get_registry (
504
 
                                E_DATA_BOOK_FACTORY (object)));
505
 
                        return;
506
 
        }
507
 
 
508
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
509
 
}
510
 
 
511
 
static void
512
116
data_book_factory_dispose (GObject *object)
513
117
{
 
118
        EDataBookFactory *factory;
514
119
        EDataBookFactoryPrivate *priv;
515
120
 
516
 
        priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (object);
517
 
 
518
 
        if (priv->registry != NULL) {
519
 
                g_object_unref (priv->registry);
520
 
                priv->registry = NULL;
521
 
        }
522
 
 
523
 
        if (priv->dbus_factory != NULL) {
524
 
                g_object_unref (priv->dbus_factory);
525
 
                priv->dbus_factory = NULL;
526
 
        }
527
 
 
528
 
        if (priv->localed_cancel) {
529
 
                g_cancellable_cancel (priv->localed_cancel);
530
 
                g_object_unref (priv->localed_cancel);
531
 
                priv->localed_cancel = NULL;
532
 
        }
533
 
 
534
 
        if (priv->localed_proxy) {
535
 
                g_object_unref (priv->localed_proxy);
536
 
                priv->localed_proxy = NULL;
537
 
        }
538
 
 
539
 
        if (priv->localed_watch_id > 0)
540
 
                g_bus_unwatch_name (priv->localed_watch_id);
541
 
 
542
 
        g_hash_table_remove_all (priv->connections);
543
 
        g_hash_table_remove_all (priv->watched_names);
 
121
        factory = E_DATA_BOOK_FACTORY (object);
 
122
        priv = factory->priv;
 
123
 
 
124
        g_clear_object (&priv->dbus_factory);
544
125
 
545
126
        /* Chain up to parent's dispose() method. */
546
127
        G_OBJECT_CLASS (e_data_book_factory_parent_class)->dispose (object);
547
128
}
548
129
 
549
130
static void
550
 
data_book_factory_finalize (GObject *object)
551
 
{
552
 
        EDataBookFactoryPrivate *priv;
553
 
 
554
 
        priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (object);
555
 
 
556
 
        g_hash_table_destroy (priv->connections);
557
 
        g_mutex_clear (&priv->connections_lock);
558
 
 
559
 
        g_hash_table_destroy (priv->watched_names);
560
 
        g_mutex_clear (&priv->watched_names_lock);
561
 
 
562
 
        g_free (priv->locale);
563
 
 
564
 
        /* Chain up to parent's finalize() method. */
565
 
        G_OBJECT_CLASS (e_data_book_factory_parent_class)->finalize (object);
566
 
}
567
 
 
568
 
static void
569
 
data_book_factory_bus_acquired (EDBusServer *server,
570
 
                                GDBusConnection *connection)
571
 
{
572
 
        EDataBookFactoryPrivate *priv;
573
 
        GError *error = NULL;
574
 
 
575
 
        priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (server);
576
 
 
577
 
        g_dbus_interface_skeleton_export (
578
 
                G_DBUS_INTERFACE_SKELETON (priv->dbus_factory),
579
 
                connection,
580
 
                "/org/gnome/evolution/dataserver/AddressBookFactory",
581
 
                &error);
582
 
 
583
 
        if (error != NULL) {
584
 
                g_error (
585
 
                        "Failed to export AddressBookFactory interface: %s",
586
 
                        error->message);
587
 
                g_assert_not_reached ();
588
 
        }
589
 
 
590
 
        /* Chain up to parent's bus_acquired() method. */
591
 
        E_DBUS_SERVER_CLASS (e_data_book_factory_parent_class)->
592
 
                bus_acquired (server, connection);
593
 
}
594
 
 
595
 
static void
596
 
data_book_factory_bus_name_lost (EDBusServer *server,
597
 
                                 GDBusConnection *connection)
598
 
{
599
 
        EDataBookFactory *factory;
600
 
 
601
 
        factory = E_DATA_BOOK_FACTORY (server);
602
 
 
603
 
        data_book_factory_connections_remove_all (factory);
604
 
 
605
 
        /* Chain up to parent's bus_name_lost() method. */
606
 
        E_DBUS_SERVER_CLASS (e_data_book_factory_parent_class)->
607
 
                bus_name_lost (server, connection);
608
 
}
609
 
 
610
 
static void
611
 
data_book_factory_quit_server (EDBusServer *server,
612
 
                               EDBusServerExitCode exit_code)
613
 
{
614
 
        /* This factory does not support reloading, so stop the signal
615
 
         * emission and return without chaining up to prevent quitting. */
616
 
        if (exit_code == E_DBUS_SERVER_EXIT_RELOAD) {
617
 
                g_signal_stop_emission_by_name (server, "quit-server");
618
 
                return;
619
 
        }
620
 
 
621
 
        /* Chain up to parent's quit_server() method. */
622
 
        E_DBUS_SERVER_CLASS (e_data_book_factory_parent_class)->
623
 
                quit_server (server, exit_code);
624
 
}
625
 
 
626
 
static gchar *
627
 
data_book_factory_interpret_locale_value (const gchar *value)
628
 
{
629
 
        gchar *interpreted_value = NULL;
630
 
        gchar **split;
631
 
 
632
 
        split = g_strsplit (value, "=", 2);
633
 
 
634
 
        if (split && split[0] && split[1])
635
 
                interpreted_value = g_strdup (split[1]);
636
 
 
637
 
        g_strfreev (split);
638
 
 
639
 
        if (!interpreted_value)
640
 
                g_warning ("Failed to interpret locale value: %s", value);
641
 
 
642
 
        return interpreted_value;
643
 
}
644
 
 
645
 
static gchar *
646
 
data_book_factory_interpret_locale (const gchar * const * locale)
647
 
{
648
 
        gint i;
649
 
        gchar *interpreted_locale = NULL;
650
 
 
651
 
        /* Prioritize LC_COLLATE and then LANG values
652
 
         * in the 'locale' specified by localed.
653
 
         *
654
 
         * If localed explicitly specifies no locale, then
655
 
         * default to checking system locale.
656
 
         */
657
 
        if (locale) {
658
 
                for (i = 0; locale[i] != NULL && interpreted_locale == NULL; i++) {
659
 
                        if (strncmp (locale[i], "LC_COLLATE", 10) == 0)
660
 
                                interpreted_locale =
661
 
                                        data_book_factory_interpret_locale_value (locale[i]);
662
 
                }
663
 
 
664
 
                for (i = 0; locale[i] != NULL && interpreted_locale == NULL; i++) {
665
 
                        if (strncmp (locale[i], "LANG", 4) == 0)
666
 
                                interpreted_locale =
667
 
                                        data_book_factory_interpret_locale_value (locale[i]);
668
 
                }
669
 
        }
670
 
 
671
 
        if (!interpreted_locale) {
672
 
                const gchar *system_locale = setlocale (LC_COLLATE, NULL);
673
 
 
674
 
                interpreted_locale = g_strdup (system_locale);
675
 
        }
676
 
 
677
 
        return interpreted_locale;
678
 
}
679
 
 
680
 
static void
681
 
data_book_factory_set_locale (EDataBookFactory *factory,
682
 
                              const gchar *locale)
683
 
{
684
 
        EDataBookFactoryPrivate *priv = factory->priv;
685
 
        GError *error = NULL;
686
 
        GList *books, *l;
687
 
 
688
 
        if (g_strcmp0 (priv->locale, locale) != 0) {
689
 
 
690
 
                g_free (priv->locale);
691
 
                priv->locale = g_strdup (locale);
692
 
 
693
 
                books = data_book_factory_list_books (factory);
694
 
                for (l = books; l; l = l->next) {
695
 
                        EDataBook *book = l->data;
696
 
 
697
 
                        if (!e_data_book_set_locale (book, locale, NULL, &error)) {
698
 
                                g_warning (
699
 
                                        "Failed to set locale on addressbook: %s",
700
 
                                        error->message);
701
 
                                g_clear_error (&error);
702
 
                        }
703
 
                }
704
 
                g_list_free_full (books, g_object_unref);
705
 
        }
706
 
}
707
 
 
708
 
static void
709
 
data_book_factory_locale_changed (GObject *object,
710
 
                                  GParamSpec *pspec,
711
 
                                  gpointer user_data)
712
 
{
713
 
        EDBusLocale1 *locale_proxy = E_DBUS_LOCALE1 (object);
714
 
        EDataBookFactory *factory = (EDataBookFactory *) user_data;
715
 
        const gchar * const *locale;
716
 
        gchar *interpreted_locale;
717
 
 
718
 
        locale = e_dbus_locale1_get_locale (locale_proxy);
719
 
        interpreted_locale = data_book_factory_interpret_locale (locale);
720
 
 
721
 
        data_book_factory_set_locale (factory, interpreted_locale);
722
 
 
723
 
        g_free (interpreted_locale);
724
 
}
725
 
 
726
 
static void
727
 
data_book_factory_localed_ready (GObject *source_object,
728
 
                                 GAsyncResult *res,
729
 
                                 gpointer user_data)
730
 
{
731
 
        EDataBookFactory *factory = (EDataBookFactory *) user_data;
732
 
        GError *error = NULL;
733
 
 
734
 
        factory->priv->localed_proxy = e_dbus_locale1_proxy_new_finish (res, &error);
735
 
 
736
 
        if (factory->priv->localed_proxy == NULL) {
737
 
                g_warning ("Error fetching localed proxy: %s", error->message);
738
 
                g_error_free (error);
739
 
        }
740
 
 
741
 
        if (factory->priv->localed_cancel) {
742
 
                g_object_unref (factory->priv->localed_cancel);
743
 
                factory->priv->localed_cancel = NULL;
744
 
        }
745
 
 
746
 
        if (factory->priv->localed_proxy) {
747
 
                g_signal_connect (
748
 
                        factory->priv->localed_proxy, "notify::locale",
749
 
                        G_CALLBACK (data_book_factory_locale_changed), factory);
750
 
 
751
 
                /* Initial refresh of the locale */
752
 
                data_book_factory_locale_changed (G_OBJECT (factory->priv->localed_proxy), NULL, factory);
753
 
        }
754
 
}
755
 
 
756
 
static void
757
 
data_book_factory_localed_appeared (GDBusConnection *connection,
758
 
                                    const gchar *name,
759
 
                                    const gchar *name_owner,
760
 
                                    gpointer user_data)
761
 
{
762
 
        EDataBookFactory *factory = (EDataBookFactory *) user_data;
763
 
 
764
 
        factory->priv->localed_cancel = g_cancellable_new ();
765
 
 
766
 
        e_dbus_locale1_proxy_new (
767
 
                connection,
768
 
                G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
769
 
                "org.freedesktop.locale1",
770
 
                "/org/freedesktop/locale1",
771
 
                factory->priv->localed_cancel,
772
 
                data_book_factory_localed_ready,
773
 
                factory);
774
 
}
775
 
 
776
 
static void
777
 
data_book_factory_localed_vanished (GDBusConnection *connection,
778
 
                                    const gchar *name,
779
 
                                    gpointer user_data)
780
 
{
781
 
        EDataBookFactory *factory = (EDataBookFactory *) user_data;
782
 
 
783
 
        if (factory->priv->localed_cancel) {
784
 
                g_cancellable_cancel (factory->priv->localed_cancel);
785
 
                g_object_unref (factory->priv->localed_cancel);
786
 
                factory->priv->localed_cancel = NULL;
787
 
        }
788
 
 
789
 
        if (factory->priv->localed_proxy) {
790
 
                g_object_unref (factory->priv->localed_proxy);
791
 
                factory->priv->localed_proxy = NULL;
792
 
        }
793
 
}
794
 
 
795
 
static gboolean
796
 
data_book_factory_initable_init (GInitable *initable,
797
 
                                 GCancellable *cancellable,
798
 
                                 GError **error)
799
 
{
800
 
        EDataBookFactoryPrivate *priv;
801
 
        GBusType bus_type = G_BUS_TYPE_SYSTEM;
802
 
 
803
 
        priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (initable);
804
 
 
805
 
        priv->registry = e_source_registry_new_sync (cancellable, error);
806
 
 
807
 
        /* When running tests, we pretend to be the "org.freedesktop.locale1" service
808
 
         * on the session bus instead of the real location on the system bus.
809
 
         */
810
 
        if (g_getenv ("EDS_TESTING") != NULL)
811
 
                bus_type = G_BUS_TYPE_SESSION;
812
 
 
813
 
        /* Watch system bus for locale change notifications */
814
 
        priv->localed_watch_id =
815
 
                g_bus_watch_name (
816
 
                        bus_type,
817
 
                        "org.freedesktop.locale1",
818
 
                        G_BUS_NAME_WATCHER_FLAGS_NONE,
819
 
                        data_book_factory_localed_appeared,
820
 
                        data_book_factory_localed_vanished,
821
 
                        initable,
822
 
                        NULL);
823
 
 
824
 
        return (priv->registry != NULL);
825
 
}
826
 
 
827
 
static void
828
131
e_data_book_factory_class_init (EDataBookFactoryClass *class)
829
132
{
830
133
        GObjectClass *object_class;
841
144
        g_type_class_add_private (class, sizeof (EDataBookFactoryPrivate));
842
145
 
843
146
        object_class = G_OBJECT_CLASS (class);
844
 
        object_class->get_property = data_book_factory_get_property;
845
147
        object_class->dispose = data_book_factory_dispose;
846
 
        object_class->finalize = data_book_factory_finalize;
847
148
 
848
149
        dbus_server_class = E_DBUS_SERVER_CLASS (class);
849
150
        dbus_server_class->bus_name = ADDRESS_BOOK_DBUS_SERVICE_NAME;
850
151
        dbus_server_class->module_directory = modules_directory;
851
 
        dbus_server_class->bus_acquired = data_book_factory_bus_acquired;
852
 
        dbus_server_class->bus_name_lost = data_book_factory_bus_name_lost;
853
 
        dbus_server_class->quit_server = data_book_factory_quit_server;
854
152
 
855
153
        data_factory_class = E_DATA_FACTORY_CLASS (class);
856
154
        data_factory_class->backend_factory_type = E_TYPE_BOOK_BACKEND_FACTORY;
857
 
 
858
 
        g_object_class_install_property (
859
 
                object_class,
860
 
                PROP_REGISTRY,
861
 
                g_param_spec_object (
862
 
                        "registry",
863
 
                        "Registry",
864
 
                        "Data source registry",
865
 
                        E_TYPE_SOURCE_REGISTRY,
866
 
                        G_PARAM_READABLE |
867
 
                        G_PARAM_STATIC_STRINGS));
 
155
        data_factory_class->factory_object_path = "/org/gnome/evolution/dataserver/AddressBookFactory";
 
156
        data_factory_class->subprocess_object_path_prefix = "/org/gnome/evolution/dataserver/Subprocess/Backend/AddressBook";
 
157
        data_factory_class->subprocess_bus_name_prefix = "org.gnome.evolution.dataserver.Subprocess.Backend.AddressBook";
 
158
        data_factory_class->get_dbus_interface_skeleton = data_book_factory_get_dbus_interface_skeleton;
 
159
        data_factory_class->get_factory_name = data_book_get_factory_name;
 
160
        data_factory_class->complete_open = data_book_complete_open;
868
161
}
869
162
 
870
163
static void
871
164
e_data_book_factory_initable_init (GInitableIface *iface)
872
165
{
873
 
        iface->init = data_book_factory_initable_init;
874
166
}
875
167
 
876
168
static void
885
177
                factory->priv->dbus_factory, "handle-open-address-book",
886
178
                G_CALLBACK (data_book_factory_handle_open_address_book_cb),
887
179
                factory);
888
 
 
889
 
        factory->priv->connections = g_hash_table_new_full (
890
 
                (GHashFunc) g_str_hash,
891
 
                (GEqualFunc) g_str_equal,
892
 
                (GDestroyNotify) g_free,
893
 
                (GDestroyNotify) g_ptr_array_unref);
894
 
 
895
 
        g_mutex_init (&factory->priv->connections_lock);
896
 
        g_mutex_init (&factory->priv->watched_names_lock);
897
 
 
898
 
        factory->priv->watched_names = g_hash_table_new_full (
899
 
                (GHashFunc) g_str_hash,
900
 
                (GEqualFunc) g_str_equal,
901
 
                (GDestroyNotify) g_free,
902
 
                (GDestroyNotify) watched_names_value_free);
903
180
}
904
181
 
905
182
EDBusServer *
910
187
                E_TYPE_DATA_BOOK_FACTORY,
911
188
                cancellable, error, NULL);
912
189
}
913
 
 
914
 
/**
915
 
 * e_data_book_factory_get_registry:
916
 
 * @factory: an #EDataBookFactory
917
 
 *
918
 
 * Returns the #ESourceRegistry owned by @factory.
919
 
 *
920
 
 * Returns: the #ESourceRegistry
921
 
 *
922
 
 * Since: 3.6
923
 
 **/
924
 
ESourceRegistry *
925
 
e_data_book_factory_get_registry (EDataBookFactory *factory)
926
 
{
927
 
        g_return_val_if_fail (E_IS_DATA_BOOK_FACTORY (factory), NULL);
928
 
 
929
 
        return factory->priv->registry;
930
 
}
931