~ubuntu-branches/ubuntu/quantal/libbonobo/quantal-201207170711

« back to all changes in this revision

Viewing changes to activation-server/activation-context-corba.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-02-18 14:40:51 UTC
  • mto: (3.1.1 etch) (1.1.25 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20050218144051-fo4h9qh2gim8x3wt
Tags: upstream-2.8.1
ImportĀ upstreamĀ versionĀ 2.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
 
2
/*
 
3
 *  bonobo-activation-server: CORBA activation dameon.
 
4
 *
 
5
 *  Copyright (C) 1999, 2000 Red Hat, Inc.
 
6
 *  Copyright (C) 1999, 2000 Eazel, Inc.
 
7
 *  Copyright (C) 1999, 2003 Ximian, Inc.
 
8
 *
 
9
 *  This library is free software; you can redistribute it and/or
 
10
 *  modify it under the terms of the GNU General Public License as
 
11
 *  published by the Free Software Foundation; either version 2 of the
 
12
 *  License, or (at your option) any later version.
 
13
 *
 
14
 *  This library is distributed in the hope that it will be useful,
 
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
 *  General Public License for more details.
 
18
 *
 
19
 *  You should have received a copy of the GNU General Public License
 
20
 *  along with this library; if not, write to the Free Software
 
21
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
22
 *
 
23
 *  Authors: Elliot Lee <sopwith@redhat.com>,
 
24
 *
 
25
 */
 
26
 
 
27
#ifdef HAVE_CONFIG_H
 
28
#include <config.h>
 
29
#endif
 
30
 
 
31
#include <stdio.h>
 
32
#include <time.h>
 
33
#include <string.h>
 
34
 
 
35
#include "server.h"
 
36
 
 
37
#include "activation-context.h"
 
38
#include "bonobo-activation-id.h"
 
39
#include "activation-context-query.h"
 
40
#include "activation-server-corba-extensions.h"
 
41
#include <libbonobo.h>
 
42
 
 
43
#undef LOCALE_DEBUG
 
44
 
 
45
#define Bonobo_LINK_TIME_TO_LIVE 256
 
46
 
 
47
static GObjectClass *parent_class = NULL;
 
48
 
 
49
static void
 
50
directory_info_free (ActivationContext *actx, CORBA_Environment *ev)
 
51
{
 
52
        CORBA_Object_release (actx->obj, ev);
 
53
        actx->obj = CORBA_OBJECT_NIL;
 
54
 
 
55
        if (actx->by_iid) {
 
56
                g_hash_table_destroy (actx->by_iid);
 
57
                actx->by_iid = NULL;
 
58
        }
 
59
 
 
60
        if (actx->list) {
 
61
                CORBA_sequence_set_release (actx->list, CORBA_TRUE);
 
62
                CORBA_free (actx->list);
 
63
                actx->list = NULL;
 
64
        }
 
65
 
 
66
        if (actx->active_servers)
 
67
                g_hash_table_destroy (actx->active_servers);
 
68
        CORBA_free (actx->active_server_list);
 
69
        actx->active_server_list = NULL;
 
70
}
 
71
 
 
72
static void
 
73
ac_update_active (ActivationContext *actx, CORBA_Environment *ev)
 
74
{
 
75
        int i;
 
76
        Bonobo_ServerStateCache *cache;
 
77
 
 
78
        cache = Bonobo_ObjectDirectory_get_active_servers (
 
79
                actx->obj, actx->time_active_pulled, ev);
 
80
 
 
81
        if (ev->_major != CORBA_NO_EXCEPTION) {
 
82
                CORBA_Object_release (actx->obj, ev);
 
83
                actx->obj = CORBA_OBJECT_NIL;
 
84
        }
 
85
 
 
86
        if (cache->_d) {
 
87
                if (actx->active_servers) {
 
88
                        g_hash_table_destroy (actx->active_servers);
 
89
                        CORBA_free (actx->active_server_list);
 
90
                }
 
91
 
 
92
                actx->active_server_list = cache;
 
93
 
 
94
                actx->time_active_pulled = time (NULL);
 
95
                actx->active_servers =
 
96
                        g_hash_table_new (g_str_hash, g_str_equal);
 
97
                for (i = 0; i < cache->_u.active_servers._length; i++)
 
98
                        g_hash_table_insert (actx->active_servers,
 
99
                                             cache->_u.
 
100
                                             active_servers._buffer[i],
 
101
                                             GINT_TO_POINTER (1));
 
102
        } else
 
103
                CORBA_free (cache);
 
104
}
 
105
 
 
106
static char *
 
107
ac_CORBA_Context_get_value (CORBA_Context         ctx, 
 
108
                            const char           *propname,
 
109
                            CORBA_Environment    *ev)
 
110
{
 
111
        return activation_server_CORBA_Context_get_value (
 
112
                ctx, propname,
 
113
                ex_Bonobo_Activation_IncompleteContext, ev);
 
114
}
 
115
 
 
116
static void
 
117
ac_update_list (ActivationContext *actx, CORBA_Environment *ev)
 
118
{
 
119
        int i;
 
120
        Bonobo_ServerInfoListCache *cache;
 
121
 
 
122
        cache = Bonobo_ObjectDirectory_get_servers (
 
123
                actx->obj, actx->time_list_pulled, ev);
 
124
 
 
125
        if (ev->_major != CORBA_NO_EXCEPTION) {
 
126
                actx->list = NULL;
 
127
                CORBA_Object_release (actx->obj, ev);
 
128
                actx->obj = CORBA_OBJECT_NIL;
 
129
                return;
 
130
        }
 
131
 
 
132
        if (cache->_d) {
 
133
                if (actx->by_iid)
 
134
                        g_hash_table_destroy (actx->by_iid);
 
135
                if (actx->list) {
 
136
                        CORBA_sequence_set_release (actx->list, CORBA_TRUE);
 
137
                        CORBA_free (actx->list);
 
138
                        actx->list = NULL;
 
139
                }
 
140
 
 
141
                actx->list = ORBit_copy_value (&cache->_u.server_list,
 
142
                                               TC_Bonobo_ServerInfoList);
 
143
 
 
144
                actx->time_list_pulled = time (NULL);
 
145
                actx->by_iid = g_hash_table_new (g_str_hash, g_str_equal);
 
146
                for (i = 0; i < actx->list->_length; i++)
 
147
                        g_hash_table_insert (actx->by_iid,
 
148
                                             actx->list->_buffer[i].iid,
 
149
                                             &(actx->list->_buffer[i]));
 
150
        }
 
151
 
 
152
        CORBA_free (cache);
 
153
}
 
154
 
 
155
static QueryExprConst
 
156
ac_query_get_var (Bonobo_ServerInfo *si, const char *id, QueryContext *qctx)
 
157
{
 
158
        QueryExprConst retval;
 
159
        ActivationContext *actx = qctx->user_data;
 
160
 
 
161
        retval.value_known = FALSE;
 
162
        retval.needs_free = FALSE;
 
163
 
 
164
        if (!strcasecmp (id, "_active")) {
 
165
                CORBA_Environment ev;
 
166
 
 
167
                CORBA_exception_init (&ev);
 
168
                ac_update_active (actx, &ev);
 
169
                CORBA_exception_free (&ev);
 
170
 
 
171
                retval.value_known = TRUE;
 
172
                retval.type = CONST_BOOLEAN;
 
173
                retval.u.v_boolean =
 
174
                        g_hash_table_lookup (actx->active_servers,
 
175
                                             si->iid) ? TRUE : FALSE;
 
176
        }
 
177
 
 
178
        return retval;
 
179
}
 
180
 
 
181
/* This function should only be called by
 
182
 * impl_Bonobo_ActivationContext_query and
 
183
 * impl_Bonobo_ActivationContext_activateMatching - hairy implicit preconditions
 
184
 * exist. */
 
185
static void
 
186
ac_query_run (ActivationContext        *actx,
 
187
              const CORBA_char        *requirements,
 
188
              const Bonobo_StringList *selection_order,
 
189
              CORBA_Context            ctx,
 
190
              Bonobo_ServerInfo      **items,
 
191
              CORBA_Environment       *ev)
 
192
{
 
193
        int total, i;
 
194
        QueryContext qctx;
 
195
 
 
196
        Bonobo_ServerInfo **orig_items;
 
197
        int item_count, orig_item_count;
 
198
        char *errstr;
 
199
        Bonobo_Activation_ParseFailed *ex;
 
200
 
 
201
        QueryExpr *qexp_requirements;
 
202
        QueryExpr **qexp_sort_items;
 
203
 
 
204
        /* First, parse the query */
 
205
        errstr = (char *) qexp_parse (requirements, &qexp_requirements);
 
206
        if (errstr) {
 
207
                puts (errstr);
 
208
 
 
209
                g_strstrip (errstr);
 
210
                ex = Bonobo_Activation_ParseFailed__alloc ();
 
211
                ex->description = CORBA_string_dup (errstr);
 
212
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
213
                                     ex_Bonobo_Activation_ParseFailed,
 
214
                                     ex);
 
215
                return;
 
216
        }
 
217
 
 
218
        qexp_sort_items =
 
219
                g_alloca (selection_order->_length * sizeof (QueryExpr *));
 
220
        for (i = 0; i < selection_order->_length; i++) {
 
221
                errstr =
 
222
                        (char *) qexp_parse (selection_order->_buffer[i],
 
223
                                             &qexp_sort_items[i]);
 
224
 
 
225
                if (errstr) {
 
226
                        qexp_free (qexp_requirements);
 
227
                        for (i--; i >= 0; i--)
 
228
                                qexp_free (qexp_sort_items[i]);
 
229
 
 
230
                        g_strstrip (errstr);
 
231
                        ex = Bonobo_Activation_ParseFailed__alloc ();
 
232
                        ex->description = CORBA_string_dup (errstr);
 
233
 
 
234
                        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
235
                                             ex_Bonobo_Activation_ParseFailed,
 
236
                                             ex);
 
237
                        return;
 
238
                }
 
239
        }
 
