source: trunk/third/bonobo-activation/server/activation-context-corba.c @ 18563

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