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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
2
/*
3
 
 * pas-book.c
4
 
 *
5
3
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 
4
 * Copyright (C) 2006 OpenedHand Ltd
 
5
 * Copyright (C) 2009 Intel Corporation
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or modify it under
 
8
 * the terms of version 2.1 of the GNU Lesser General Public License as
 
9
 * published by the Free Software Foundation.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful, but WITHOUT
 
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
13
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 
14
 * details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public License
 
17
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 
18
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
19
 *
 
20
 * Author: Ross Burton <ross@linux.intel.com>
6
21
 */
7
22
 
8
 
#ifdef HAVE_CONFIG_H
9
 
#include <config.h>
10
 
#endif
11
 
 
12
 
#include <bonobo/bonobo-main.h>
13
 
#include <bonobo/bonobo-arg.h>
14
 
#include "libedataserver/e-list.h"
15
 
#include <libebook/e-contact.h>
 
23
#include <unistd.h>
 
24
#include <stdlib.h>
 
25
#include <dbus/dbus.h>
 
26
#include <dbus/dbus-glib.h>
 
27
#include <dbus/dbus-glib-lowlevel.h>
 
28
#include <glib/gi18n.h>
 
29
#include <glib-object.h>
 
30
#include "e-data-book-enumtypes.h"
 
31
#include "e-data-book-factory.h"
 
32
#include "e-data-book.h"
16
33
#include "e-data-book-view.h"
17
 
#include "e-book-backend.h"
18
34
#include "e-book-backend-sexp.h"
19
 
#include "e-data-book.h"
20
 
 
21
 
static BonoboObjectClass *e_data_book_parent_class;
22
 
POA_GNOME_Evolution_Addressbook_Book__vepv e_data_book_vepv;
23
 
 
24
 
struct _EDataBookPrivate {
25
 
        EBookBackend                               *backend;
26
 
        GNOME_Evolution_Addressbook_BookListener  listener;
27
 
        ESource                                    *source;
 
35
#include "opid.h"
 
36
 
 
37
DBusGConnection *connection;
 
38
 
 
39
/* DBus glue */
 
40
static void impl_AddressBook_Book_open(EDataBook *book, gboolean only_if_exists, DBusGMethodInvocation *context);
 
41
static void impl_AddressBook_Book_remove(EDataBook *book, DBusGMethodInvocation *context);
 
42
static void impl_AddressBook_Book_getContact(EDataBook *book, const gchar *IN_uid, DBusGMethodInvocation *context);
 
43
static void impl_AddressBook_Book_getContactList(EDataBook *book, const gchar *query, DBusGMethodInvocation *context);
 
44
static void impl_AddressBook_Book_authenticateUser(EDataBook *book, const gchar *IN_user, const gchar *IN_passwd, const gchar *IN_auth_method, DBusGMethodInvocation *context);
 
45
static void impl_AddressBook_Book_addContact(EDataBook *book, const gchar *IN_vcard, DBusGMethodInvocation *context);
 
46
static void impl_AddressBook_Book_modifyContact(EDataBook *book, const gchar *IN_vcard, DBusGMethodInvocation *context);
 
47
static void impl_AddressBook_Book_removeContacts(EDataBook *book, const gchar **IN_uids, DBusGMethodInvocation *context);
 
48
static gboolean impl_AddressBook_Book_getStaticCapabilities(EDataBook *book, gchar **OUT_capabilities, GError **error);
 
49
static void impl_AddressBook_Book_getSupportedFields(EDataBook *book, DBusGMethodInvocation *context);
 
50
static void impl_AddressBook_Book_getRequiredFields(EDataBook *book, DBusGMethodInvocation *context);
 
51
static void impl_AddressBook_Book_getSupportedAuthMethods(EDataBook *book, DBusGMethodInvocation *context);
 
52
static void impl_AddressBook_Book_getBookView (EDataBook *book, const gchar *search, const guint max_results, DBusGMethodInvocation *context);
 
53
static void impl_AddressBook_Book_getChanges(EDataBook *book, const gchar *IN_change_id, DBusGMethodInvocation *context);
 
54
static gboolean impl_AddressBook_Book_cancelOperation(EDataBook *book, GError **error);
 
55
static void impl_AddressBook_Book_close(EDataBook *book, DBusGMethodInvocation *context);
 
56
#include "e-data-book-glue.h"
 
57
 
 
58
static void return_status_and_list (guint32 opid, EDataBookStatus status, GList *list, gboolean free_data);
 
59
static void data_book_return_error (DBusGMethodInvocation *context, gint code, const gchar *error_str);
 
60
 
 
61
enum {
 
62
        WRITABLE,
 
63
        CONNECTION,
 
64
        AUTH_REQUIRED,
 
65
        LAST_SIGNAL
28
66
};
29
67
 
30
 
static void
31
 
impl_GNOME_Evolution_Addressbook_Book_open (PortableServer_Servant servant,
32
 
                                            const CORBA_long opid,
33
 
                                            const CORBA_boolean only_if_exists,
34
 
                                            CORBA_Environment *ev)
35
 
{
36
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
37
 
 
38
 
        printf ("impl_GNOME_Evolution_Addressbook_Book_open (%p)\n", (gpointer) book);
39
 
 
40
 
        e_book_backend_open (e_data_book_get_backend (book), book, opid, only_if_exists);
41
 
}
42
 
 
43
 
static void
44
 
impl_GNOME_Evolution_Addressbook_Book_remove (PortableServer_Servant servant,
45
 
                                              const CORBA_long opid,
46
 
                                              CORBA_Environment *ev)
47
 
{
48
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
49
 
 
50
 
        printf ("impl_GNOME_Evolution_Addressbook_Book_remove\n");
51
 
 
52
 
        e_book_backend_remove (e_data_book_get_backend (book), book, opid);
53
 
}
54
 
 
55
 
static void
56
 
impl_GNOME_Evolution_Addressbook_Book_getContact (PortableServer_Servant servant,
57
 
                                                  const CORBA_long opid,
58
 
                                                  const CORBA_char *id,
59
 
                                                  CORBA_Environment *ev)
60
 
{
61
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
62
 
 
63
 
        printf ("impl_GNOME_Evolution_Addressbook_Book_getContact\n");
64
 
 
65
 
        e_book_backend_get_contact (e_data_book_get_backend (book), book, opid, id);
66
 
}
67
 
 
68
 
static void
69
 
impl_GNOME_Evolution_Addressbook_Book_getContactList (PortableServer_Servant servant,
70
 
                                                      const CORBA_long opid,
71
 
                                                      const CORBA_char *query,
72
 
                                                      CORBA_Environment *ev)
73
 
{
74
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
75
 
 
76
 
        printf ("impl_GNOME_Evolution_Addressbook_Book_getContactList\n");
77
 
 
78
 
        e_book_backend_get_contact_list (e_data_book_get_backend (book), book, opid, query);
79
 
}
80
 
 
81
 
static void
82
 
impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant servant,
83
 
                                                        const CORBA_long opid,
84
 
                                                        const gchar * user,
85
 
                                                        const gchar * passwd,
86
 
                                                        const gchar * auth_method,
87
 
                                                        CORBA_Environment *ev)
88
 
{
89
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
90
 
 
91
 
        e_book_backend_authenticate_user (e_data_book_get_backend (book), book,
92
 
                                          opid, user, passwd, auth_method);
93
 
}
94
 
 
95
 
static void
96
 
impl_GNOME_Evolution_Addressbook_Book_addContact (PortableServer_Servant servant,
97
 
                                                  const CORBA_long opid,
98
 
                                                  const CORBA_char *vcard,
99
 
                                                  CORBA_Environment *ev)
100
 
{
101
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
102
 
 
103
 
        e_book_backend_create_contact (e_data_book_get_backend (book), book, opid, vcard);
104
 
}
105
 
 
106
 
static void
107
 
impl_GNOME_Evolution_Addressbook_Book_removeContacts (PortableServer_Servant servant,
108
 
                                                      const CORBA_long opid,
109
 
                                                      const GNOME_Evolution_Addressbook_ContactIdList *ids,
110
 
                                                      CORBA_Environment *ev)
111
 
{
112
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
113
 
        gint i;
114
 
        GList *id_list = NULL;
115
 
 
116
 
        for (i = 0; i < ids->_length; i ++)
117
 
                id_list = g_list_append (id_list, ids->_buffer[i]);
118
 
 
119
 
        e_book_backend_remove_contacts (e_data_book_get_backend (book), book, opid, id_list);
120
 
 
121
 
        g_list_free (id_list);
122
 
}
123
 
 
124
 
static void
125
 
impl_GNOME_Evolution_Addressbook_Book_modifyContact (PortableServer_Servant servant,
126
 
                                                     const CORBA_long opid,
127
 
                                                     const CORBA_char *vcard,
128
 
                                                     CORBA_Environment *ev)