240
 
 
241
        total = actx->total_servers;
 
242
        orig_items = g_alloca (total * sizeof (Bonobo_ServerInfo *));
 
243
 
 
244
        {
 
245
                int i;
 
246
 
 
247
                item_count = 0;
 
248
 
 
249
                if (actx->obj != CORBA_OBJECT_NIL)
 
250
                        for (i = 0; i < actx->list->_length; i++, item_count++)
 
251
                                items[item_count] = &actx->list->_buffer[i];
 
252
        }
 
253
 
 
254
        memcpy (orig_items, items, item_count * sizeof (Bonobo_ServerInfo *));
 
255
        orig_item_count = item_count;
 
256
 
 
257
        qctx.sil = orig_items;
 
258
        qctx.nservers = orig_item_count;
 
259
        qctx.cctx = ctx;
 
260
        qctx.id_evaluator = ac_query_get_var;
 
261
        qctx.user_data = actx;
 
262
 
 
263
        for (i = 0; i < item_count; i++) {
 
264
                if (!qexp_matches (items[i], qexp_requirements, &qctx))
 
265
                        items[i] = NULL;
 
266
        }
 
267
 
 
268
        qexp_sort (items, item_count, qexp_sort_items,
 
269
                   selection_order->_length, &qctx);
 
270
 
 
271
        qexp_free (qexp_requirements);
 
