source: trunk/third/bonobo/bonobo/bonobo-moniker-util.c @ 16754

Revision 16754, 27.1 KB checked in by ghudson, 23 years ago (diff)
Merge with bonobo 1.0.14; remove ATHTOOLROOT support.
Line 
1/*
2 * bonobo-moniker-util.c
3 *
4 * Copyright (C) 2000  Helix Code, Inc.
5 *
6 * Authors:
7 *      Michael Meeks    (michael@helixcode.com)
8 *      Ettore Perazzoli (ettore@helixcode.com)
9 */
10/* #include <syslog.h> */
11
12#include <bonobo/bonobo-moniker-util.h>
13#include <bonobo/bonobo-exception.h>
14#include <liboaf/liboaf.h>
15#include <liboaf/oaf-async.h>
16#include <ORBitservices/CosNaming.h>
17
18struct {
19        char *prefix;
20        char *oafiid;
21} fast_prefix [] = {
22        { "file:",   "OAFIID:Bonobo_Moniker_File"  },
23        { "query:(", "OAFIID:Bonobo_Moniker_Query" },
24        { "!",       "OAFIID:Bonobo_Moniker_Item"  },
25        { "OAFIID:", "OAFIID:Bonobo_Moniker_Oaf"   },
26        { "OAFAID:", "OAFIID:Bonobo_Moniker_Oaf"   },
27        { "new:",    "OAFIID:Bonobo_Moniker_New"   },
28        { "http:",   "OAFIID:Bonobo_Moniker_http"  },
29/*
30        { "queue:", "" },
31*/
32        { NULL, NULL }
33};
34
35static char *
36moniker_id_from_nickname (const CORBA_char *name)
37{
38        int i;
39
40        for (i = 0; fast_prefix [i].prefix; i++) {
41                int len = strlen (fast_prefix [i].prefix);
42
43                if (!g_strncasecmp (fast_prefix [i].prefix, name, len)) {
44
45                        return fast_prefix [i].oafiid;
46                }
47        }
48
49        return NULL;
50}
51
52/*
53 * get_full_interface_name:
54 * @ifname: original name: can be in form Bonobo/Control
55 *
56 * Return value: full name eg. IDL:Bonobo/Control:1.0
57 */
58static gchar *
59get_full_interface_name (const char *ifname)
60{
61        int len, had_ver;
62        const char *a;
63        char *retval, *b;
64
65        g_return_val_if_fail (ifname != NULL, NULL);
66
67        len = strlen (ifname);
68        retval = g_new (char, len + 4 + 4 + 1);
69
70        strcpy (retval, "IDL:");
71        a = ifname;
72        b = retval + 4;
73
74        if (ifname [0] == 'I' &&
75            ifname [1] == 'D' &&
76            ifname [2] == 'L' &&
77            ifname [3] == ':')
78                a += 4;
79
80        for (had_ver = 0; (*b = *a); a++, b++) {
81                if (*a == ':')
82                        had_ver = 1;
83        }
84
85        if (!had_ver)
86                strcpy (b, ":1.0");
87
88        return retval;
89}
90
91static gchar *
92query_from_name (const char *name)
93{
94        char *prefix, *query;
95        int   len;
96
97        for (len = 0; name [len]; len++) {
98                if (name [len] == ':') {
99                        len++;
100                        break;
101                }
102        }
103
104
105        prefix = g_strndup (name, len);
106               
107        query = g_strdup_printf (
108                "repo_ids.has ('IDL:Bonobo/Moniker:1.0') AND "
109                "bonobo:moniker.has ('%s')", prefix);
110        g_free (prefix);
111
112        return query;
113}
114
115/**
116 * bonobo_moniker_util_new_from_name_full:
117 * @parent: A parent moniker to chain to or CORBA_OBJECT_NIL
118 * @name: the display name
119 * @ev: corba environment
120 *
121 *  This routine is used to continue building up the chain
122 * that forms a multi-part moniker. The parent is referenced
123 * as the parent and passed onto the next stage of parsing
124 * the 'name'. We eventually return a moniker handle which
125 * represents the end of a linked list of monikers each
126 * pointing to their parent:
127 *
128 * file:/tmp/a.tar.gz <-- gzip: <-- tar: <-- [ this is returned ]
129 *
130 * Return value: The end node of a list of monikers representing @name
131 **/
132Bonobo_Moniker
133bonobo_moniker_util_new_from_name_full (Bonobo_Moniker     parent,
134                                        const CORBA_char  *name,
135                                        CORBA_Environment *ev)
136{
137        Bonobo_Unknown   object;
138        Bonobo_Moniker   toplevel, moniker;
139        const char       *iid;
140
141        g_return_val_if_fail (ev != NULL, NULL);
142        g_return_val_if_fail (name != NULL, NULL);
143
144        if (!name [0])
145                return bonobo_object_dup_ref (parent, ev);
146
147        if (name [0] == '#')
148                name++;
149
150        if (!(iid = moniker_id_from_nickname (name))) {
151                char *query;
152
153                query = query_from_name (name);
154
155                object = oaf_activate (query, NULL, 0, NULL, ev);
156
157                g_free (query);
158               
159                if (BONOBO_EX (ev))
160                        return CORBA_OBJECT_NIL;
161
162                if (object == CORBA_OBJECT_NIL) {
163                        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
164                                             ex_Bonobo_Moniker_UnknownPrefix, NULL);
165                        return CORBA_OBJECT_NIL;
166                }
167        } else {
168                object = oaf_activate_from_id ((gchar *) iid, 0, NULL, ev);
169
170                if (BONOBO_EX (ev))
171                        return CORBA_OBJECT_NIL;
172               
173                if (object == CORBA_OBJECT_NIL) {
174                        g_warning ("Activating '%s' returned nothing", iid);
175                        return CORBA_OBJECT_NIL;
176                }
177        }
178
179        toplevel = Bonobo_Unknown_queryInterface (
180                object, "IDL:Bonobo/Moniker:1.0", ev);
181
182        if (BONOBO_EX (ev)) {
183                bonobo_object_release_unref (object, ev);
184                return CORBA_OBJECT_NIL;
185        }
186
187        bonobo_object_release_unref (object, ev);
188
189        if (toplevel == CORBA_OBJECT_NIL) {
190                g_warning ("Moniker object '%s' doesn't implement "
191                           "the Moniker interface", iid);
192                return CORBA_OBJECT_NIL;
193        }
194
195        moniker = Bonobo_Moniker_parseDisplayName (toplevel, parent,
196                                                   name, ev);
197        if (BONOBO_EX (ev))
198                return CORBA_OBJECT_NIL;
199
200        bonobo_object_release_unref (toplevel, ev);
201
202        if (BONOBO_EX (ev))
203                return CORBA_OBJECT_NIL;
204
205        return moniker;
206}
207
208/**
209 * bonobo_moniker_util_get_parent_name:
210 * @moniker: the moniker
211 * @ev: a corba exception environment
212 *
213 *  This gets the display name of the parent moniker ( recursively
214 * all of the parents of this moniker ).
215 *
216 * Return value: the display name; use CORBA_free to release it.
217 **/
218CORBA_char *
219bonobo_moniker_util_get_parent_name (Bonobo_Moniker     moniker,
220                                     CORBA_Environment *ev)
221{
222        Bonobo_Moniker parent;
223        CORBA_char    *name;
224
225        g_return_val_if_fail (ev != NULL, NULL);
226        g_return_val_if_fail (moniker != CORBA_OBJECT_NIL, NULL);
227
228        parent = Bonobo_Moniker__get_parent (moniker, ev);
229
230        if (BONOBO_EX (ev) ||
231            parent == CORBA_OBJECT_NIL)
232                return NULL;
233       
234        name = Bonobo_Moniker_getDisplayName (parent, ev);
235
236        if (BONOBO_EX (ev))
237                name = NULL;
238
239        bonobo_object_release_unref (parent, ev);
240
241        return name;
242}
243
244/**
245 * bonobo_moniker_util_qi_return:
246 * @object: the unknown to query
247 * @requested_interface: the desired interface
248 * @ev: a corba exception environment
249 *
250 *  A helper function to share code from the end of a resolve
251 * implementation; this ensures that the returned object is of
252 * the correct interface by doing a queryInterface on the object.
253 *
254 * Return value: an handle to the requested interface
255 **/
256Bonobo_Unknown
257bonobo_moniker_util_qi_return (Bonobo_Unknown     object,
258                               const CORBA_char  *requested_interface,
259                               CORBA_Environment *ev)
260{
261        Bonobo_Unknown retval = CORBA_OBJECT_NIL;
262
263        if (BONOBO_EX (ev))
264                return CORBA_OBJECT_NIL;
265       
266        if (object == CORBA_OBJECT_NIL) {
267                g_warning ("Object is NIL");
268                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
269                                     ex_Bonobo_Moniker_InterfaceNotFound, NULL);
270                return CORBA_OBJECT_NIL;
271        }
272
273        retval = Bonobo_Unknown_queryInterface (
274                object, requested_interface, ev);
275
276        if (BONOBO_EX (ev))
277                goto release_unref_object;
278       
279        if (retval == CORBA_OBJECT_NIL) {
280                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
281                                     ex_Bonobo_Moniker_InterfaceNotFound, NULL);
282                goto release_unref_object;
283        }
284
285 release_unref_object: 
286        bonobo_object_release_unref (object, ev);
287
288        if (retval != CORBA_OBJECT_NIL)
289                return CORBA_Object_duplicate (retval, ev);
290        else
291                return CORBA_OBJECT_NIL;
292}
293
294/**
295 * bonobo_moniker_util_seek_std_separator:
296 * @str: the string to scan
297 * @min_idx: the minimum offset at which a separator can be found.
298 *
299 *  This looks for a standard separator in a moniker's
300 * display name string. Most monikers will want to use
301 * standard separators.
302 *
303 *  See also bonobo_moniker_util_escape
304 *
305 * Return value: the position of the standard separator, or a
306 * pointer to the end of the string.
307 **/
308int
309bonobo_moniker_util_seek_std_separator (const CORBA_char *str,
310                                        int               min_idx)
311{
312        int i;
313
314        g_return_val_if_fail (str != NULL, 0);
315        g_return_val_if_fail (min_idx >= 0, 0);
316
317        for (i = 0; i < min_idx; i++) {
318                if (!str [i]) {
319                        g_warning ("Serious separator error, seeking in '%s' < %d",
320                                   str, min_idx);
321                        return i;
322                }
323        }
324
325        for (; str [i]; i++) {
326
327                if (str [i] == '\\' && str [i + 1])
328                        i++;
329                else if (str [i] == '!' ||
330                         str [i] == '#')
331                        break;
332        }
333       
334        return i;
335}
336
337/**
338 * bonobo_moniker_util_escape:
339 * @string: an unescaped string
340 * @offset: an offset of characters to ignore
341 *
342 *  Escapes possible separator characters inside a moniker
343 * these include '!' and '#', the '\' escaping character is
344 * used.
345 *
346 * Return value: an escaped sub-string.
347 **/
348char *
349bonobo_moniker_util_escape (const char *string, int offset)
350{
351        gchar *escaped, *p;
352        guint  backslashes = 0;
353        int    i, len;
354
355        g_return_val_if_fail (string != NULL, NULL);
356
357        len = strlen (string);
358        g_return_val_if_fail (offset < len, NULL);
359
360        for (i = offset; i < len; i++) {
361                if (string [i] == '\0')
362                        break;
363                else if (string [i] == '\\' ||
364                         string [i] == '#'  ||
365                         string [i] == '!')
366                        backslashes ++;
367        }
368       
369        if (!backslashes)
370                return g_strdup (&string [offset]);
371
372        p = escaped = g_new (gchar, len - offset + backslashes + 1);
373
374        for (i = offset; i < len; i++) {
375                if (string [i] == '\\' ||
376                    string [i] == '#'  ||
377                    string [i] == '!')
378                        *p++ = '\\';
379                *p++ = string [i];
380        }
381        *p = '\0';
382
383        return escaped;
384}
385
386/**
387 * bonobo_moniker_util_unescape:
388 * @string: a string
389 * @num_chars: the number of chars to process.
390 *
391 *  This routine strips @num_chars: from the start of
392 * @string, discards the rest, and proceeds to un-escape
393 * characters escaped with '\'.
394 *
395 * Return value: the unescaped sub string.
396 **/
397char *
398bonobo_moniker_util_unescape (const char *string, int num_chars)
399{
400        gchar *escaped, *p;
401        guint  backslashes = 0;
402        int    i;
403
404        g_return_val_if_fail (string != NULL, NULL);
405
406        for (i = 0; i < num_chars; i++) {
407                if (string [i] == '\0')
408                        break;
409                else if (string [i] == '\\') {
410                        if (string [i + 1] == '\\')
411                                i++;
412                        backslashes ++;
413                }
414        }
415
416        if (!backslashes)
417                return g_strndup (string, num_chars);
418
419        p = escaped = g_new (gchar, strlen (string) - backslashes + 1);
420
421        for (i = 0; i < num_chars; i++) {
422                if (string [i] == '\\') {
423                        if (!string [++i])
424                                break;
425                        *p++ = string [i];
426                } else
427                        *p++ = string [i];
428        }
429        *p = '\0';
430
431        return escaped;
432}
433
434/**
435 * bonobo_moniker_client_new_from_name:
436 * @name: the display name of a moniker
437 * @ev: a corba exception environment
438 *
439 *  This routine tries to parse a Moniker in string form
440 *
441 * eg. file:/tmp/a.tar.gz#gzip:#tar:
442 *
443 * into a CORBA_Object representation of this that can
444 * later be resolved against an interface.
445 *
446 * Return value: a new Moniker handle
447 **/
448Bonobo_Moniker
449bonobo_moniker_client_new_from_name (const CORBA_char  *name,
450                                     CORBA_Environment *ev)
451{
452        return bonobo_moniker_util_new_from_name_full (
453                CORBA_OBJECT_NIL, name, ev);
454}
455
456/**
457 * bonobo_moniker_client_get_name:
458 * @moniker: a moniker handle
459 * @ev: a corba exception environment
460 *
461 * Return value: the display name of the moniker.
462 **/
463CORBA_char *
464bonobo_moniker_client_get_name (Bonobo_Moniker     moniker,
465                                CORBA_Environment *ev)
466{
467        CORBA_char *name;
468
469        g_return_val_if_fail (ev != NULL, NULL);
470        g_return_val_if_fail (moniker != CORBA_OBJECT_NIL, NULL);
471
472        name = Bonobo_Moniker_getDisplayName (moniker, ev);
473
474        if (BONOBO_EX (ev))
475                return NULL;
476
477        return name;
478}
479
480static void
481init_default_resolve_options (Bonobo_ResolveOptions *options)
482{
483        options->flags = 0;
484        options->timeout = -1;
485}
486
487/**
488 * bonobo_moniker_client_resolve_default:
489 * @moniker: a moniker
490 * @interface_name: the name of the interface we want returned as the result
491 * @ev: a corba exception environment
492 *
493 *  This resolves the moniker object against the given interface,
494 * with a default set of resolve options.
495 *
496 * Return value: the interfaces resolved to or CORBA_OBJECT_NIL
497 **/
498Bonobo_Unknown
499bonobo_moniker_client_resolve_default (Bonobo_Moniker     moniker,
500                                       const char        *interface_name,
501                                       CORBA_Environment *ev)
502{
503        Bonobo_ResolveOptions options;
504        Bonobo_Unknown        retval;
505        char                 *real_if;
506       
507        g_return_val_if_fail (interface_name != NULL, CORBA_OBJECT_NIL);
508        g_return_val_if_fail (moniker != CORBA_OBJECT_NIL, CORBA_OBJECT_NIL);
509
510        real_if = get_full_interface_name (interface_name);
511
512        init_default_resolve_options (&options);
513
514        retval = Bonobo_Moniker_resolve (moniker, &options, real_if, ev);
515
516        g_free (real_if);
517
518        return retval;
519}
520
521/**
522 * bonobo_moniker_client_resolve_client_default:
523 * @moniker: the moniker
524 * @interface_name: the name of the interface we want returned as the result
525 * @ev: a corba exception environment
526 *
527 * See: bonobo_moniker_client_resolve_default; however this version returns
528 * a BonoboObjectClient wrapped reference.
529 *
530 * Return value: a BonoboObjectClient style reference.
531 **/
532BonoboObjectClient *
533bonobo_moniker_client_resolve_client_default (Bonobo_Moniker     moniker,
534                                              const char        *interface_name,
535                                              CORBA_Environment *ev)
536{
537        Bonobo_Unknown unknown;
538
539        g_return_val_if_fail (ev != NULL, NULL);
540
541        unknown = bonobo_moniker_client_resolve_default (
542                moniker, interface_name, ev);
543
544        if (BONOBO_EX (ev))
545                return NULL;
546
547        if (unknown == CORBA_OBJECT_NIL)
548                return NULL;
549
550        return bonobo_object_client_from_corba (unknown);
551}
552
553/**
554 * bonobo_get_object:
555 * @name: the display name of a moniker
556 * @interface_name: the name of the interface we want returned as the result
557 * @ev: a corba exception environment
558 *
559 *  This encapsulates both the parse stage and resolve process of using
560 * a moniker, providing a simple VisualBasic like mechanism for using the
561 * object name space.
562 *
563 * Return value: the requested interface or CORBA_OBJECT_NIL
564 **/
565Bonobo_Unknown
566bonobo_get_object (const CORBA_char *name,
567                   const char        *interface_name,
568                   CORBA_Environment *ev)
569{
570        Bonobo_Moniker moniker;
571        Bonobo_Unknown retval = CORBA_OBJECT_NIL;
572
573        moniker = bonobo_moniker_client_new_from_name (name, ev);
574
575        if (BONOBO_EX (ev))
576                retval = CORBA_OBJECT_NIL;
577        else {
578                retval = bonobo_moniker_client_resolve_default (
579                        moniker, interface_name, ev);
580
581                bonobo_object_release_unref (moniker, ev);
582               
583                if (BONOBO_EX (ev))
584                        retval = CORBA_OBJECT_NIL;
585        }
586
587/*      syslog (LOG_WARNING, "Bonobo: get_object '%s' '%s' returns %p ex '%s'",
588                name ? name : "<null>", interface_name ? interface_name : "<null>",
589                retval, ev->_major == CORBA_NO_EXCEPTION ? "<no exception>" :
590                bonobo_exception_get_text (ev)); */
591
592        return retval;
593}
594
595typedef struct {
596        char                *name;
597        BonoboMonikerAsyncFn cb;
598        gpointer             user_data;
599        guint                timeout_msec;
600        Bonobo_Unknown       moniker;
601} parse_async_ctx_t;
602
603static void
604parse_async_ctx_free (parse_async_ctx_t *ctx)
605{
606        if (ctx) {
607                g_free (ctx->name);
608                g_free (ctx);
609        }
610}
611
612static void
613async_parse_cb (BonoboAsyncReply  *reply,
614                CORBA_Environment *ev,
615                gpointer           user_data)
616{
617        parse_async_ctx_t *ctx = user_data;
618
619        if (BONOBO_EX (ev))
620                ctx->cb (CORBA_OBJECT_NIL, ev, ctx->user_data);
621        else {
622                Bonobo_Moniker retval;
623
624                bonobo_async_demarshal (reply, &retval, NULL);
625
626                ctx->cb (retval, ev, ctx->user_data);
627        }
628
629        bonobo_object_release_unref (ctx->moniker, ev);
630        parse_async_ctx_free (ctx);
631}
632
633static void
634async_activation_cb (CORBA_Object activated_object,
635                     const char  *error_reason,
636                     gpointer     user_data)
637{
638        parse_async_ctx_t *ctx = user_data;
639        CORBA_Environment ev;
640
641        CORBA_exception_init (&ev);
642
643        if (error_reason) { /* badly designed oaf interface */
644
645                CORBA_exception_set (&ev, CORBA_USER_EXCEPTION,
646                                     ex_Bonobo_Moniker_UnknownPrefix, NULL);
647
648                ctx->cb (CORBA_OBJECT_NIL, &ev, ctx->user_data);
649                parse_async_ctx_free (ctx);
650        } else {
651                ctx->moniker = Bonobo_Unknown_queryInterface (
652                        activated_object, "IDL:Bonobo/Moniker:1.0", &ev);
653
654                if (BONOBO_EX (&ev)) {
655                        ctx->cb (CORBA_OBJECT_NIL, &ev, ctx->user_data);
656                        parse_async_ctx_free (ctx);
657               
658                } else if (ctx->moniker == CORBA_OBJECT_NIL) {
659                        CORBA_exception_set (&ev, CORBA_USER_EXCEPTION,
660                                             ex_Bonobo_Moniker_InterfaceNotFound, NULL);
661                        ctx->cb (CORBA_OBJECT_NIL, &ev, ctx->user_data);
662                        parse_async_ctx_free (ctx);
663                } else {
664                        static const BonoboAsyncArg arguments [] = {
665                                { TC_Object, BONOBO_ASYNC_IN },
666                                { TC_string, BONOBO_ASYNC_IN },
667                                { NULL }
668                        };
669                        static const CORBA_TypeCode exceptions [] = {
670                                TC_Bonobo_Moniker_InvalidSyntax,
671                                TC_Bonobo_Moniker_UnknownPrefix,
672                                NULL
673                        };
674                        static const BonoboAsyncMethod method = {
675                                "parseDisplayName",
676                                TC_Object,
677                                arguments,
678                                exceptions
679                        };
680                        CORBA_Object obj = CORBA_OBJECT_NIL;
681                        gpointer arg_values [2];
682       
683                        arg_values[0] = &obj;
684                        arg_values[1] = &ctx->name;
685                        bonobo_async_invoke (&method, async_parse_cb, ctx,
686                                             ctx->timeout_msec,
687                                             ctx->moniker, arg_values, &ev);
688                       
689                        if (BONOBO_EX (&ev)) {
690                                ctx->cb (CORBA_OBJECT_NIL, &ev, ctx->user_data);
691                                parse_async_ctx_free (ctx);
692                        }
693
694                        bonobo_object_release_unref (activated_object, &ev);
695                }
696        }
697
698        CORBA_exception_free (&ev);
699}
700
701/**
702 * bonobo_moniker_client_new_from_name_async:
703 * @name: the name
704 * @ev: a corba exception environment
705 * @timeout_msec: the timeout in milliseconds
706 * @cb: the async callback that gets the response
707 * @user_data: user context data to pass to that callback
708 *
709 * An asynchronous version of new_from_name
710 **/
711void
712bonobo_moniker_client_new_from_name_async (const CORBA_char    *name,
713                                           CORBA_Environment   *ev,
714                                           guint                timeout_msec,
715                                           BonoboMonikerAsyncFn cb,
716                                           gpointer             user_data)
717{
718        parse_async_ctx_t *ctx;
719        const char        *iid;
720
721        g_return_if_fail (ev != NULL);
722        g_return_if_fail (cb != NULL);
723        g_return_if_fail (name != NULL);
724
725        if (!name [0]) {
726                cb (CORBA_OBJECT_NIL, ev, user_data);
727                return;
728        }
729
730        if (name [0] == '#')
731                name++;
732
733        ctx = g_new0 (parse_async_ctx_t, 1);
734        ctx->name         = g_strdup (name);
735        ctx->cb           = cb;
736        ctx->user_data    = user_data;
737        ctx->timeout_msec = timeout_msec;
738        ctx->moniker      = CORBA_OBJECT_NIL;
739
740        if (!(iid = moniker_id_from_nickname (name))) {
741                char *query;
742
743                query = query_from_name (name);
744
745                oaf_activate_async (query, NULL, 0,
746                                    async_activation_cb, ctx, ev);
747
748                g_free (query);
749        } else
750                oaf_activate_from_id_async ((gchar *) iid, 0,
751                                            async_activation_cb, ctx, ev);
752}
753
754typedef struct {
755        Bonobo_Moniker       moniker;
756        BonoboMonikerAsyncFn cb;
757        gpointer             user_data;
758} resolve_async_ctx_t;
759
760static void
761resolve_async_cb (BonoboAsyncReply  *handle,
762                  CORBA_Environment *ev,
763                  gpointer           user_data)
764{
765        resolve_async_ctx_t *ctx = user_data;
766
767        if (BONOBO_EX (ev))
768                ctx->cb (CORBA_OBJECT_NIL, ev, ctx->user_data);
769        else {
770                Bonobo_Unknown object;
771                bonobo_async_demarshal (handle, &object, NULL);
772                ctx->cb (object, ev, ctx->user_data);
773        }
774
775        bonobo_object_release_unref (ctx->moniker, ev);
776        g_free (ctx);
777}
778
779/**
780 * bonobo_moniker_resolve_async:
781 * @moniker: the moniker to resolve
782 * @options: resolve options
783 * @interface_name: the name of the interface we want returned as the result
784 * @ev: a corba exception environment
785 * @timeout_msec: the timeout in milliseconds
786 * @cb: the async callback that gets the response
787 * @user_data: user context data to pass to that callback
788 *
789 * An async version of bonobo_moniker_client_resolve
790 **/
791void
792bonobo_moniker_resolve_async (Bonobo_Moniker         moniker,
793                              Bonobo_ResolveOptions *options,
794                              const char            *interface_name,
795                              CORBA_Environment     *ev,
796                              guint                  timeout_msec,
797                              BonoboMonikerAsyncFn   cb,
798                              gpointer               user_data)
799{
800        static const BonoboAsyncArg arguments [] = {
801                { TC_Bonobo_ResolveOptions, BONOBO_ASYNC_IN },
802                { TC_string,                BONOBO_ASYNC_IN },
803                { NULL }
804        };
805        static const CORBA_TypeCode exceptions [] = {
806                TC_Bonobo_Moniker_InterfaceNotFound,
807                TC_Bonobo_Moniker_UnknownPrefix,
808                NULL
809        };
810        static const BonoboAsyncMethod method = {
811                "resolve",
812                TC_Object,
813                arguments,
814                exceptions
815        };
816        gpointer arg_values [2];
817        resolve_async_ctx_t *ctx;
818       
819        arg_values[0] = &options;
820        arg_values[1] = &interface_name;
821        g_return_if_fail (ev != NULL);
822        g_return_if_fail (cb != NULL);
823        g_return_if_fail (moniker != CORBA_OBJECT_NIL);
824        g_return_if_fail (options != CORBA_OBJECT_NIL);
825        g_return_if_fail (interface_name != CORBA_OBJECT_NIL);
826
827        ctx = g_new0 (resolve_async_ctx_t, 1);
828        ctx->cb = cb;
829        ctx->user_data = user_data;
830        ctx->moniker = bonobo_object_dup_ref (moniker, ev);
831
832        bonobo_async_invoke (&method, resolve_async_cb, ctx,
833                             timeout_msec, ctx->moniker, arg_values, ev);
834}
835
836/**
837 * bonobo_moniker_resolve_async_default:
838 * @moniker:
839 * @interface_name: the name of the interface we want returned as the result
840 * @ev: a corba exception environment
841 * @timeout_msec: the timeout in milliseconds
842 * @cb: the async callback that gets the response
843 * @user_data: user context data to pass to that callback
844 *
845 * An async version of bonobo_moniker_client_resolve_default
846 **/
847void
848bonobo_moniker_resolve_async_default (Bonobo_Moniker       moniker,
849                                      const char          *interface_name,
850                                      CORBA_Environment   *ev,
851                                      guint                timeout_msec,
852                                      BonoboMonikerAsyncFn cb,
853                                      gpointer             user_data)
854{
855        Bonobo_ResolveOptions options;
856
857        g_return_if_fail (ev != NULL);
858        g_return_if_fail (cb != NULL);
859        g_return_if_fail (moniker != CORBA_OBJECT_NIL);
860        g_return_if_fail (interface_name != CORBA_OBJECT_NIL);
861
862        init_default_resolve_options (&options);
863
864        bonobo_moniker_resolve_async (moniker, &options, interface_name,
865                                      ev, timeout_msec, cb, user_data);
866}
867
868
869typedef struct {
870        guint                timeout_msec;
871        char                *interface_name;
872        BonoboMonikerAsyncFn cb;
873        gpointer             user_data;
874} get_object_async_ctx_t;
875
876static void
877get_object_async_ctx_free (get_object_async_ctx_t *ctx)
878{
879        if (ctx) {
880                g_free (ctx->interface_name);
881                g_free (ctx);
882        }
883}
884
885static void
886get_async2_cb (Bonobo_Unknown     object,
887               CORBA_Environment *ev,
888               gpointer           user_data)
889{
890        get_object_async_ctx_t *ctx = user_data;
891
892        ctx->cb (object, ev, ctx->user_data);
893
894        get_object_async_ctx_free (ctx);
895}       
896
897static void
898get_async1_cb (Bonobo_Unknown     object,
899               CORBA_Environment *ev,
900               gpointer           user_data)
901{
902        get_object_async_ctx_t *ctx = user_data;
903
904        if (BONOBO_EX (ev)) {
905                ctx->cb (CORBA_OBJECT_NIL, ev, ctx->user_data);
906                get_object_async_ctx_free (ctx);
907        } else {
908                bonobo_moniker_resolve_async_default (
909                        object, ctx->interface_name, ev,
910                        ctx->timeout_msec, get_async2_cb, ctx);
911
912                if (BONOBO_EX (ev)) {
913                        ctx->cb (CORBA_OBJECT_NIL, ev, ctx->user_data);
914                        get_object_async_ctx_free (ctx);
915                }
916        }
917}       
918
919/**
920 * bonobo_get_object_async:
921 * @name:
922 * @interface_name: the name of the interface we want returned as the result
923 * @ev: a corba exception environment
924 * @timeout_msec: the timeout in milliseconds
925 * @cb: the async callback that gets the response
926 * @user_data: user context data to pass to that callback
927 *
928 * An async version of bonobo_get_object
929 **/
930void
931bonobo_get_object_async (const CORBA_char    *name,
932                         const char          *interface_name,
933                         CORBA_Environment   *ev,
934                         guint                timeout_msec,
935                         BonoboMonikerAsyncFn cb,
936                         gpointer             user_data)
937{
938        get_object_async_ctx_t *ctx;
939
940        g_return_if_fail (ev != NULL);
941        g_return_if_fail (cb != NULL);
942        g_return_if_fail (name != NULL);
943        g_return_if_fail (interface_name != NULL);
944
945        ctx = g_new0 (get_object_async_ctx_t, 1);
946        ctx->cb = cb;
947        ctx->user_data = user_data;
948        ctx->interface_name = get_full_interface_name (interface_name);
949        ctx->timeout_msec = timeout_msec;
950
951        bonobo_moniker_client_new_from_name_async (
952                name, ev, timeout_msec, get_async1_cb, ctx);
953}
954
955/**
956 * bonobo_moniker_client_equal:
957 * @moniker: The moniker
958 * @name: a display name eg. file:/demo/a.jpeg
959 * @opt_ev: optional CORBA_Environment or NULL.
960 *
961 * Compare a full @moniker with the given @name
962 *
963 * Return value: TRUE if they are the same
964 **/
965gboolean
966bonobo_moniker_client_equal (Bonobo_Moniker     moniker,
967                             const CORBA_char  *name,
968                             CORBA_Environment *opt_ev)
969{
970        CORBA_long l;
971        CORBA_Environment *real_ev, tmp_ev;
972       
973        g_return_val_if_fail (name != NULL, FALSE);
974        g_return_val_if_fail (moniker != CORBA_OBJECT_NIL, FALSE);
975
976        if (opt_ev)
977                real_ev = opt_ev;
978        else {
979                CORBA_exception_init (&tmp_ev);
980                real_ev = &tmp_ev;
981        }
982
983        l = Bonobo_Moniker_equal (moniker, name, real_ev);
984
985        if (BONOBO_EX (real_ev))
986                l = 0;
987
988        if (!opt_ev)
989                CORBA_exception_free (&tmp_ev);
990
991        return l != 0;
992}
993
994static CosNaming_NamingContext
995lookup_naming_context (GList *path,
996                       CORBA_Environment *ev)
997{
998        CosNaming_NamingContext ns, ctx, new_ctx;
999        CosNaming_Name *cn;
1000        GList          *l;
1001
1002        g_return_val_if_fail (path != NULL, CORBA_OBJECT_NIL);
1003        g_return_val_if_fail (path->data != NULL, CORBA_OBJECT_NIL);
1004        g_return_val_if_fail (ev != NULL, CORBA_OBJECT_NIL);
1005
1006        ns =  oaf_name_service_get (ev);
1007        if (BONOBO_EX (ev) || ns == CORBA_OBJECT_NIL)
1008                return CORBA_OBJECT_NIL;
1009
1010        ctx = ns;
1011
1012        for (l = path; l != NULL; l = l->next) {
1013
1014                cn =  ORBit_string_to_CosNaming_Name (l->data, ev);
1015                if (BONOBO_EX (ev) || !cn)
1016                        break;
1017
1018                new_ctx = CosNaming_NamingContext_resolve (ctx, cn, ev);
1019                if (BONOBO_USER_EX (ev, ex_CosNaming_NamingContext_NotFound)) {
1020                        CORBA_exception_init (ev);
1021                        new_ctx = CosNaming_NamingContext_bind_new_context (
1022                                ctx, cn, ev);
1023                        if (BONOBO_EX (ev) || new_ctx == CORBA_OBJECT_NIL) {
1024                                CORBA_free (cn);
1025                                break;
1026                        }
1027                }
1028
1029                CORBA_free (cn);
1030
1031                if (BONOBO_EX (ev))
1032                        new_ctx = CORBA_OBJECT_NIL;
1033               
1034                CORBA_Object_release (ctx, ev);
1035
1036                ctx = new_ctx;
1037
1038                if (!ctx)
1039                        break;
1040        }
1041
1042        return ctx;
1043}
1044
1045static CosNaming_Name *
1046url_to_name (char *url, char *opt_kind)
1047{
1048        LName ln;
1049        LNameComponent lnc;
1050        CosNaming_Name *retval;
1051        CORBA_Environment ev;
1052
1053        g_return_val_if_fail (url != NULL, NULL);
1054
1055        CORBA_exception_init (&ev);
1056
1057        lnc = create_lname_component ();
1058        LNameComponent_set_id (lnc, url, &ev);
1059       
1060        if (opt_kind)
1061                LNameComponent_set_kind (lnc, opt_kind, &ev);
1062
1063        ln = create_lname ();
1064        LName_insert_component (ln, 1, lnc, &ev);
1065
1066        retval = LName_to_idl_form (ln, &ev);
1067
1068        LName_destroy (ln, &ev);
1069
1070        CORBA_exception_free (&ev);
1071
1072        return retval;
1073}
1074
1075static CosNaming_NamingContext
1076get_url_context (char *oafiid,
1077                 CORBA_Environment *ev)
1078{
1079        CosNaming_NamingContext  ctx = NULL;
1080        GList                   *path = NULL;
1081
1082        path = g_list_append (path, "GNOME");
1083        path = g_list_append (path, "URL");
1084        path = g_list_append (path, oafiid);
1085
1086        ctx = lookup_naming_context (path, ev);
1087
1088        g_list_free (path);
1089               
1090        return ctx;
1091}
1092
1093void
1094bonobo_url_register (char              *oafiid,
1095                     char              *url,
1096                     char              *mime_type,
1097                     Bonobo_Unknown     object,
1098                     CORBA_Environment *ev)
1099{
1100        CosNaming_NamingContext  ctx = NULL;
1101        CosNaming_Name          *cn;
1102
1103        bonobo_return_if_fail (oafiid != NULL, ev);
1104        bonobo_return_if_fail (url != NULL, ev);
1105        bonobo_return_if_fail (object != CORBA_OBJECT_NIL, ev);
1106       
1107        ctx = get_url_context (oafiid, ev);
1108               
1109        if (BONOBO_EX (ev) || ctx == CORBA_OBJECT_NIL)
1110                return;
1111       
1112        cn = url_to_name (url, mime_type);
1113
1114        CosNaming_NamingContext_bind (ctx, cn, object, ev);
1115
1116        CORBA_free (cn);
1117
1118        CORBA_Object_release (ctx, NULL);
1119}
1120
1121void
1122bonobo_url_unregister (char              *oafiid,
1123                       char              *url,
1124                       CORBA_Environment *ev)
1125{
1126        CosNaming_NamingContext  ctx = NULL;
1127        CosNaming_Name          *cn;
1128
1129        bonobo_return_if_fail (oafiid != NULL, ev);
1130        bonobo_return_if_fail (url != NULL, ev);
1131
1132        ctx = get_url_context (oafiid, ev);
1133               
1134        if (BONOBO_EX (ev) || ctx == CORBA_OBJECT_NIL)
1135                return;
1136       
1137        cn = url_to_name (url, NULL);
1138
1139        CosNaming_NamingContext_unbind (ctx, cn, ev);
1140
1141        CORBA_free (cn);
1142
1143        CORBA_Object_release (ctx, NULL);
1144}
1145
1146Bonobo_Unknown
1147bonobo_url_lookup (char              *oafiid,
1148                   char              *url,
1149                   CORBA_Environment *ev)
1150{
1151        CosNaming_NamingContext  ctx = NULL;
1152        CosNaming_Name          *cn;
1153        Bonobo_Unknown           retval;
1154
1155        bonobo_return_val_if_fail (oafiid != NULL, CORBA_OBJECT_NIL, ev);
1156        bonobo_return_val_if_fail (url != NULL, CORBA_OBJECT_NIL, ev);
1157
1158        ctx = get_url_context (oafiid, ev);
1159               
1160        if (BONOBO_EX (ev) || ctx == CORBA_OBJECT_NIL)
1161                return CORBA_OBJECT_NIL;
1162       
1163        cn = url_to_name (url, NULL);
1164
1165        retval = CosNaming_NamingContext_resolve (ctx, cn, ev);
1166
1167        CORBA_free (cn);
1168
1169        CORBA_Object_release (ctx, NULL);
1170
1171        return retval;
1172}
1173
Note: See TracBrowser for help on using the repository browser.