129
 
{
130
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
131
 
 
132
 
        e_book_backend_modify_contact (e_data_book_get_backend (book), book, opid, vcard);
133
 
}
134
 
 
135
 
static void
136
 
impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servant,
137
 
                                                   const CORBA_long opid,
138
 
                                                   const GNOME_Evolution_Addressbook_BookViewListener listener,
139
 
                                                   const CORBA_char *search,
140
 
                                                   const GNOME_Evolution_Addressbook_stringlist* requested_fields,
141
 
                                                   const CORBA_long max_results,
142
 
                                                   CORBA_Environment *ev)
143
 
{
144
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
 
68
static guint signals[LAST_SIGNAL] = { 0 };
 
69
 
 
70
static GThreadPool *op_pool;
 
71
 
 
72
typedef enum {
 
73
        OP_OPEN,
 
74
        OP_AUTHENTICATE,
 
75
        OP_ADD_CONTACT,
 
76
        OP_GET_CONTACT,
 
77
        OP_GET_CONTACTS,
 
78
        OP_MODIFY_CONTACT,
 
79
        OP_REMOVE_CONTACTS,
 
80
        OP_GET_CHANGES,
 
81
} OperationID;
 
82
 
 
83
typedef struct {
 
84
        OperationID op;
 
85
        guint32 id; /* operation id */
 
86
        EDataBook *book; /* book */
 
87
        union {
 
88
                /* OP_OPEN */
 
89
                gboolean only_if_exists;
 
90
                /* OP_AUTHENTICATE */
 
91
                struct {
 
92
                        gchar *username;
 
93
                        gchar *password;
 
94
                        gchar *method;
 
95
                } auth;
 
96
                /* OP_ADD_CONTACT */
 
97
                /* OP_MODIFY_CONTACT */
 
98
                gchar *vcard;
 
99
                /* OP_GET_CONTACT */
 
100
                gchar *uid;
 
101
                /* OP_GET_CONTACTS */
 
102
                gchar *query;
 
103
                /* OP_MODIFY_CONTACT */
 
104
                gchar **vcards;
 
105
                /* OP_REMOVE_CONTACTS */
 
106
                GList *ids;
 
107
                /* OP_GET_CHANGES */
 
108
                gchar *change_id;
 
109
        } d;
 
110
} OperationData;
 
111
 
 
112
static void
 
113
operation_thread (gpointer data, gpointer user_data)
 
114
{
 
115
        OperationData *op = data;
 
116
        EBookBackend *backend;
 
117
 
 
118
        backend = e_data_book_get_backend (op->book);
 
119
 
 
120
        switch (op->op) {
 
121
        case OP_OPEN:
 
122
                e_book_backend_open (backend, op->book, op->id, op->d.only_if_exists);
 
123
                break;
 
124
        case OP_AUTHENTICATE:
 
125
                e_book_backend_authenticate_user (backend, op->book, op->id,
 
126
                                                  op->d.auth.username,
 
127
                                                  op->d.auth.password,
 
128
                                                  op->d.auth.method);
 
129
                g_free (op->d.auth.username);
 
130
                g_free (op->d.auth.password);
 
131
                g_free (op->d.auth.method);
 
132
                break;
 
133
        case OP_ADD_CONTACT:
 
134
                e_book_backend_create_contact (backend, op->book, op->id, op->d.vcard);
 
135
                g_free (op->d.vcard);
 
136
                break;
 
137
        case OP_GET_CONTACT:
 
138
                e_book_backend_get_contact (backend, op->book, op->id, op->d.uid);
 
139
                g_free (op->d.uid);
 
140
                break;
 
141
        case OP_GET_CONTACTS:
 
142
                e_book_backend_get_contact_list (backend, op->book, op->id, op->d.query);
 
143
                g_free (op->d.query);
 
144
                break;
 
145
        case OP_MODIFY_CONTACT:
 
146
                e_book_backend_modify_contact (backend, op->book, op->id, op->d.vcard);
 
147
                g_free (op->d.vcard);
 
148
                break;
 
149
        case OP_REMOVE_CONTACTS:
 
150
                e_book_backend_remove_contacts (backend, op->book, op->id, op->d.ids);
 
151
                g_list_foreach (op->d.ids, (GFunc)g_free, NULL);
 
152
                g_list_free (op->d.ids);
 
153
                break;
 
154
        case OP_GET_CHANGES:
 
155
                e_book_backend_get_changes (backend, op->book, op->id, op->d.change_id);
 
156
                g_free (op->d.change_id);
 
157
                break;
 
158
        }
 
159
 
 
160
        g_object_unref (op->book);
 
161
        g_slice_free (OperationData, op);
 
162
}
 
163
 
 
164
static OperationData *
 
165
op_new (OperationID op, EDataBook *book, DBusGMethodInvocation *context)
 
166
{
 
167
        OperationData *data;
 
168
 
 
169
        data = g_slice_new0 (OperationData);
 
170
        data->op = op;
 
171
        data->book = g_object_ref (book);
 
172
        data->id = opid_store (context);
 
173
 
 
174
        return data;
 
175
}
 
176
 
 
177
/* Create the EDataBook error quark */
 
178
GQuark
 
179
e_data_book_error_quark (void)
 
180
{
 
181
        static GQuark quark = 0;
 
182
        if (G_UNLIKELY (quark == 0))
 
183
                quark = g_quark_from_static_string ("e-data-book-error");
 
184
        return quark;
 
185
}
 
186
 
 
187
/* Generate the GObject boilerplate */
 
188
G_DEFINE_TYPE(EDataBook, e_data_book, G_TYPE_OBJECT)
 
189
 
 
190
static void
 
191
e_data_book_dispose (GObject *object)
 
192
{
 
193
        EDataBook *book = E_DATA_BOOK (object);
 
194
 
 
195
        if (book->backend) {
 
196
                g_object_unref (book->backend);
 
197
                book->backend = NULL;
 
198
        }
 
199
 
 
200
        if (book->source) {
 
201
                g_object_unref (book->source);
 
202
                book->source = NULL;
 
203
        }
 
204
 
 
205
        G_OBJECT_CLASS (e_data_book_parent_class)->dispose (object);
 
206
}
 
207
 
 
208
static void
 
209
e_data_book_class_init (EDataBookClass *e_data_book_class)
 
210
{
 
211
        GObjectClass *object_class = G_OBJECT_CLASS (e_data_book_class);
 
212
 
 
213
        object_class->dispose = e_data_book_dispose;
 
214
 
 
215
        signals[WRITABLE] =
 
216
                g_signal_new ("writable",
 
217
                              G_OBJECT_CLASS_TYPE (e_data_book_class),
 
218
                              G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
 
219
                              0,
 
220
                              NULL, NULL,
 
221
                              g_cclosure_marshal_VOID__BOOLEAN,
 
222
                              G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 
223
 
 
224
        signals[CONNECTION] =
 
225
                g_signal_new ("connection",
 
226
                              G_OBJECT_CLASS_TYPE (e_data_book_class),
 
227
                              G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
 
228
                              0,
 
229
                              NULL, NULL,
 
230
                              g_cclosure_marshal_VOID__BOOLEAN,
 
231
                              G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 
232
 
 
233
        signals[AUTH_REQUIRED] =
 
234
                g_signal_new ("auth-required",
 
235
                              G_OBJECT_CLASS_TYPE (e_data_book_class),
 
236
                              G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
 
237
                              0,
 
238
                              NULL, NULL,
 
239
                              g_cclosure_marshal_VOID__VOID,
 
240
                              G_TYPE_NONE, 0);
 
241
 
 
242
        dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (e_data_book_class), &dbus_glib_e_data_book_object_info);
 
243
 
 
244
        dbus_g_error_domain_register (E_DATA_BOOK_ERROR, NULL, E_TYPE_DATA_BOOK_STATUS);
 
245
 
 
246
        op_pool = g_thread_pool_new (operation_thread, NULL, 10, FALSE, NULL);
 
247
        /* Kill threads which don't do anything for 10 seconds */
 
248
        g_thread_pool_set_max_idle_time (10 * 1000);
 
249
}
 
250
 
 
251
/* Instance init */
 
252
static void
 
253
e_data_book_init (EDataBook *ebook)
 
254
{
 
255
}
 
256
 
 
257
EDataBook *
 
258
e_data_book_new (EBookBackend *backend, ESource *source)
 
259
{
 
260
        EDataBook *book;
 
261
 
 
262
        book = g_object_new (E_TYPE_DATA_BOOK, NULL);
 
263
        book->backend = g_object_ref (backend);
 
264
        book->source = g_object_ref (source);
 
265
 
 
266
        return book;
 
267
}
 
268
 
 
269
ESource*
 
270
e_data_book_get_source (EDataBook *book)
 
271
{
 
272
        g_return_val_if_fail (book != NULL, NULL);
 
273
 
 
274
        return book->source;
 
275
}
 
276
 
 
277
EBookBackend*
 
278
e_data_book_get_backend (EDataBook *book)
 
279
{
 
280
        g_return_val_if_fail (book != NULL, NULL);
 
281
 
 
282
        return book->backend;
 
283
}
 
284
 
 
285
static void
 
286
impl_AddressBook_Book_open(EDataBook *book, gboolean only_if_exists, DBusGMethodInvocation *context)
 
287
{
 
288
        OperationData *op;
 
289
 
 
290
        op = op_new (OP_OPEN, book, context);
 
291
        op->d.only_if_exists = only_if_exists;
 
292
        g_thread_pool_push (op_pool, op, NULL);
 
293
}
 
294
 
 
295
void
 
296
e_data_book_respond_open (EDataBook *book, guint opid, EDataBookStatus status)
 
297
{
 
298
        DBusGMethodInvocation *context = opid_fetch (opid);
 
299
 
 
300
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
301
                data_book_return_error (context, status, _("Cannot open book"));
 
302
        } else {
 
303
                dbus_g_method_return (context);
 
304
        }
 
305
}
 
306
 
 
307
static void
 
308
impl_AddressBook_Book_remove(EDataBook *book, DBusGMethodInvocation *context)
 
309
{
 
310
        e_book_backend_remove (book->backend, book, opid_store (context));
 
311
}
 
312
 
 
313
void
 
314
e_data_book_respond_remove (EDataBook *book, guint opid, EDataBookStatus status)
 
315
{
 
316
        DBusGMethodInvocation *context = opid_fetch (opid);
 
317
 
 
318
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
319
                data_book_return_error (context, status, _("Cannot remove book"));
 
320
        } else {
 
321
                dbus_g_method_return (context);
 
322
        }
 
323
}
 