272
        for (i = 0; i < selection_order->_length; i++)
 
273
                qexp_free (qexp_sort_items[i]);
 
274
}
 
275
 
 
276
static void
 
277
ac_update_lists (ActivationContext *actx,
 
278
                 CORBA_Environment *ev)
 
279
{
 
280
        int prev, new;
 
281
 
 
282
        if (actx->refs > 0) {
 
283
                /* FIXME: what happens on re-enterency here ?
 
284
                 * looks like this could get seriously out of date */
 
285
                return;
 
286
        }
 
287
 
 
288
        if (actx->list)
 
289
                prev = actx->list->_length;
 
290
        else
 
291
                prev = 0;
 
292
 
 
293
        ac_update_list (actx, ev);
 
294
 
 
295
        if (actx->list)
 
296
                new = actx->list->_length;
 
297
        else
 
298
                new = 0;
 
299
 
 
300
        actx->total_servers += (new - prev);
 
301
}
 
302
 
 
303
static GList *clients = NULL;
 
304
 
 
305
void
 
306
activation_clients_cache_notify (void)
 
307
{
 
308
        GList *l;
 
309
        GSList *notify = NULL, *l2;
 
310
        CORBA_Environment ev;
 
311
 
 
312
        CORBA_exception_init (&ev);
 
313
 
 
314
        for (l = clients; l; l = l->next)
 
315
                notify = g_slist_prepend (notify, CORBA_Object_duplicate (l->data, &ev));
 
316
 
 
317
        for (l2 = notify; l2; l2 = l2->next) {
 
318
                Bonobo_ActivationClient_resetCache (l2->data, &ev);
 
319
                if (ev._major != CORBA_NO_EXCEPTION)
 
320
                        clients = g_list_remove (clients, l2->data);
 
321
 
 
322
                CORBA_Object_release (l2->data, &ev);
 
323
                CORBA_exception_free (&ev);
 
324
        }
 
325
}
 
326
 
 
327
gboolean
 
328
activation_clients_is_empty_scan (void)
 
329
{
 
330
        GList *l, *next;
 
331
 
 
332
        for (l = clients; l; l = next) {
 
333
                next = l->next;
 
334
                if (ORBit_small_get_connection_status (l->data) ==
 
335
                    ORBIT_CONNECTION_DISCONNECTED) {
 
336
                        CORBA_Object_release (l->data, NULL);
 
337
                        clients = g_list_delete_link (clients, l);
 
338
                }
 
339
        }
 
340
 
 
341
        return clients == NULL;
 
342
}
 
343
 
 
344
static void
 
345
active_client_cnx_broken (ORBitConnection *cnx,
 
346
                          gpointer         dummy)
 
347
{
 
348
        if (activation_clients_is_empty_scan ()) {
 
349
#ifdef BONOBO_ACTIVATION_DEBUG
 
350
                g_warning ("All clients dead");
 
351
#endif
 
352
                check_quit ();
 
353
        }
 
354
 
 
355
}
 
356
 
 
357
static void
 
358
impl_Bonobo_ActivationContext_addClient (PortableServer_Servant        servant,
 
359
                                         const Bonobo_ActivationClient client,
 
360
                                         const CORBA_char             *locales,
 
361
                                         CORBA_Environment            *ev)
 
