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

Revision 16754, 12.2 KB checked in by ghudson, 23 years ago (diff)
Merge with bonobo 1.0.14; remove ATHTOOLROOT support.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/**
3 * bonobo-moniker: Object naming abstraction
4 *
5 * Author:
6 *      Michael Meeks (michael@helixcode.com)
7 *
8 * Copyright 2000, Helix Code, Inc.
9 */
10#include <config.h>
11
12#include <bonobo/bonobo-exception.h>
13#include <bonobo/bonobo-moniker.h>
14#include <bonobo/bonobo-moniker-util.h>
15#include <bonobo/bonobo-moniker-extender.h>
16
17struct _BonoboMonikerPrivate {
18        Bonobo_Moniker parent;
19
20        int            prefix_len;
21        char          *prefix;
22
23        char          *name;
24
25        gboolean       sensitive;
26};
27
28#define PARENT_TYPE BONOBO_X_OBJECT_TYPE
29
30static GtkObjectClass *bonobo_moniker_parent_class;
31
32#define CLASS(o) BONOBO_MONIKER_CLASS (GTK_OBJECT (o)->klass)
33
34static inline BonoboMoniker *
35bonobo_moniker_from_servant (PortableServer_Servant servant)
36{
37        return BONOBO_MONIKER (bonobo_object_from_servant (servant));
38}
39
40static Bonobo_Moniker
41impl_get_parent (PortableServer_Servant servant,
42                 CORBA_Environment     *ev)
43{
44        BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
45
46        return CLASS (moniker)->get_parent (moniker, ev);
47}
48
49static void
50impl_set_parent (PortableServer_Servant servant,
51                 const Bonobo_Moniker   value,
52                 CORBA_Environment     *ev)
53{
54        BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
55
56        CLASS (moniker)->set_parent (moniker, value, ev);
57}
58
59/**
60 * bonobo_moniker_set_parent:
61 * @moniker: the moniker
62 * @parent: the parent
63 * @ev: a corba exception environment
64 *
65 *  This sets the monikers parent; a moniker is really a long chain
66 * of hierarchical monikers; referenced by the most local moniker.
67 * This sets the parent pointer.
68 **/
69void
70bonobo_moniker_set_parent (BonoboMoniker     *moniker,
71                           Bonobo_Moniker     parent,
72                           CORBA_Environment *ev)
73{
74        g_return_if_fail (BONOBO_IS_MONIKER (moniker));
75       
76        bonobo_object_release_unref (moniker->priv->parent, ev);
77        moniker->priv->parent = bonobo_object_dup_ref (parent, ev);
78}
79
80/**
81 * bonobo_moniker_get_parent:
82 * @moniker: the moniker
83 * @ev: a corba exception environment
84 *
85 * See bonobo_moniker_set_parent;
86 *
87 * Return value: the parent of this moniker
88 **/
89Bonobo_Moniker
90bonobo_moniker_get_parent (BonoboMoniker     *moniker,
91                           CORBA_Environment *ev)
92{
93        g_return_val_if_fail (BONOBO_IS_MONIKER (moniker),
94                              CORBA_OBJECT_NIL);
95       
96        if (moniker->priv->parent == CORBA_OBJECT_NIL)
97                return CORBA_OBJECT_NIL;
98       
99        return bonobo_object_dup_ref (moniker->priv->parent, ev);
100}
101
102/**
103 * bonobo_moniker_get_name:
104 * @moniker: the moniker
105 *
106 * gets the unescaped name of the moniker less the prefix eg
107 * file:/tmp/hash\#.gz returns /tmp/hash#.gz
108 *
109 * Return value: the string
110 **/
111const char *
112bonobo_moniker_get_name (BonoboMoniker *moniker)
113{       
114        const char *str;
115
116        g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), "");
117
118        str = CLASS (moniker)->get_name (moniker);
119
120        if (str)
121                return str + moniker->priv->prefix_len;
122        else
123                return "";
124}
125
126/**
127 * bonobo_moniker_get_name_full:
128 * @moniker: the moniker
129 *
130 * gets the full unescaped display name of the moniker eg.
131 * file:/tmp/hash\#.gz returns file:/tmp/hash#.gz
132 *
133 * Return value: the string
134 **/
135const char *
136bonobo_moniker_get_name_full (BonoboMoniker *moniker)
137{       
138        g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), "");
139
140        return CLASS (moniker)->get_name (moniker);
141}
142
143/**
144 * bonobo_moniker_get_name_escaped:
145 * @moniker: a moniker
146 *
147 * Get the full, escaped display name of the moniker eg.
148 * file:/tmp/hash\#.gz returns file:/tmp/hash\#.gz
149 *
150 * Return value: the dynamically allocated string,
151 * or NULL in case of failure.
152 * Must release with g_free().
153 **/
154char *
155bonobo_moniker_get_name_escaped (BonoboMoniker *moniker)
156{
157        g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), NULL);
158
159        return bonobo_moniker_util_escape (
160                CLASS (moniker)->get_name (moniker), 0);
161}
162
163/**
164 * bonobo_moniker_set_name:
165 * @moniker: the BonoboMoniker to configure.
166 * @name: new name for this moniker.
167 * @num_chars: number of characters in name to copy.
168 *
169 * This functions sets the moniker name in @moniker to be @name.
170 */
171void
172bonobo_moniker_set_name (BonoboMoniker *moniker,
173                         const char    *name,
174                         int            num_chars)
175{
176        char *str;
177
178        g_return_if_fail (BONOBO_IS_MONIKER (moniker));
179
180        str = bonobo_moniker_util_unescape (name, num_chars);
181
182        CLASS (moniker)->set_name (moniker, str);
183
184        g_free (str);
185}
186
187/**
188 * bonobo_moniker_get_prefix:
189 * @moniker: a moniker
190 *
191 * Return value: the registered prefix for this moniker or
192 * NULL if there isn't one. eg "file:"
193 **/
194const char *
195bonobo_moniker_get_prefix (BonoboMoniker *moniker)
196{
197        g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), "");
198
199        return moniker->priv->prefix;
200}
201
202static void
203impl_bonobo_moniker_set_name (BonoboMoniker *moniker,
204                              const char    *unescaped_name)
205{
206        g_return_if_fail (BONOBO_IS_MONIKER (moniker));
207        g_return_if_fail (strlen (unescaped_name) >= moniker->priv->prefix_len);
208
209        g_free (moniker->priv->name);
210        moniker->priv->name = g_strdup (unescaped_name);
211}
212
213static const char *
214impl_bonobo_moniker_get_name (BonoboMoniker *moniker)
215{
216        g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), "");
217
218        return moniker->priv->name;
219}
220
221static CORBA_char *
222bonobo_moniker_default_get_display_name (BonoboMoniker     *moniker,
223                                         CORBA_Environment *ev)
224{
225        CORBA_char *ans, *parent_name;
226        char       *tmp;
227       
228        parent_name = bonobo_moniker_util_get_parent_name (
229                BONOBO_OBJREF (moniker), ev);
230
231        if (BONOBO_EX (ev))
232                return NULL;
233
234        if (!parent_name)
235                return CORBA_string_dup (moniker->priv->name);
236
237        if (!moniker->priv->name)
238                return parent_name;
239
240        tmp = g_strdup_printf ("%s%s", parent_name, moniker->priv->name);
241
242        if (parent_name)
243                CORBA_free (parent_name);
244
245        ans = CORBA_string_dup (tmp);
246
247        g_free (tmp);
248       
249        return ans;
250}
251
252static Bonobo_Moniker
253bonobo_moniker_default_parse_display_name (BonoboMoniker     *moniker,
254                                           Bonobo_Moniker     parent,
255                                           const CORBA_char  *name,
256                                           CORBA_Environment *ev)
257{
258        int i;
259       
260        g_return_val_if_fail (moniker != NULL, CORBA_OBJECT_NIL);
261        g_return_val_if_fail (moniker->priv != NULL, CORBA_OBJECT_NIL);
262        g_return_val_if_fail (strlen (name) >= moniker->priv->prefix_len, CORBA_OBJECT_NIL);
263
264        bonobo_moniker_set_parent (moniker, parent, ev);
265
266        i = bonobo_moniker_util_seek_std_separator (name, moniker->priv->prefix_len);
267
268        bonobo_moniker_set_name (moniker, name, i);
269
270        return bonobo_moniker_util_new_from_name_full (BONOBO_OBJREF (moniker),
271                                                       &name [i], ev); 
272}
273
274static CORBA_long
275bonobo_moniker_default_equal (BonoboMoniker     *moniker,
276                              const CORBA_char  *display_name,
277                              CORBA_Environment *ev)
278{
279        int         i;
280        CORBA_long  offset;
281        const char *p;
282        char       *name;
283       
284        if (moniker->priv->parent != CORBA_OBJECT_NIL) {
285                offset = Bonobo_Moniker_equal (
286                        moniker->priv->parent, display_name, ev);
287                if (BONOBO_EX (ev) || offset == 0)
288                        return 0;
289        } else
290                offset = 0;
291
292        p = &display_name [offset];
293
294        i = bonobo_moniker_util_seek_std_separator (p, moniker->priv->prefix_len);
295
296        name = bonobo_moniker_get_name_escaped (moniker);
297
298        /* FIXME: this has not been tested with moniker lists  */
299/*      g_warning ("Compare %d chars of '%s' to '%s' - case sensitive ?%c",
300        i, name, p, moniker->priv->sensitive?'y':'n');*/
301
302        if (( moniker->priv->sensitive && !strncmp       (name, p, i)) ||
303            (!moniker->priv->sensitive && !g_strncasecmp (name, p, i))) {
304/*              g_warning ("Matching moniker - equal");*/
305                return i + offset;
306        } else {
307/*              g_warning ("No match");*/
308                return 0;
309        }
310
311        g_free (name);
312}
313
314static CORBA_char *
315impl_get_display_name (PortableServer_Servant servant,
316                       CORBA_Environment     *ev)
317{
318        BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
319       
320        return CLASS (moniker)->get_display_name (moniker, ev);
321}
322
323static Bonobo_Moniker
324impl_parse_display_name (PortableServer_Servant servant,
325                         Bonobo_Moniker         parent,
326                         const CORBA_char      *name,
327                         CORBA_Environment     *ev)
328{
329        BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
330
331        return CLASS (moniker)->parse_display_name (moniker, parent, name, ev);
332}
333
334static Bonobo_Unknown
335impl_resolve (PortableServer_Servant       servant,
336              const Bonobo_ResolveOptions *options,
337              const CORBA_char            *requested_interface,
338              CORBA_Environment           *ev)
339{
340        BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
341        Bonobo_Unknown retval;
342
343        /* Try a standard resolve */
344        retval = CLASS (moniker)->resolve (moniker, options,
345                                           requested_interface, ev);
346
347        /* Try an extender */
348        if (!BONOBO_EX (ev) && retval == CORBA_OBJECT_NIL &&
349            moniker->priv->prefix) {
350
351                Bonobo_Unknown extender;
352               
353                extender = bonobo_moniker_find_extender (
354                        moniker->priv->prefix,
355                        requested_interface, ev);
356               
357                if (BONOBO_EX (ev))
358                        return CORBA_OBJECT_NIL;
359
360                else if (extender != CORBA_OBJECT_NIL) {
361                        retval = Bonobo_MonikerExtender_resolve (
362                                extender, BONOBO_OBJREF (moniker),
363                                options, moniker->priv->name,
364                                requested_interface, ev);
365
366                        bonobo_object_release_unref (extender, ev);
367                }
368        }
369
370        if (!BONOBO_EX (ev) && retval == CORBA_OBJECT_NIL)
371                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
372                                     ex_Bonobo_Moniker_InterfaceNotFound,
373                                     NULL);
374
375        return retval;
376}
377
378static CORBA_long
379impl_equal (PortableServer_Servant servant,
380            const CORBA_char      *displayName,
381            CORBA_Environment     *ev)
382{
383        BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
384
385        return CLASS (moniker)->equal (moniker, displayName, ev);
386}
387
388static void
389bonobo_moniker_destroy (GtkObject *object)
390{
391        BonoboMoniker *moniker = BONOBO_MONIKER (object);
392
393        if (moniker->priv->parent != CORBA_OBJECT_NIL)
394                bonobo_object_release_unref (moniker->priv->parent, NULL);
395
396        g_free (moniker->priv->prefix);
397        g_free (moniker->priv->name);
398        g_free (moniker->priv);
399
400        bonobo_moniker_parent_class->destroy (object);
401}
402
403static void
404bonobo_moniker_class_init (BonoboMonikerClass *klass)
405{
406        GtkObjectClass *oclass = (GtkObjectClass *)klass;
407        POA_Bonobo_Moniker__epv *epv = &klass->epv;
408
409        bonobo_moniker_parent_class = gtk_type_class (PARENT_TYPE);
410
411        oclass->destroy = bonobo_moniker_destroy;
412
413        klass->get_parent = bonobo_moniker_get_parent;
414        klass->set_parent = bonobo_moniker_set_parent;
415        klass->get_display_name = bonobo_moniker_default_get_display_name;
416        klass->parse_display_name = bonobo_moniker_default_parse_display_name;
417        klass->equal = bonobo_moniker_default_equal;
418
419        klass->set_name   = impl_bonobo_moniker_set_name;
420        klass->get_name   = impl_bonobo_moniker_get_name;
421
422        epv->_get_parent      = impl_get_parent;
423        epv->_set_parent      = impl_set_parent;
424        epv->getDisplayName   = impl_get_display_name;
425        epv->parseDisplayName = impl_parse_display_name;
426        epv->resolve          = impl_resolve;
427        epv->equal            = impl_equal;
428}
429
430static void
431bonobo_moniker_init (GtkObject *object)
432{
433        BonoboMoniker *moniker = BONOBO_MONIKER (object);
434
435        moniker->priv = g_new (BonoboMonikerPrivate, 1);
436
437        moniker->priv->parent = CORBA_OBJECT_NIL;
438        moniker->priv->name   = NULL;
439}
440
441BONOBO_X_TYPE_FUNC_FULL (BonoboMoniker,
442                           Bonobo_Moniker,
443                           PARENT_TYPE,
444                           bonobo_moniker);
445
446/**
447 * bonobo_moniker_construct:
448 * @moniker: an un-constructed moniker object.
449 * @corba_moniker: a CORBA handle inheriting from Bonobo::Moniker, or
450 * CORBA_OBJECT_NIL, in which case a base Bonobo::Moniker is created.
451 * @prefix: the prefix name of the moniker eg. 'file:', '!' or 'tar:' or NULL
452 * @shlib_id:
453 *
454 *  Constructs a newly created bonobo moniker with the given arguments.
455 *
456 * Return value: the constructed moniker or NULL on failure.
457 **/
458BonoboMoniker *
459bonobo_moniker_construct (BonoboMoniker *moniker,
460                          const char    *prefix)
461{
462        if (prefix) {
463                moniker->priv->prefix = g_strdup (prefix);
464                moniker->priv->prefix_len = strlen (prefix);
465        }
466
467        moniker->priv->sensitive = TRUE;
468
469        return moniker;
470}
471
472/**
473 * bonobo_moniker_set_case_sensitive:
474 * @moniker: the moniker
475 * @sensitive: whether to see case on equality compare
476 *
477 * Sets up whether we use case sensitivity for the default equal impl.
478 **/
479void
480bonobo_moniker_set_case_sensitive (BonoboMoniker *moniker,
481                                   gboolean       sensitive)
482{
483        g_return_if_fail (BONOBO_IS_MONIKER (moniker));
484
485        moniker->priv->sensitive = sensitive;
486}
487
488/**
489 * bonobo_moniker_get_case_sensitive:
490 * @moniker: the moniker
491 *
492 * Return value: whether we use case sensitivity for the default equal impl.
493 **/
494gboolean
495bonobo_moniker_get_case_sensitive (BonoboMoniker *moniker)
496{
497        g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), FALSE);
498
499        return moniker->priv->sensitive;
500}
Note: See TracBrowser for help on using the repository browser.