324
 
 
325
static void
 
326
impl_AddressBook_Book_getContact (EDataBook *book, const gchar *IN_uid, DBusGMethodInvocation *context)
 
327
{
 
328
        OperationData *op;
 
329
 
 
330
        if (IN_uid == NULL) {
 
331
                data_book_return_error (context, E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND, _("Cannot get contact"));
 
332
                return;
 
333
        }
 
334
 
 
335
        op = op_new (OP_GET_CONTACT, book, context);
 
336
        op->d.uid = g_strdup (IN_uid);
 
337
        g_thread_pool_push (op_pool, op, NULL);
 
338
}
 
339
 
 
340
void
 
341
e_data_book_respond_get_contact (EDataBook *book, guint32 opid, EDataBookStatus status, const gchar *vcard)
 
342
{
 
343
        DBusGMethodInvocation *context = opid_fetch (opid);
 
344
 
 
345
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
346
                data_book_return_error  (context, status, _("Cannot get contact"));
 
347
        } else {
 
348
                dbus_g_method_return (context, vcard);
 
349
        }
 
350
}
 
351
 
 
352
static void
 
353
impl_AddressBook_Book_getContactList (EDataBook *book, const gchar *query, DBusGMethodInvocation *context)
 
354
{
 
355
        OperationData *op;
 
356
 
 
357
        if (query == NULL || query[0] == '\0') {
 
358
                data_book_return_error (context, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Empty query"));
 
359
                return;
 
360
        }
 
361
 
 
362
        op = op_new (OP_GET_CONTACTS, book, context);
 
363
        op->d.query = g_strdup (query);
 
364
        g_thread_pool_push (op_pool, op, NULL);
 
365
}
 
366
 
 
367
void
 
368
e_data_book_respond_get_contact_list (EDataBook *book, guint32 opid, EDataBookStatus status, GList *cards)
 
369
{
 
370
        return_status_and_list (opid, status, cards, TRUE);
 
371
}
 
372
 
 
373
static void
 
374
impl_AddressBook_Book_authenticateUser(EDataBook *book, const gchar *IN_user, const gchar *IN_passwd, const gchar *IN_auth_method, DBusGMethodInvocation *context)
 
375
{
 
376
        OperationData *op;
 
377
 
 
378
        op = op_new (OP_AUTHENTICATE, book, context);
 
379
        op->d.auth.username = g_strdup (IN_user);
 
380
        op->d.auth.password = g_strdup (IN_passwd);
 
381
        op->d.auth.method = g_strdup (IN_auth_method);
 
382
        g_thread_pool_push (op_pool, op, NULL);
 
383
}
 
384
 
 
385
static void
 
386
data_book_return_error (DBusGMethodInvocation *context, gint code, const gchar *error_str)
 
387
{
 
388
        GError *error;
 
389
 
 
390
        error = g_error_new (E_DATA_BOOK_ERROR, code, "%s", error_str);
 
391
        dbus_g_method_return_error (context, error);
 
392
 
 
393
        g_error_free (error);
 
394
}
 
395
 
 
396
void
 
397
e_data_book_respond_authenticate_user (EDataBook *book, guint32 opid, EDataBookStatus status)
 
398
{
 
399
        DBusGMethodInvocation *context = opid_fetch (opid);
 
400
 
 
401
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
402
                data_book_return_error (context, status, _("Cannot authenticate user"));
 
403
        } else {
 
404
                dbus_g_method_return (context);
 
405
        }
 
406
}
 
407
 
 
408
static void
 
409
impl_AddressBook_Book_addContact (EDataBook *book, const gchar *IN_vcard, DBusGMethodInvocation *context)
 
410
{
 
411
        OperationData *op;
 
412
 
 
413
        if (IN_vcard == NULL || IN_vcard[0] == '\0') {
 
414
                data_book_return_error (context, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Cannot add contact"));
 
415
                return;
 
416
        }
 
417
 
 
418
        op = op_new (OP_ADD_CONTACT, book, context);
 
419
        op->d.vcard = g_strdup (IN_vcard);
 
420
        g_thread_pool_push (op_pool, op, NULL);
 
421
}
 
422
 
 
423
void
 
424
e_data_book_respond_create (EDataBook *book, guint32 opid, EDataBookStatus status, EContact *contact)
 
425
{
 
426
        DBusGMethodInvocation *context = opid_fetch (opid);
 
427
 
 
428
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
429
                data_book_return_error (context, status, _("Cannot add contact"));
 
430
        } else {
 
431
                e_book_backend_notify_update (e_data_book_get_backend (book), contact);
 
432
                e_book_backend_notify_complete (e_data_book_get_backend (book));
 
433
 
 
434
                dbus_g_method_return (context, e_contact_get_const (contact, E_CONTACT_UID));
 
435
        }
 
436
}
 
437
 
 
438
static void
 
439
impl_AddressBook_Book_modifyContact (EDataBook *book, const gchar *IN_vcard, DBusGMethodInvocation *context)
 
440
{
 
441
        OperationData *op;
 
442
 
 
443
        if (IN_vcard == NULL) {
 
444
                data_book_return_error (context, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Cannot modify contact"));
 
445
                return;
 
446
        }
 
447
 
 
448
        op = op_new (OP_MODIFY_CONTACT, book, context);
 
449
        op->d.vcard = g_strdup (IN_vcard);
 
450
        g_thread_pool_push (op_pool, op, NULL);
 
451
}
 
452
 
 
453
void
 
454
e_data_book_respond_modify (EDataBook *book, guint32 opid, EDataBookStatus status, EContact *contact)
 
455
{
 
456
        DBusGMethodInvocation *context = opid_fetch (opid);
 
457
 
 
458
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
459
                data_book_return_error (context, status, _("Cannot modify contact"));
 
460
        } else {
 
461
                e_book_backend_notify_update (e_data_book_get_backend (book), contact);
 
462
                e_book_backend_notify_complete (e_data_book_get_backend (book));
 
463
 
 
464
                dbus_g_method_return (context);
 
465
        }
 
466
}
 
467
 
 
468
static void
 
469
impl_AddressBook_Book_removeContacts(EDataBook *book, const gchar **IN_uids, DBusGMethodInvocation *context)
 
470
{
 
471
        OperationData *op;
 
472
 
 
473
        /* Allow an empty array to be removed */
 
474
        if (IN_uids == NULL) {
 
475
                dbus_g_method_return (context);
 
476
                return;
 
477
        }
 
478
 
 
479
        op = op_new (OP_REMOVE_CONTACTS, book, context);
 
480
 
 
481
        for (; *IN_uids; IN_uids++) {
 
482
                op->d.ids = g_list_prepend (op->d.ids, g_strdup (*IN_uids));
 
483
        }
 
484
 
 
485
        g_thread_pool_push (op_pool, op, NULL);
 
486
}
 
487
 
 
488
void
 
489
e_data_book_respond_remove_contacts (EDataBook *book, guint32 opid, EDataBookStatus status, GList *ids)
 