362
{
 
363
        GList *l;
 
364
        gboolean new_locale;
 
365
        ORBitConnection *cnx;
 
366
 
 
367
        new_locale = register_interest_in_locales (locales);
 
368
 
 
369
        cnx = ORBit_small_get_connection (client);
 
370
        for (l = clients; l; l = l->next)
 
371
                if (cnx == ORBit_small_get_connection (l->data))
 
372
                        break;
 
373
        
 
374
        clients = g_list_prepend (
 
375
                clients, CORBA_Object_duplicate (client, ev));
 
376
 
 
377
        if (!l) {
 
378
                g_signal_connect (
 
379
                        cnx, "broken",
 
380
                        G_CALLBACK (active_client_cnx_broken),
 
381
                        NULL);
 
382
                check_quit ();
 
383
        }
 
384
 
 
385
        if (new_locale)
 
386
                bonobo_object_directory_reload ();
 
387
}
 
388
 
 
389
static Bonobo_ObjectDirectoryList *
 
390
impl_Bonobo_ActivationContext__get_directories (PortableServer_Servant servant,
 
391
                                                CORBA_Environment     *ev)
 
392
{
 
393
        ActivationContext *actx = ACTIVATION_CONTEXT (servant);
 
394
        Bonobo_ObjectDirectoryList *retval;
 
395
 
 
396
        retval = Bonobo_ObjectDirectoryList__alloc ();
 
397
        if (actx->obj != CORBA_OBJECT_NIL) {
 
398
                retval->_length = 1;
 
399
                retval->_buffer =
 
400
                        CORBA_sequence_Bonobo_ObjectDirectory_allocbuf (1);
 
401
                retval->_buffer[0] = CORBA_Object_duplicate (actx->obj, ev);
 
402
        } else {
 
403
                retval->_length = 0;
 
404
        }
 
405
 
 
406
        CORBA_sequence_set_release (retval, CORBA_TRUE);
 
407
 
 
408
        return retval;
 
409
}
 
410
 
 
411
static void
 
412
impl_Bonobo_ActivationContext_addDirectory (PortableServer_Servant servant,
 
413
                                            Bonobo_ObjectDirectory dir,
 
414
                                            CORBA_Environment     *ev)
 
415
{
 
416
        ActivationContext *actx = ACTIVATION_CONTEXT (servant);
 
417
 
 
418
        if (actx->obj == dir)
 
419
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
420
                                     ex_Bonobo_Activation_AlreadyListed,
 
421
                                     NULL);
 
422
        else {
 
423
                CORBA_Object_release (actx->obj, ev);
 
424
                actx->obj = CORBA_Object_duplicate (dir, ev);
 
425
        }
 
426
}
 
427
 
 
428
static void
 
429
impl_Bonobo_ActivationContext_removeDirectory (PortableServer_Servant servant,
 
430
                                               Bonobo_ObjectDirectory dir,
 
431
                                               CORBA_Environment     *ev)
 
432
{
 
433
        ActivationContext *actx = ACTIVATION_CONTEXT (servant);
 
434
 
 
435
        if (dir != actx->obj)
 
436
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
437
                                     ex_Bonobo_Activation_NotListed,
 
438
                                     NULL);
 
439
        else {
 
440
                if (actx->refs) {
 
441
                        CORBA_Object_release (actx->obj, ev);
 
442
                        actx->obj = CORBA_OBJECT_NIL;
 
443
                } else
 
444
                        directory_info_free (actx, ev);
 
445
        }
 
446
}
 
447
 
 
448
static void
 
449
ac_do_activation (ActivationContext                  *actx,
 
450
                  Bonobo_ServerInfo                  *server,
 
451
                  const Bonobo_ActivationEnvironment *environment,
 
452
                  Bonobo_ActivationResult            *out,
 
453
                  Bonobo_ActivationFlags              flags,
 
454
                  const char                         *hostname,
 
455
                  Bonobo_ActivationClient             client,
 
456
                  CORBA_Context                       ctx,
 
457
                  CORBA_Environment                  *ev)
 
458
{
 
459
        int num_layers;
 
460
        Bonobo_ServerInfo *activatable;
 
461
 
 
462
        /* When doing checks for shlib loadability, we 
 
463
         * have to find the info on the factory object in case
 
464
         * a factory is inside a shlib 
 
465
         */
 
466
        if (!actx->obj || ev->_major != CORBA_NO_EXCEPTION) {
 
467
                Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc ();
 
468
                errval->description =
 
469
                        CORBA_string_dup
 
470
                        (_("Couldn't find which child the server was listed in"));
 
471
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
472
                                     ex_Bonobo_GeneralError, errval);
 
473
                return;
 
474
        }
 