490
{
 
491
        DBusGMethodInvocation *context = opid_fetch (opid);
 
492
 
 
493
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
494
                data_book_return_error (context, status, _("Cannot remove contacts"));
 
495
        } else {
 
496
                GList *i;
 
497
 
 
498
                for (i = ids; i; i = i->next)
 
499
                        e_book_backend_notify_remove (e_data_book_get_backend (book), i->data);
 
500
                e_book_backend_notify_complete (e_data_book_get_backend (book));
 
501
 
 
502
                dbus_g_method_return (context);
 
503
        }
 
504
}
 
505
 
 
506
static gboolean
 
507
impl_AddressBook_Book_getStaticCapabilities(EDataBook *book, gchar **OUT_capabilities, GError **error)
 
508
{
 
509
        *OUT_capabilities = e_book_backend_get_static_capabilities (e_data_book_get_backend (book));
 
510
        return TRUE;
 
511
}
 
512
 
 
513
static void
 
514
impl_AddressBook_Book_getSupportedFields(EDataBook *book, DBusGMethodInvocation *context)
 
515
{
 
516
        e_book_backend_get_supported_fields (e_data_book_get_backend (book), book, opid_store (context));
 
517
}
 
518
 
 
519
void
 
520
e_data_book_respond_get_supported_fields (EDataBook *book, guint32 opid, EDataBookStatus status, GList *fields)
 
521
{
 
522
        return_status_and_list (opid, status, fields, FALSE);
 
523
}
 
524
 
 
525
static void
 
526
impl_AddressBook_Book_getRequiredFields(EDataBook *book, DBusGMethodInvocation *context)
 
527
{
 
528
        e_book_backend_get_required_fields (e_data_book_get_backend (book), book, opid_store (context));
 
529
}
 
530
 
 
531
void
 
532
e_data_book_respond_get_required_fields (EDataBook *book, guint32 opid, EDataBookStatus status, GList *fields)
 
533
{
 
534
        return_status_and_list (opid, status, fields, FALSE);
 
535
}
 
536
 
 
537
static void
 
538
impl_AddressBook_Book_getSupportedAuthMethods(EDataBook *book, DBusGMethodInvocation *context)
 
539
{
 
540
        e_book_backend_get_supported_auth_methods (e_data_book_get_backend (book), book, opid_store (context));
 
541
}
 
542
 
 
543
void
 
544
e_data_book_respond_get_supported_auth_methods (EDataBook *book, guint32 opid, EDataBookStatus status, GList *auth_methods)
 
545
{
 
546
        return_status_and_list (opid, status, auth_methods, FALSE);
 
547
}
 
548
 
 
549
static gchar *
 
550
construct_bookview_path (void)
 
551
{
 
552
        static volatile guint counter = 1;
 
553
 
 
554
        return g_strdup_printf ("/org/gnome/evolution/dataserver/addressbook/BookView/%d/%d",
 
555
                                getpid (),
 
556
                                g_atomic_int_exchange_and_add ((int*)&counter, 1));
 
557
}
 
558
 
 
559
static void
 
560
impl_AddressBook_Book_getBookView (EDataBook *book, const gchar *search, const guint max_results, DBusGMethodInvocation *context)
 
561
{
145
562
        EBookBackend *backend = e_data_book_get_backend (book);
146
563
        EBookBackendSExp *card_sexp;
147
 
        EDataBookView *view;
148
 
 
149
 
        g_warning ("impl_GNOME_Evolution_Addressbook_Book_getBookView (%s)\n", search);
150
 
 
151
 
        /* we handle this entirely here, since it doesn't require any
152
 
           backend involvement now that we have e_data_book_view_start to
153
 
           actually kick off the search. */
 
564
        EDataBookView *book_view;
 
565
        gchar *path;
154
566
 
155
567
        card_sexp = e_book_backend_sexp_new (search);
156
568
        if (!card_sexp) {
157
 
                e_data_book_respond_get_book_view (book, opid, GNOME_Evolution_Addressbook_InvalidQuery, NULL);
158
 
                return;
159
 
        }
160
 
 
161
 
        /* XXX still need to add requested_fields here */
162
 
        view = e_data_book_view_new (backend, listener, search, card_sexp, max_results);
163
 
 
164
 
        if (!view) {
165
 
                g_object_unref (card_sexp);
166
 
                e_data_book_respond_get_book_view (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
167
 
                return;
168
 
        }
169
 
 
170
 
        e_book_backend_add_book_view (backend, view);
171
 
 
172
 
        e_data_book_respond_get_book_view (book, opid, GNOME_Evolution_Addressbook_Success, view);
173
 
}
174
 
 
175
 
static void
176
 
impl_GNOME_Evolution_Addressbook_Book_getChanges (PortableServer_Servant servant,
177
 
                                                  const CORBA_long opid,
178
 
                                                  const CORBA_char *change_id,
179
 
                                                  CORBA_Environment *ev)
180
 
{
181
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
182
 
 
183
 
        e_book_backend_get_changes (e_data_book_get_backend (book), book, opid, change_id);
184
 
}
185
 
 
186
 
static gchar *
187
 
impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities (PortableServer_Servant servant,
188
 
                                                             CORBA_Environment *ev)
189
 
{
190
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
191
 
        gchar *temp;
192
 
        gchar *ret_val;
193
 
 
194
 
        temp = e_book_backend_get_static_capabilities (book->priv->backend);
195
 
        ret_val = CORBA_string_dup(temp);
196
 
        g_free(temp);
197
 
        return ret_val;
198
 
}
199
 
 
200
 
static void
201
 
impl_GNOME_Evolution_Addressbook_Book_getRequiredFields (PortableServer_Servant servant,
202
 
                                                          const CORBA_long opid,
203
 
                                                          CORBA_Environment *ev)
204
 
 
205
 
{
206
 
 
207
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
208
 
 
209
 
        e_book_backend_get_required_fields (e_data_book_get_backend (book), book, opid);
210
 
 
211
 
}
212
 
 
213
 
static void
214
 
impl_GNOME_Evolution_Addressbook_Book_getSupportedFields (PortableServer_Servant servant,
215
 
                                                          const CORBA_long opid,
216
 
                                                          CORBA_Environment *ev)
217
 
{
218
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
219
 
 
220
 
        e_book_backend_get_supported_fields (e_data_book_get_backend (book), book, opid);
221
 
}
222
 
 
223
 
static void
224
 
impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Servant servant,
225
 
                                                               const CORBA_long opid,
226
 
                                                               CORBA_Environment *ev)
227
 
{
228
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
229
 
 
230
 
        e_book_backend_get_supported_auth_methods (e_data_book_get_backend (book), book, opid);
231
 
}
232
 
 
233
 
static GNOME_Evolution_Addressbook_CallStatus
234
 
impl_GNOME_Evolution_Addressbook_Book_cancelOperation (PortableServer_Servant servant,
235
 
                                                       CORBA_Environment *ev)
236
 
{
237
 
        EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
238
 
 
239
 
        return e_book_backend_cancel_operation (e_data_book_get_backend (book), book);
240
 
}
241
 
 
242
 
/**
243
 
 * e_data_book_get_backend:
244
 
 * @book: an #EDataBook
245
 
 *
246
 
 * Gets the #EBookBackend being used to store data for @book.
247
 
 *
248
 
 * Return value: The #EBookBackend being used.
249
 
 **/
250
 
EBookBackend *
251
 
e_data_book_get_backend (EDataBook *book)
252
 
{
253
 
        g_return_val_if_fail (book && E_IS_DATA_BOOK (book), NULL);
254
 
 
255
 
        return book->priv->backend;
256
 
}
257
 
 
258
 
/**
259
 
 * e_data_book_get_listener:
260
 
 * @book: an #EDataBook
261
 
 *
262
 
 * Gets the CORBA listener associated with @book.
263
 
 *
264
 
 * Return value: A #GNOME_Evolution_Addressbook_BookListener.
265
 
 **/
266
 
GNOME_Evolution_Addressbook_BookListener
267
 
e_data_book_get_listener (EDataBook *book)
268
 
{
269
 
        g_return_val_if_fail (book && E_IS_DATA_BOOK (book), CORBA_OBJECT_NIL);
270
 
 
271
 
        return book->priv->listener;
272
 
}
273
 
 
274
 
/**
275
 
 * e_data_book_get_source:
276
 
 * @book: an #EDataBook
277
 
 *
278
 
 * Gets the #ESource associated with @book.
279
 
 *
280
 
 * Return value: An #ESource.
281
 
 **/
282
 
ESource *
283
 
e_data_book_get_source (EDataBook *book)
284
 
{
285
 
        return book->priv->source;
286
 
}
287
 
 
288
 