475
 
 
476
        for (num_layers = 0, activatable = server;
 
477
             activatable && activatable->server_type &&
 
478
                     !strcmp (activatable->server_type, "factory") &&
 
479
             num_layers < Bonobo_LINK_TIME_TO_LIVE; num_layers++) {
 
480
 
 
481
                activatable = g_hash_table_lookup (actx->by_iid, activatable->location_info);
 
482
        }
 
483
 
 
484
        if (activatable == NULL) {              
 
485
                Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc ();
 
486
                errval->description = CORBA_string_dup ("Couldn't find the factory server");
 
487
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION, 
 
488
                                     ex_Bonobo_GeneralError, errval);
 
489
                return;
 
490
        } 
 
491
        else if (num_layers == Bonobo_LINK_TIME_TO_LIVE) {
 
492
                Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc ();
 
493
                errval->description = CORBA_string_dup ("Location loop");
 
494
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
495
                                     ex_Bonobo_GeneralError, errval);
 
496
                return;
 
497
        }
 
498
 
 
499
        /* A shared library must be on the same host as the activator in
 
500
         * order for loading to work properly (no, we're not going to
 
501
         * bother with loading a remote shlib into a process - it gets far too complicated
 
502
         * far too quickly :-) */
 
503
        
 
504
        if (activatable && !strcmp (activatable->server_type, "shlib")
 
505
            && !(flags & Bonobo_ACTIVATION_FLAG_NO_LOCAL)
 
506
            && (hostname && !strcmp (activatable->hostname, hostname))) {
 
507
                int j;
 
508
                char tbuf[512];
 
509
                
 
510
                out->res._d = Bonobo_ACTIVATION_RESULT_SHLIB;           
 
511
 
 
512
                /* Here is an explanation as to why we add 2 to num_layers.
 
513
                 * At the end of the string list, after all the factory iids are added
 
514
                 * to the string list, we then add the iid of the shaed library and the 
 
515
                 * location info.  This data is later used in oaf_server_activate_shlib
 
516
                 * to activate the component
 
517
                 */              
 
518
                out->res._u.res_shlib._length = num_layers + 2;
 
519
                out->res._u.res_shlib._buffer = CORBA_sequence_CORBA_string_allocbuf (num_layers + 2);
 
520
 
 
521
                /* Copy over factory info */
 
522
                for (j = 0, activatable = server; activatable
 
523
                     && !strcmp (activatable->server_type, "factory"); j++) {
 
524
                        out->res._u.res_shlib._buffer[j] = CORBA_string_dup (activatable->iid);
 
525
                        activatable = g_hash_table_lookup (actx->by_iid,
 
526
                                                           activatable->location_info);
 
527
                }
 
528
 
 
529
                /* Copy shlib iid into buffer */
 
530
                out->res._u.res_shlib._buffer[j] = CORBA_string_dup (activatable->iid);
 
531
 
 
532
                /* Copy location into last buffer slot for use in later activation */
 
533
                out->res._u.res_shlib._buffer[j+1] = CORBA_string_dup (activatable->location_info);
 
534
                
 
535
                g_snprintf (tbuf, sizeof (tbuf), "OAFAID:[%s,%s,%s]",
 
536
                            activatable->iid,
 
537
                            activatable->username,
 
538
                            activatable->hostname);
 
539
                out->aid = CORBA_string_dup (tbuf);
 
540
        } else {
 
541
                CORBA_Object retval;
 
542
 
 
543
                retval = Bonobo_ObjectDirectory_activate (
 
544
                        actx->obj, server->iid, BONOBO_OBJREF (actx),
 
545
                        environment, flags, client, ctx, ev);
 
546
 
 
547
                if (ev->_major == CORBA_NO_EXCEPTION) {
 
548
                        char tbuf[512];
 
549
                        out->res._d = Bonobo_ACTIVATION_RESULT_OBJECT;
 
550
                        out->res._u.res_object = retval;
 
551
                        g_snprintf (tbuf, sizeof (tbuf),
 
552
                                    "OAFAID:[%s,%s,%s]", activatable->iid,
 
553
                                    activatable->username,
 
554
                                    activatable->hostname);
 
555
                        out->aid = CORBA_string_dup (tbuf);
 
556
                }
 
557
#ifdef BONOBO_ACTIVATION_DEBUG
 
558
                else
 
559
                        g_warning ("Activation of '%s' failed with exception '%s'",
 
560
                                   activatable->iid, ev->_id);
 
561
#endif
 
562
        }
 
563
}
 
564
 
 
565
 
 
566
static Bonobo_ActivationResult *
 
567
impl_Bonobo_ActivationContext_activateMatchingFull (
 
568
        PortableServer_Servant              servant,
 
569
        const CORBA_char                   *requirements,
 
570
        const Bonobo_StringList            *selection_order,
 
571
        const Bonobo_ActivationEnvironment *environment,
 
572
        const Bonobo_ActivationFlags        flags,
 
573
        Bonobo_ActivationClient             client,
 
574
        CORBA_Context                       ctx,
 
575
        CORBA_Environment                  *ev)
 
576
{
 
577
        ActivationContext *actx = ACTIVATION_CONTEXT (servant);
 
578
        Bonobo_ActivationResult *retval = NULL;
 
579
        Bonobo_ServerInfo **items, *curitem;
 
580
        int i;
 
581
        char *hostname;
 
582
 
 
583
        ac_update_lists (actx, ev);
 
584
 
 
585
        actx->refs++;
 
586
 
 
587
        items = g_alloca (actx->total_servers *
 
588
                          sizeof (Bonobo_ServerInfo *));
 
589
        ac_query_run (actx, requirements, selection_order, ctx, items, ev);
 
590
 
 
591
        if (ev->_major != CORBA_NO_EXCEPTION)
 
592
                goto out;
 
593
 
 
594
        hostname = ac_CORBA_Context_get_value (ctx, "hostname", ev);
 
595
 
 
596
        retval = Bonobo_ActivationResult__alloc ();
 
597
        retval->res._d = Bonobo_ACTIVATION_RESULT_NONE;
 
598
 
 
599
        for (i = 0; (retval->res._d == Bonobo_ACTIVATION_RESULT_NONE) && items[i]
 
600
             && (i < actx->total_servers); i++) {
 
601
                curitem = items[i];
 
602
 
 
603
                ac_do_activation (actx, curitem, environment,
 
604
                                  retval, flags, hostname, client, ctx, ev);
 
605
        }
 
606
 
 
607
        if (retval->res._d == Bonobo_ACTIVATION_RESULT_NONE)
 
608
                retval->aid = CORBA_string_dup ("");
 
609
 
 
610
        g_free (hostname);
 
611
 
 
612
 out:
 
613
        if (ev->_major != CORBA_NO_EXCEPTION) {
 
614
                CORBA_free (retval);
 
615
                retval = NULL;
 
616
        }
 
617
 
 
618
        actx->refs--;
 
619
 
 
620
        return retval;
 
621
}
 
622
 
 
623
static Bonobo_ActivationResult *
 
624
impl_Bonobo_ActivationContext_activateMatching (
 
625
        PortableServer_Servant              servant,
 
626
        const CORBA_char                   *requirements,
 
627
        const Bonobo_StringList            *selection_order,
 
628
        const Bonobo_ActivationEnvironment *environment,
 
629
        const Bonobo_ActivationFlags        flags,
 
630
        CORBA_Context                       ctx,
 
631
        CORBA_Environment                  *ev)
 
632
{
 
633
        return impl_Bonobo_ActivationContext_activateMatchingFull
 
634
                (servant, requirements, selection_order,
 
635
                 environment, flags, CORBA_OBJECT_NIL, ctx, ev);
 
636
}
 
637
 
 
638
static Bonobo_ServerInfoList *
 
639
impl_Bonobo_ActivationContext_query (PortableServer_Servant servant,
 
640
                                     const CORBA_char * requirements,
 
641
                                     const Bonobo_StringList * selection_order,
 
642
                                     CORBA_Context ctx, CORBA_Environment * ev)
 
643
{
 
644
        ActivationContext *actx = ACTIVATION_CONTEXT (servant);
 
645
        Bonobo_ServerInfoList *retval;
 
646
        Bonobo_ServerInfo **items;
 
647
        int item_count;
 
648
        int i, j, total;
 
649
 
 
650
        retval = Bonobo_ServerInfoList__alloc ();
 
651
        retval->_length = 0;
 
652
        retval->_buffer = NULL;
 
653
        CORBA_sequence_set_release (retval, CORBA_TRUE);
 
654
 
 
655
        /* Pull in new lists from OD servers */
 
656
        ac_update_lists (actx, ev);
 
657
        actx->refs++;
 
658
 
 
659
        items = g_alloca (actx->total_servers *
 
660
                          sizeof (Bonobo_ServerInfo *));
 
661
        item_count = actx->total_servers;
 
662
 
 
663
        ac_query_run (actx, requirements, selection_order, ctx, items, ev);
 
664
 
 
665
        if (ev->_major == CORBA_NO_EXCEPTION) {
 
666
                for (total = i = 0; i < item_count; i++) {
 
667
                        if (items[i])
 
668
                                total++;
 
669
                }
 
670
 
 
671
                retval->_length = total;
 
672
                retval->_buffer =
 
673
                        CORBA_sequence_Bonobo_ServerInfo_allocbuf (total);
 
674
 
 
675
                for (i = j = 0; i < item_count; i++) {
 
676
                        if (!items[i])
 
677
                                continue;
 
678
 
 
679
                        Bonobo_ServerInfo_copy (&retval->_buffer[j], items[i]);
 
680
 
 
681
                        j++;
 
682
                }
 
683
        }
 
684
 
 
685
        actx->refs--;
 
686
 
 
687
        return retval;
 
688
}
 
689
 
 
690
static char *
 
691
ac_aid_to_query_string (const CORBA_char *aid)
 