/**
289
 
 * e_data_book_respond_open:
290
 
 * @book: an #EDataBook
291
 
 * @opid: the operation ID that generated the response
292
 
 * @status: the outcome of the operation
293
 
 *
294
 
 * Respond to an 'open' request specified by @opid on @book,
295
 
 * indicating @status as the outcome.
296
 
 **/
297
 
void
298
 
e_data_book_respond_open (EDataBook                              *book,
299
 
                          guint32                                 opid,
300
 
                          GNOME_Evolution_Addressbook_CallStatus  status)
301
 
{
302
 
        CORBA_Environment ev;
303
 
 
304
 
        CORBA_exception_init (&ev);
305
 
        GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (book->priv->listener, opid, status, &ev);
306
 
 
307
 
        if (ev._major != CORBA_NO_EXCEPTION) {
308
 
                g_warning ("e_data_book_respond_open: Exception "
309
 
                           "responding to BookListener!\n");
310
 
        }
311
 
 
312
 
        CORBA_exception_free (&ev);
313
 
}
314
 
 
315
 
/**
316
 
 * e_data_book_respond_remove:
317
 
 * @book: an #EDataBook
318
 
 * @opid: the operation ID that generated the response
319
 
 * @status: the outcome of the operation
320
 
 *
321
 
 * Respond to a 'remove' request to remove all of @book's data,
322
 
 * specified by @opid, indicating @status as the outcome.
323
 
 **/
324
 
void
325
 
e_data_book_respond_remove (EDataBook                           *book,
326
 
                            guint32                              opid,
327
 
                            GNOME_Evolution_Addressbook_CallStatus  status)
328
 
{
329
 
        CORBA_Environment ev;
330
 
 
331
 
        CORBA_exception_init (&ev);
332
 
        GNOME_Evolution_Addressbook_BookListener_notifyBookRemoved (book->priv->listener, opid, status, &ev);
333
 
 
334
 
        if (ev._major != CORBA_NO_EXCEPTION) {
335
 
                g_warning ("e_data_book_respond_remove: Exception "
336
 
                           "responding to BookListener!\n");
337
 
        }
338
 
 
339
 
        CORBA_exception_free (&ev);
340
 
}
341
 
 
342
 
/**
343
 
 * e_data_book_respond_create:
344
 
 * @book: an #EDataBook
345
 
 * @opid: the operation ID that generated the response
346
 
 * @status: the outcome of the operation
347
 
 * @contact: the contact created, or %NULL
348
 
 *
349
 
 * Respond to a 'create' request specified by @opid on @book,
350
 
 * indicating @status as the outcome.
351
 
 **/
352
 
void
353
 
e_data_book_respond_create (EDataBook                              *book,
354
 
                            guint32                                 opid,
355
 
                            GNOME_Evolution_Addressbook_CallStatus  status,
356
 
                            EContact                               *contact)
357
 
{
358
 
        CORBA_Environment ev;
359
 
 
360
 
        if (status == GNOME_Evolution_Addressbook_Success) {
361
 
                e_book_backend_notify_update (book->priv->backend, contact);
362
 
                e_book_backend_notify_complete (book->priv->backend);
363
 
        }
364
 
 
365
 
        CORBA_exception_init (&ev);
366
 
 
367
 
        GNOME_Evolution_Addressbook_BookListener_notifyContactCreated (
368
 
                book->priv->listener, opid, status,
369
 
                status == GNOME_Evolution_Addressbook_Success ? e_contact_get_const (contact, E_CONTACT_UID) : "",
370
 
                &ev);
371
 
 
372
 
        if (ev._major != CORBA_NO_EXCEPTION) {
373
 
                g_warning ("e_data_book_respond_create: Exception "
374
 
                           "responding to BookListener!\n");
375
 
        }
376
 
 
377
 
        CORBA_exception_free (&ev);
378
 
}
379
 
 
380
 
/**
381
 
 * e_data_book_respond_remove_contacts:
382
 
 * @book: an #EDataBook
383
 
 * @opid: the operation ID that generated the response
384
 
 * @status: the outcome of the operation
385
 
 * @ids: a list of contact IDs removed
386
 
 *
387
 
 * Respond to a 'remove contacts' request specified by @opid on @book,
388
 
 * indicating @status as the outcome.
389
 
 **/
390
 
void
391
 
e_data_book_respond_remove_contacts (EDataBook                              *book,
392
 
                                     guint32                                 opid,
393
 
                                     GNOME_Evolution_Addressbook_CallStatus  status,
394
 
                                     GList                                  *ids)
395
 
{
396
 
        CORBA_Environment ev;
397
 
        GList *i;
398
 
 
399
 
        CORBA_exception_init (&ev);
400
 
 
401
 
        if (ids) {
402
 
                for (i = ids; i; i = i->next)
403
 
                        e_book_backend_notify_remove (book->priv->backend, i->data);
404
 
                e_book_backend_notify_complete (book->priv->backend);
405
 
        }
406
 
 
407
 
        GNOME_Evolution_Addressbook_BookListener_notifyContactsRemoved (
408
 
                book->priv->listener, opid, status, &ev);
409
 
 
410
 
        if (ev._major != CORBA_NO_EXCEPTION) {
411
 
                g_warning ("e_data_book_respond_remove: Exception "
412
 
                           "responding to BookListener!\n");
413
 
        }
414
 
 
415
 
        CORBA_exception_free (&ev);
416
 
}
417
 
 
418
 
/**
419
 
 * e_data_book_respond_modify:
420
 
 * @book: an #EDataBook
421
 
 * @opid: the operation ID that generated the response
422
 
 * @status: the outcome of the operation
423
 
 * @contact: the modified #EContact
424
 
 *
425
 
 * Respond to a 'modify' request specified by @opid on @book,
426
 
 * indicating @status as the outcome.
427
 
 **/
428
 
void
429
 
e_data_book_respond_modify (EDataBook                              *book,
430
 
                            guint32                                 opid,
431
 
                            GNOME_Evolution_Addressbook_CallStatus  status,
432
 
                            EContact                               *contact)
433
 
{
434
 
        CORBA_Environment ev;
435
 
 
436
 
        if (status == GNOME_Evolution_Addressbook_Success) {
437
 
                e_book_backend_notify_update (book->priv->backend, contact);
438
 
                e_book_backend_notify_complete (book->priv->backend);
439
 
        }
440
 
 
441
 
        CORBA_exception_init (&ev);
442
 
 
443
 
        GNOME_Evolution_Addressbook_BookListener_notifyContactModified (
444
 
                book->priv->listener, opid, status, &ev);
445
 
 
446
 
        if (ev._major != CORBA_NO_EXCEPTION) {
447
 
                g_warning ("e_data_book_respond_modify: Exception "
448
 
                           "responding to BookListener!\n");
449
 
        }
450
 
 
451
 
        CORBA_exception_free (&ev);
452
 
}
453
 
 
454
 
/**
455
 
 * e_data_book_respond_authenticate_user:
456
 
 * @book: an #EDataBook
457
 
 * @opid: the operation ID that generated the response
458
 
 * @status: the outcome of the operation
459
 
 *
460
 
 * Respond to an 'authenticate' request specified by @opid on @book,
461
 
 * indicating @status as the outcome.
462
 
 **/
463
 
void
464
 
e_data_book_respond_authenticate_user (EDataBook                              *book,
465
 
                                       guint32                                 opid,
466
 
                                       GNOME_Evolution_Addressbook_CallStatus  status)
467
 
{
468
 
        CORBA_Environment ev;
469
 
 
470
 
        CORBA_exception_init (&ev);
471
 
 
472
 
        GNOME_Evolution_Addressbook_BookListener_notifyAuthenticationResult (
473
 
                book->priv->listener, opid, status, &ev);
474
 
 
475
 
        if (ev._major != CORBA_NO_EXCEPTION) {
476
 
                g_warning ("e_data_book_respond_authenticate_user: Exception "
477
 
                           "responding to BookListener!\n");
478
 
        }
479
 
 
480
 
        CORBA_exception_free (&ev);
481
 
}
482
 
 
483
 
/**
484
 
 * e_data_book_respond_get_required_fields:
485
 
 * @book: an #EDataBook
486
 
 * @opid: the operation ID that generated the response
487
 
 * @status: the outcome of the operation
488
 
 * @fields: a list of required field names
489
 
 *
490
 
 * Respond to a 'get required fields' request specified by @opid on @book,
491
 
 * indicating @status as the outcome.
492
 
 **/
493
 
void
494
 
e_data_book_respond_get_required_fields (EDataBook                              *book,
495
 
                                          guint32                                 opid,
496
 
                                          GNOME_Evolution_Addressbook_CallStatus  status,
497
 
                                          GList                                  *fields)
498
 
{
499
 
 
500
 
        CORBA_Environment ev;
501
 
        GNOME_Evolution_Addressbook_stringlist stringlist;
502
 
        gint num_fields;
503
 
        gint i;
504
 
        GList *iter;
505
 
 
506
 
        CORBA_exception_init (&ev);
507
 
 
508
 
        num_fields = g_list_length (fields);
509
 
 
510
 
        stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields);
511
 
        stringlist._maximum = num_fields;
512
 
        stringlist._length = num_fields;
513
 
 
514
 
        for (i = 0, iter = fields; iter; iter = iter->next, i ++) {
515
 
                stringlist._buffer[i] = CORBA_string_dup ((gchar *)iter->data);
516
 
        }
517
 
 
518
 
        printf ("calling GNOME_Evolution_Addressbook_BookListener_notifyRequiredFields\n");
519
 
 
520
 
        GNOME_Evolution_Addressbook_BookListener_notifyRequiredFields (
521
 
                        book->priv->listener, opid, status,
522
 
                        &stringlist,
523
 
                        &ev);
524
 
 
525
 
        CORBA_exception_free (&ev);
526
 
 
527
 
        CORBA_free(stringlist._buffer);
528
 
}
529
 
 
530
 
/**
531
 
 * e_data_book_respond_get_supported_fields:
532
 
 * @book: an #EDataBook
533
 
 * @opid: the operation ID that generated the response
534
 
 * @status: the outcome of the operation
535
 
 * @fields: a list of supported field names
536
 
 *
537
 
 * Respond to a 'get supported fields' request specified by @opid on @book,
538
 
 * indicating @status as the outcome.
539
 
 **/
540
 
void
541
 
e_data_book_respond_get_supported_fields (EDataBook                              *book,
542
 
                                          guint32                                 opid,
543
 
                                          GNOME_Evolution_Addressbook_CallStatus  status,
544
 
                                          GList                                  *fields)
545
 
{
546
 
        CORBA_Environment ev;
547
 
        GNOME_Evolution_Addressbook_stringlist stringlist;
548
 
        gint num_fields;
549
 
        gint i;
550
 
        GList *iter;
551
 
 
552
 
        CORBA_exception_init (&ev);
553
 
 
554
 
        num_fields = g_list_length (fields);
555
 
 
556
 
        stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields);
557
 
        stringlist._maximum = num_fields;
558
 
        stringlist._length = num_fields;
559
 
 
560
 
        for (i = 0, iter = fields; iter; iter = iter->next, i ++) {
561
 
                stringlist._buffer[i] = CORBA_string_dup ((gchar *)iter->data);
562
 
        }
563
 
 
564
 
        printf ("calling GNOME_Evolution_Addressbook_BookListener_notifySupportedFields\n");
565
 
 
566
 
        GNOME_Evolution_Addressbook_BookListener_notifySupportedFields (
567
 
                        book->priv->listener, opid, status,
568
 
                        &stringlist,
569
 
                        &ev);
570
 
 
571
 
        CORBA_exception_free (&ev);
572
 
 
573
 
        CORBA_free(stringlist._buffer);
574
 
}
575
 
 
576
 
/**
577
 
 * e_data_book_respond_get_supported_auth_methods:
578
 
 * @book: an #EDataBook
579
 
 * @opid: the operation ID that generated the response
580
 
 * @status: the outcome of the operation
581
 
 * @auth_methods: a list of names for supported auth methods
582
 
 *
583
 
 * Respond to a 'get supported auth methods' request specified by @opid on @book,
584
 
 * indicating @status as the outcome.
585
 
 **/
586
 
void
587
 
e_data_book_respond_get_supported_auth_methods (EDataBook                              *book,
588
 
                                                guint32                                 opid,
589
 
                                                GNOME_Evolution_Addressbook_CallStatus  status,
590
 
                                                GList                                  *auth_methods)
591
 
{
592
 
        CORBA_Environment ev;
593
 
        GNOME_Evolution_Addressbook_stringlist stringlist;
594
 
        gint num_auth_methods;
595
 
        GList *iter;
596
 
        gint i;
597
 
 
598
 
        CORBA_exception_init (&ev);
599
 
 
600
 
        num_auth_methods = g_list_length (auth_methods);
601
 
 
602
 
        stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_auth_methods);
603
 
        stringlist._maximum = num_auth_methods;
604
 
        stringlist._length = num_auth_methods;
605
 
 
606
 
        for (i = 0, iter = auth_methods; iter; iter = iter->next, i ++) {
607
 
                stringlist._buffer[i] = CORBA_string_dup ((gchar *)iter->data);
608
 
        }
609
 
 
610
 
        GNOME_Evolution_Addressbook_BookListener_notifySupportedAuthMethods (
611
 
                        book->priv->listener, opid, status,
612
 
                        &stringlist,
613
 
                        &ev);
614
 
 
615
 
        CORBA_exception_free (&ev);
616
 
 
617
 
        CORBA_free(stringlist._buffer);
618
 
}
619
 
 
620
 
static void
621
 
view_destroy(gpointer data, GObject *where_object_was)
622
 
{
623
 
        EDataBook           *book = (EDataBook *)data;
624
 
        e_book_backend_remove_book_view (book->priv->backend, (EDataBookView*)where_object_was);
625
 
}
626
 
 
627
 
/**
628
 
 * e_data_book_respond_get_book_view:
629
 
 * @book: an #EDataBook
630
 
 * @opid: the operation ID that generated the response
631
 
 * @status: the outcome of the operation
632
 
 * @book_view: the #EDataBookView created
633
 
 *
634
 
 * Respond to a 'get book view' request specified by @opid on @book,
635
 
 * indicating @status as the outcome.
636
 
 **/
637
 
void
638
 
e_data_book_respond_get_book_view (EDataBook                              *book,
639
 
                                   guint32                                 opid,
640
 
                                   GNOME_Evolution_Addressbook_CallStatus  status,
641
 
                                   EDataBookView                          *book_view)
642
 
{
643
 
        CORBA_Environment ev;
644
 
        CORBA_Object      object = CORBA_OBJECT_NIL;
645
 
 
646
 
        printf ("e_data_book_respond_get_book_view\n");
647
 
 
648
 
        CORBA_exception_init (&ev);
649
 
 
650
 
        if (book_view) {
651
 
                object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
652
 
 
653
 
                g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
654
 
        }
655
 
 
656
 
        GNOME_Evolution_Addressbook_BookListener_notifyViewRequested (
657
 
                book->priv->listener, opid, status, object, &ev);
658
 
 
659
 
        if (ev._major != CORBA_NO_EXCEPTION) {
660
 
                g_warning ("e_data_book_respond_get_book_view: Exception "
661
 
                           "responding to BookListener!\n");
662
 
        }
663
 
 
664
 
        CORBA_exception_free (&ev);
665
 
}
666
 
 
667
 
/**
668
 
 * e_data_book_respond_get_contact:
669
 
 * @book: an #EDataBook
670
 
 * @opid: the operation ID that generated the response
671
 
 * @status: the outcome of the operation
672
 
 * @vcard: the found VCard, or %NULL
673
 
 *
674
 
 * Respond to a 'get contact' request specified by @opid on @book,
675
 
 * indicating @status as the outcome.
676
 
 **/
677
 
void
678
 
e_data_book_respond_get_contact (EDataBook                              *book,
679
 
                                 guint32                                 opid,
680
 
                                 GNOME_Evolution_Addressbook_CallStatus  status,
681
 
                                 const gchar                            *vcard)
682
 
{
683
 
        CORBA_Environment ev;
684
 
 
685
 
        CORBA_exception_init (&ev);
686
 
 
687
 
        GNOME_Evolution_Addressbook_BookListener_notifyContactRequested (book->priv->listener,
688
 
                                                                         opid,
689
 
                                                                         status,
690
 
                                                                         vcard,
691
 
                                                                         &ev);
692
 
 
693
 
        if (ev._major != CORBA_NO_EXCEPTION)
694
 
                g_message ("could not notify listener of get-contact response");
695
 
 
696
 
        CORBA_exception_free (&ev);
697
 
}
698
 
 
699
 
/**
700
 
 * e_data_book_respond_get_contact_list:
701
 
 * @book: an #EDataBook
702
 
 * @opid: the operation ID that generated the response
703
 
 * @status: the outcome of the operation
704
 
 * @card_list: a list of VCard strings
705
 
 *
706
 
 * Respond to a 'get contact list' request specified by @opid on @book,
707
 
 * indicating @status as the outcome.
708
 
 **/
709
 
void
710
 
e_data_book_respond_get_contact_list (EDataBook                              *book,
711
 
                                      guint32                                 opid,
712
 
                                      GNOME_Evolution_Addressbook_CallStatus  status,
713
 
                                      GList                                  *card_list)
714
 
{
715
 
        CORBA_Environment ev;
716
 
        GNOME_Evolution_Addressbook_stringlist stringlist;
717
 
        gint num_cards;
718
 
        gint i;
719
 
        GList *l;
720
 
 
721
 
        CORBA_exception_init (&ev);
722
 
 
723
 
        num_cards = g_list_length (card_list);
724
 
 
725
 
        stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_cards);