692
{
 
693
        char *requirements;
 
694
        char *iid_requirement;
 
695
        char *username_requirement;
 
696
        char *hostname_requirement;
 
697
        BonoboActivationInfo *ainfo;
 
698
 
 
699
        ainfo = bonobo_activation_id_parse (aid);
 
700
        if (!ainfo)
 
701
                return NULL;
 
702
 
 
703
        iid_requirement = g_strconcat ("iid == \'", ainfo->iid, "\' ", NULL);
 
704
 
 
705
        if (ainfo->user) {
 
706
                username_requirement = g_strconcat ("AND username == \'", ainfo->user, "\'", NULL);
 
707
        } else {
 
708
                username_requirement = g_strdup ("");
 
709
        }
 
710
        
 
711
        if (ainfo->host) {
 
712
                hostname_requirement = g_strconcat ("AND hostname == \'", ainfo->host, "\'", NULL);
 
713
        } else {
 
714
                hostname_requirement = g_strdup ("");
 
715
        }
 
716
        
 
717
        requirements = g_strconcat (iid_requirement, username_requirement, 
 
718
                                    hostname_requirement, NULL);
 
719
 
 
720
        g_free (iid_requirement);
 
721
        g_free (username_requirement);
 
722
        g_free (hostname_requirement);
 
723
        bonobo_activation_info_free (ainfo);
 
724
 
 
725
        return requirements;
 
726
}
 
727
 
 
728
static void
 
729
ac_context_to_string_array (CORBA_Context context, char **sort_criteria,
 
730
                            CORBA_Environment *ev)
 
731
{
 
732
        char *context_username;
 
733
        char *context_hostname;
 
734
 
 
735
        context_username = ac_CORBA_Context_get_value (context, "username", ev);
 
736
        context_hostname = ac_CORBA_Context_get_value (context, "hostname", ev);
 
737
        if (ev->_major != CORBA_NO_EXCEPTION)
 
738
                return;
 
739
        
 
740
        sort_criteria[0] = g_strconcat ("username == \'", context_username, "\'", NULL);
 
741
        sort_criteria[1] = g_strconcat ("hostname == \'", context_hostname, "\'", NULL);
 
742
        sort_criteria[2] = NULL;
 
743
 
 
744
        g_free (context_username);
 
745
        g_free (context_hostname);
 
746
}
 
747
 
 
748
#define PARSE_ERROR_NOT_AN_AID (_("Not a valid Activation ID"))
 
749
 
 
750
static Bonobo_ActivationResult *
 
751
impl_Bonobo_ActivationContext_activateFromAidFull (PortableServer_Servant  servant,
 
752
                                                   const CORBA_char       *aid,
 
753
                                                   Bonobo_ActivationFlags  flags,
 
754
                                                   Bonobo_ActivationClient client,
 
755
                                                   CORBA_Context           ctx,
 
756
                                                   CORBA_Environment      *ev)
 
757
{
 
758
        ActivationContext *actx = ACTIVATION_CONTEXT (servant);
 
759
        Bonobo_ActivationResult *retval;
 
760
        char *requirements;
 
761
        char *sort_criteria[3];
 
762
        Bonobo_StringList selection_order;
 
763
        Bonobo_ActivationEnvironment environment;
 
764
 
 
765
        if (strncmp ("OAFAID:", aid, 7) != 0) {
 
766
                Bonobo_Activation_ParseFailed *ex;
 
767
 
 
768
                ex = Bonobo_Activation_ParseFailed__alloc ();
 
769
                ex->description = CORBA_string_dup (PARSE_ERROR_NOT_AN_AID);
 
770
 
 
771
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
772
                                     ex_Bonobo_Activation_ParseFailed,
 
773
                                     ex);
 
774
                return NULL;
 
775
        }
 
776
 
 
777
        ac_update_lists (actx, ev);
 
778
        if (ev->_major != CORBA_NO_EXCEPTION)
 
779
                return NULL;
 
780
 
 
781
        actx->refs++;
 
782
 
 
783
        requirements = ac_aid_to_query_string (aid);
 
784
        if (requirements == NULL) {
 
785
                actx->refs--;
 
786
                return NULL;
 
787
        }
 
788
 
 
789
        ac_context_to_string_array (ctx, sort_criteria, ev);
 
790
        if (ev->_major != CORBA_NO_EXCEPTION) {
 
791
                actx->refs--;
 
792
                g_free (requirements);
 
793
                return NULL;
 
794
        }
 
795
 
 
796
        selection_order._length = 2;
 
797
        selection_order._buffer = sort_criteria;
 
798
        CORBA_sequence_set_release (&selection_order, CORBA_FALSE);
 
799
 
 
800
        memset (&environment, 0, sizeof (Bonobo_ActivationEnvironment));
 
801
 
 
802
        retval = impl_Bonobo_ActivationContext_activateMatchingFull (
 
803
                actx, requirements, &selection_order, &environment,
 
804
                flags, client, ctx, ev);
 