726
 
        stringlist._maximum = num_cards;
727
 
        stringlist._length = num_cards;
728
 
 
729
 
        for (i = 0, l = card_list; l; l = l->next, i ++)
730
 
                stringlist._buffer[i] = CORBA_string_dup (l->data);
731
 
 
732
 
        g_list_foreach (card_list, (GFunc)g_free, NULL);
733
 
        g_list_free (card_list);
734
 
 
735
 
        GNOME_Evolution_Addressbook_BookListener_notifyContactListRequested (book->priv->listener,
736
 
                                                                             opid,
737
 
                                                                             status,
738
 
                                                                             &stringlist,
739
 
                                                                             &ev);
740
 
 
741
 
        if (ev._major != CORBA_NO_EXCEPTION)
742
 
                g_message ("could not notify listener of get-contact-list response");
743
 
 
744
 
        CORBA_exception_free (&ev);
745
 
 
746
 
        CORBA_free(stringlist._buffer);
747
 
}
748
 
 
749
 
/**
750
 
 * e_data_book_respond_get_changes:
751
 
 * @book: an #EDataBook
752
 
 * @opid: the operation ID that generated the response
753
 
 * @status: the outcome of the operation
754
 
 * @changes: a list of GNOME_Evolution_Addressbook_BookChangeItem items
755
 
 *
756
 
 * Respond to a 'get changes' request specified by @opid on @book,
757
 
 * indicating @status as the outcome.
758
 
 **/
759
 
void
760
 
e_data_book_respond_get_changes (EDataBook                              *book,
761
 
                                 guint32                                 opid,
762
 
                                 GNOME_Evolution_Addressbook_CallStatus  status,
763
 
                                 GList                                  *changes)
764
 
{
765
 
        CORBA_Environment ev;
766
 
        GNOME_Evolution_Addressbook_BookChangeList changelist;
767
 
        gint num_changes;
768
 
        gint i;
769
 
        GList *l;
770
 
 
771
 
        CORBA_exception_init (&ev);
772
 
 
773
 
        num_changes = g_list_length (changes);
774
 
 
775
 
        changelist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_BookChangeItem_allocbuf (num_changes);
776
 
        changelist._maximum = num_changes;
777
 
        changelist._length = num_changes;
778
 
 
779
 
        for (i = 0, l = changes; l; l = l->next, i ++) {
780
 
                GNOME_Evolution_Addressbook_BookChangeItem *change = (GNOME_Evolution_Addressbook_BookChangeItem*)l->data;
781
 
                changelist._buffer[i] = *change;
782
 
                changelist._buffer[i].vcard = CORBA_string_dup (change->vcard);
783
 
        }
784
 
 
785
 
        g_list_foreach (changes, (GFunc)CORBA_free, NULL);
786
 
        g_list_free (changes);
787
 
 
788
 
        GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (book->priv->listener,
789
 
                                                                         opid,
790
 
                                                                         status,
791
 
                                                                         &changelist,
792
 
                                                                         &ev);
793
 
 
794
 
        if (ev._major != CORBA_NO_EXCEPTION)
795
 
                g_message ("could not notify listener of get-changes response");
796
 
 
797
 
        CORBA_exception_free (&ev);
798
 
 
799
 
        CORBA_free(changelist._buffer);
800
 
}
801
 
 
802
 
/**
803
 
 * e_data_book_report_writable:
804
 
 * @book: an #EDataBook
805
 
 * @writable: %TRUE if @book is writeable, %FALSE otherwise
806
 
 *
807
 
 * Notify listeners that @book's writeable status has changed
808
 
 * to @writable.
809
 
 **/
810
 
void
811
 
e_data_book_report_writable (EDataBook                           *book,
812
 
                             gboolean                           writable)
813
 
{
814
 
        CORBA_Environment ev;
815
 
 
816
 
        CORBA_exception_init (&ev);
817
 
 
818
 
        GNOME_Evolution_Addressbook_BookListener_notifyWritable (
819
 
                book->priv->listener, (CORBA_boolean) writable, &ev);
820
 
 
821
 
        if (ev._major != CORBA_NO_EXCEPTION) {
822
 
                g_warning ("e_data_book_report_writable: Exception "
823
 
                           "responding to BookListener!\n");
824
 
        }
825
 
 
826
 
        CORBA_exception_free (&ev);
827
 
}
828
 
 
829
 
/**
830
 
 * e_data_book_report_connection_status:
831
 
 * @book: an #EDataBook
832
 
 * @is_online: %TRUE if the book is connected, %FALSE otherwise
833
 
 *
834
 
 * Notify listeners that @book's online status has changed
835
 
 * to @is_online.
836
 
 **/
837
 
void
838
 
e_data_book_report_connection_status (EDataBook   *book,
839
 
                                      gboolean    is_online)
840
 
{
841
 
        CORBA_Environment ev;
842
 
 
843
 
        CORBA_exception_init (&ev);
844
 
 
845
 
        GNOME_Evolution_Addressbook_BookListener_notifyConnectionStatus (
846
 
                book->priv->listener, (CORBA_boolean) is_online, &ev);
847
 
 
848
 
        if (ev._major != CORBA_NO_EXCEPTION) {
849
 
                g_warning ("e_data_book_report_connection_status: Exception "
850
 
                           "responding to BookListener!\n");
851
 
        }
852
 
 
853
 
        CORBA_exception_free (&ev);
854
 
 
855
 
}
856
 
 
857
 
/**
858
 
 * e_data_book_report_connection_status:
859
 
 * @book: an #EDataBook
860
 
 *
861
 
 * Notify listeners that @book requires authentication.
862
 
 **/
 
569
                data_book_return_error (context, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Invalid query"));
 
570
                return;
 
571
        }
 
572
 
 
573
        path = construct_bookview_path ();
 
574
        book_view = e_data_book_view_new (book, path, search, card_sexp, max_results);
 
575
 
 
576
        e_book_backend_add_book_view (backend, book_view);
 
577
 
 
578
        dbus_g_method_return (context, path);
 
579
        g_free (path);
 
580
}
 
581
 
 
582
static void
 
583
impl_AddressBook_Book_getChanges(EDataBook *book, const gchar *IN_change_id, DBusGMethodInvocation *context)
 
584
{
 
585
        OperationData *op;
 
586
 
 
587
        op = op_new (OP_GET_CHANGES, book, context);
 
588
        op->d.change_id = g_strdup (IN_change_id);
 
589
        g_thread_pool_push (op_pool, op, NULL);
 
590
}
 
591
 
 
592
void
 
593
e_data_book_respond_get_changes (EDataBook *book, guint32 opid, EDataBookStatus status, GList *changes)
 
594
{
 
595
        DBusGMethodInvocation *context = opid_fetch (opid);
 
596
 
 
597
        if (status != E_DATA_BOOK_STATUS_SUCCESS) {
 
598
                data_book_return_error (context, status, _("Cannot get changes"));
 
599
        } else {
 
600
                /* The DBus interface to this is a(us), an array of structs of unsigned ints
 
601
                   and strings.  In dbus-glib this is a GPtrArray of GValueArray of unsigned
 
602
                   gint and strings. */
 
603
                GPtrArray *array;
 
604
 
 
605
                array = g_ptr_array_new ();
 
606
 
 
607
                while (changes != NULL) {
 
608
                        EDataBookChange *change = (EDataBookChange *) changes->data;
 
609
                        GValueArray *vals;
 
610
 
 
611
                        vals = g_value_array_new (2);
 
612
 
 
613
                        g_value_array_append (vals, NULL);
 
614
                        g_value_init (g_value_array_get_nth (vals, 0), G_TYPE_UINT);
 
615
                        g_value_set_uint (g_value_array_get_nth (vals, 0), change->change_type);
 
616
 
 
617
                        g_value_array_append (vals, NULL);
 
618
                        g_value_init (g_value_array_get_nth (vals, 1), G_TYPE_STRING);
 
619
                        g_value_take_string (g_value_array_get_nth (vals, 1), change->vcard);
 
620
                        /* Now change->vcard is owned by the GValue */
 
621
 
 
622
                        g_free (change);
 
623
                        changes = g_list_remove (changes, change);
 
624
                }
 
625
 
 
626
                dbus_g_method_return (context, array);
 
627
                g_ptr_array_foreach (array, (GFunc)g_value_array_free, NULL);
 
628
                g_ptr_array_free (array, TRUE);
 
629
        }
 
630
}
 
631
 
 
632
static gboolean
 
633
impl_AddressBook_Book_cancelOperation(EDataBook *book, GError **error)
 
634
{
 
635
        if (e_book_backend_cancel_operation (e_data_book_get_backend (book), book) != GNOME_Evolution_Addressbook_Success) {
 
636
                g_set_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_COULD_NOT_CANCEL, "Failed to cancel operation");
 
637
                return FALSE;
 
638
        }
 
639
 
 
640
        return TRUE;
 
641
}
 
642
 
 
643
static void
 
644
impl_AddressBook_Book_close(EDataBook *book, DBusGMethodInvocation *context)
 
645
{
 
646
        e_book_backend_remove_client (e_data_book_get_backend (book), book);
 
647
        g_object_unref (book);
 
648
 
 
649
        dbus_g_method_return (context);
 
650
}
 
651
 
 
652
void
 
653
e_data_book_report_writable (EDataBook *book, gboolean writable)
 
654
{
 
655
        g_return_if_fail (book != NULL);
 
656
 
 
657
        g_signal_emit (book, signals[WRITABLE], 0, writable);
 
658
}
 
659
 
 
660
void
 
661
e_data_book_report_connection_status (EDataBook *book, gboolean connected)
 
662
{
 
663
        g_return_if_fail (book != NULL);
 
664
 
 
665
        g_signal_emit (book, signals[CONNECTION], 0, connected);
 
666
}
 
667
 
863
668
void
864
669
e_data_book_report_auth_required (EDataBook *book)
865
670
{
866
 
 
867
 
        CORBA_Environment ev;
868
 
 
869
 
        CORBA_exception_init (&ev);
870
 
 
871
 
        GNOME_Evolution_Addressbook_BookListener_notifyAuthRequired (
872
 
                         book->priv->listener,  &ev);
873
 
 
874
 
        if (ev._major != CORBA_NO_EXCEPTION) {
875
 
                g_warning ("e_data_book_report_auth_required: Exception "
876
 
                           "responding to BookListener!\n");
877
 
        }
878
 
 
879
 
        CORBA_exception_free (&ev);
880
 
 
881
 
}
882
 
 
883
 
static void
884
 
e_data_book_construct (EDataBook                *book,
885
 
                       EBookBackend             *backend,
886
 
                       ESource *source,
887
 
                       GNOME_Evolution_Addressbook_BookListener listener)
888
 
{
889
 
        EDataBookPrivate *priv;
890
 
        CORBA_Environment ev;
891
 
 
892
671
        g_return_if_fail (book != NULL);
893
 
        g_return_if_fail (source != NULL);
894
 
 
895
 
        priv = book->priv;
896
 
 
897
 
        CORBA_exception_init (&ev);
898
 
        book->priv->listener = CORBA_Object_duplicate (listener, &ev);
899
 
 
900
 
        if (ev._major != CORBA_NO_EXCEPTION) {
901
 
                g_message ("e_data_book_construct(): could not duplicate the listener");
902
 
                CORBA_exception_free (&ev);
903
 
                return;
904
 
        }
905
 
 
906
 
        CORBA_exception_free (&ev);
907
 
 
908
 
        g_object_ref (source);
909
 
 
910
 
        priv->backend   = g_object_ref(backend);
911
 
        priv->source    = source;
912
 
}
913
 
 
914
 
/**
915
 
 * e_data_book_new:
916
 
 * @backend: an #EBookBackend
917
 
 * @source: an #ESource
918
 
 * @listener: a #GNOME_Evolution_Addressbook_BookListener CORBA object
919
 
 *
920
 
 * Create a new #EDataBook using @backend for storage, @source as the
921
 
 * storage location and @listener for reporting status.
922
 
 *
923
 
 * Return value: A new #EDataBook.
924
 
 **/
925
 
EDataBook *
926
 
e_data_book_new (EBookBackend                               *backend,
927
 
                 ESource *source,
928
 
                 GNOME_Evolution_Addressbook_BookListener  listener)
929
 
{
930
 
        static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
931
 
        static PortableServer_POA poa = NULL;
932
 
        EDataBook *book;
933
 
 
934
 
        g_static_mutex_lock (&mutex);
935
 
        if (poa == NULL)
936
 
                poa = bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL);
937
 
        g_static_mutex_unlock (&mutex);
938
 
 
939
 
        book = g_object_new (E_TYPE_DATA_BOOK, "poa", poa, NULL);
940
 
 
941
 
        e_data_book_construct (book, backend, source, listener);
942
 
 
943
 
        return book;
944
 
}
945
 
 
946
 
static void
947
 
e_data_book_dispose (GObject *object)
948
 
{
949
 
        EDataBook *book = E_DATA_BOOK (object);
950
 
 
951
 
        if (book->priv) {
952
 
                CORBA_Environment ev;
953
 
 
954
 
                CORBA_exception_init (&ev);
955
 
                CORBA_Object_release (book->priv->listener, &ev);
956
 
 
957
 
                if (ev._major != CORBA_NO_EXCEPTION)
958
 
                        g_message ("e_data_book_construct(): could not release the listener");
959
 
 
960
 
                CORBA_exception_free (&ev);
961
 
 
962
 
                g_object_unref (book->priv->source);
963
 
                g_object_unref (book->priv->backend);
964
 
                g_free (book->priv);
965
 
                book->priv = NULL;
966
 
        }
967
 
 
968
 
        if (G_OBJECT_CLASS (e_data_book_parent_class)->dispose)
969
 
                G_OBJECT_CLASS (e_data_book_parent_class)->dispose (object);
970
 
}
971
 
 
972
 
static void
973
 
e_data_book_class_init (EDataBookClass *klass)
974
 
{
975
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
976
 
        POA_GNOME_Evolution_Addressbook_Book__epv *epv;
977
 
 
978
 
        e_data_book_parent_class = g_type_class_peek_parent (klass);
979
 
 
980
 
        object_class->dispose = e_data_book_dispose;
981
 
 
982
 
        epv = &klass->epv;
983
 
 
984
 
        epv->open                    = impl_GNOME_Evolution_Addressbook_Book_open;
985
 
        epv->remove                  = impl_GNOME_Evolution_Addressbook_Book_remove;
986
 
        epv->getContact              = impl_GNOME_Evolution_Addressbook_Book_getContact;
987
 
        epv->getContactList          = impl_GNOME_Evolution_Addressbook_Book_getContactList;
988
 
        epv->authenticateUser        = impl_GNOME_Evolution_Addressbook_Book_authenticateUser;
989
 
        epv->addContact              = impl_GNOME_Evolution_Addressbook_Book_addContact;
990
 
        epv->removeContacts          = impl_GNOME_Evolution_Addressbook_Book_removeContacts;
991
 
        epv->modifyContact           = impl_GNOME_Evolution_Addressbook_Book_modifyContact;
992
 
        epv->getStaticCapabilities   = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities;
993
 
        epv->getSupportedFields      = impl_GNOME_Evolution_Addressbook_Book_getSupportedFields;
994
 
        epv->getRequiredFields       = impl_GNOME_Evolution_Addressbook_Book_getRequiredFields;
995
 
        epv->getSupportedAuthMethods = impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods;
996
 
        epv->getBookView             = impl_GNOME_Evolution_Addressbook_Book_getBookView;
997
 
        epv->getChanges              = impl_GNOME_Evolution_Addressbook_Book_getChanges;
998
 
        epv->cancelOperation         = impl_GNOME_Evolution_Addressbook_Book_cancelOperation;
999
 
 
1000
 
}
1001
 
 
1002
 
static void
1003
 
e_data_book_init (EDataBook *book)
1004
 
{
1005
 
        book->priv                = g_new0 (EDataBookPrivate, 1);
1006
 
}
1007
 
 
1008
 
BONOBO_TYPE_FUNC_FULL (
1009
 
                       EDataBook,
1010
 
                       GNOME_Evolution_Addressbook_Book,
1011
 
                       BONOBO_TYPE_OBJECT,
1012
 
                       e_data_book)
 
672
 
 
673
        g_signal_emit (book, signals[AUTH_REQUIRED], 0);
 
674
}
 
675
 
 
676
static void
 
677
return_status_and_list (guint32 opid, EDataBookStatus status, GList *list, gboolean free_data)
 
678
{
 
679
        DBusGMethodInvocation *context = opid_fetch (opid);
 
680
 
 
681
        if (status == E_DATA_BOOK_STATUS_SUCCESS) {
 
682
                gchar **array;
 
683
                GList *l;
 
684
                gint i = 0;
 
685
 
 
686
                array = g_new0 (gchar *, g_list_length (list) + 1);
 
687
                for (l = list; l != NULL; l = l->next) {
 
688
                        array[i++] = l->data;
 
689
                }
 
690
 
 
691
                dbus_g_method_return (context, array);
 
692
 
 
693
                if (free_data) {
 
694
                        g_strfreev (array);
 
695
                } else {
 
696
                        g_free (array);
 
697
                }
 
698
        } else {
 
699
                data_book_return_error (context, status, _("Cannot complete operation"));
 
700
        }
 
701
}