805
 
 
806
        g_free (sort_criteria[0]);
 
807
        g_free (sort_criteria[1]);
 
808
        g_free (requirements);
 
809
 
 
810
        actx->refs--;
 
811
 
 
812
        return retval;
 
813
}
 
814
 
 
815
static Bonobo_ActivationResult *
 
816
impl_Bonobo_ActivationContext_activateFromAid (PortableServer_Servant  servant,
 
817
                                               const CORBA_char       *aid,
 
818
                                               Bonobo_ActivationFlags  flags,
 
819
                                               CORBA_Context           ctx,
 
820
                                               CORBA_Environment      *ev)
 
821
{
 
822
        return impl_Bonobo_ActivationContext_activateFromAidFull
 
823
                (servant, aid, flags, CORBA_OBJECT_NIL, ctx, ev);
 
824
}
 
825
 
 
826
static CORBA_long
 
827
impl_Bonobo_ActivationContext_getVersion (PortableServer_Servant  servant,
 
828
                                          CORBA_Environment      *ev)
 
829
{
 
830
        return (BONOBO_ACTIVATION_MAJOR_VERSION*10000 + 
 
831
                BONOBO_ACTIVATION_MINOR_VERSION*100 +
 
832
                BONOBO_ACTIVATION_MICRO_VERSION);
 
833
}
 
834
 
 
835
static ActivationContext *main_ac = NULL;
 
836
 
 
837
void
 
838
activation_context_setup (PortableServer_POA     poa,
 
839
                          Bonobo_ObjectDirectory dir,
 
840
                          CORBA_Environment     *ev)
 
841
{
 
842
        main_ac = g_object_new (activation_context_get_type (), NULL);
 
843
 
 
844
        impl_Bonobo_ActivationContext_addDirectory
 
845
                (BONOBO_OBJECT (main_ac), dir, ev);
 
846
}
 
847
 
 
848
void
 
849
activation_context_shutdown (void)
 
850
{
 
851
        if (main_ac) {
 
852
                bonobo_object_set_immortal (BONOBO_OBJECT (main_ac), FALSE);
 
853
                bonobo_object_unref (BONOBO_OBJECT (main_ac));
 
854
                main_ac = NULL;
 
855
        }        
 
856
}
 
857
 
 
858
Bonobo_ActivationContext
 
859
activation_context_get (void)
 
860
{
 
861
        if (!main_ac)
 
862
                return CORBA_OBJECT_NIL;
 
863
        else
 
864
                return BONOBO_OBJREF (main_ac);
 
865
}
 
866
 
 
867
static void 
 
868
activation_context_finalize (GObject *object)
 
869
{
 
870
        CORBA_Environment ev[1];
 
871
        ActivationContext *actx = (ActivationContext *) object;
 
872
 
 
873
        CORBA_exception_init (ev);
 
874
 
 
875
        directory_info_free (actx, ev);
 
876
 
 
877
        CORBA_exception_free (ev);
 
878
 
 
879
        parent_class->finalize (object);
 
880
}
 
881
 
 
882
static void
 
883
activation_context_class_init (ActivationContextClass *klass)
 
884
{
 
885
        GObjectClass *object_class = (GObjectClass *) klass;
 
886
        POA_Bonobo_ActivationContext__epv *epv = &klass->epv;
 
887
 
 
888
        parent_class = g_type_class_peek_parent (klass);
 
889
        object_class->finalize = activation_context_finalize;
 
890
 
 
891
        epv->_get_directories = impl_Bonobo_ActivationContext__get_directories;
 
892
        epv->addClient         = impl_Bonobo_ActivationContext_addClient;
 
893
        epv->addDirectory      = impl_Bonobo_ActivationContext_addDirectory;
 
894
        epv->removeDirectory   = impl_Bonobo_ActivationContext_removeDirectory;
 
895
        epv->query             = impl_Bonobo_ActivationContext_query;
 
896
        epv->activateMatching  = impl_Bonobo_ActivationContext_activateMatching;
 
897
        epv->activateFromAid   = impl_Bonobo_ActivationContext_activateFromAid;
 
898
        epv->getVersion        = impl_Bonobo_ActivationContext_getVersion;
 
899
        epv->activateMatchingFull = impl_Bonobo_ActivationContext_activateMatchingFull;
 
900
        epv->activateFromAidFull  = impl_Bonobo_ActivationContext_activateFromAidFull;
 
901
}
 
902
 
 
903
static void
 
904
activation_context_init (ActivationContext *actx)
 
905
{
 
906
        bonobo_object_set_immortal (BONOBO_OBJECT (actx), TRUE);
 
907
}
 
908
 
 
909
BONOBO_TYPE_FUNC_FULL (ActivationContext,
 
910
                       Bonobo_ActivationContext,
 
911
                       BONOBO_TYPE_OBJECT,
 
912
                       activation_context)