## BonoboMonikerExtender BonoboMonikerExtender — A way to extend arbitary monikers |

## Synopsis

                        BonoboMonikerExtender;
                        BonoboMonikerExtenderClass;
    Bonobo_Unknown      (*BonoboMonikerExtenderFn)          (BonoboMonikerExtender *extender,
                                                             const Bonobo_Moniker parent,
                                                             const Bonobo_ResolveOptions *options,
                                                             const CORBA_char *display_name,
                                                             const CORBA_char *requested_interface,
                                                             CORBA_Environment *ev);
    BonoboMonikerExtender * bonobo_moniker_extender_new     (BonoboMonikerExtenderFn resolve,
                                                             gpointer data);
    Bonobo_MonikerExtender  bonobo_moniker_find_extender    (const gchar *name,
                                                             const gchar *interface,
                                                             CORBA_Environment *opt_ev);
    Bonobo_Unknown      bonobo_moniker_use_extender         (const gchar *extender_oafiid,
                                                             BonoboMoniker *moniker,
                                                             const Bonobo_ResolveOptions *options,
                                                             const CORBA_char *requested_interface,
                                                             CORBA_Environment *opt_ev);

## Object Hierarchy

      GObject
       +----BonoboObject
             +----BonoboMonikerExtender

## Description

A moniker extender is used to extend the functionality of a moniker. There are two standard moniker extenders that cannot be system wide, since they use the oaf database to expand the scope of a moniker to arbitrarily many interfaces. These are invoked explicitely by monikers implementing the stream interface in the following way:

Example 18. Explicit Stream extender usage example

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Bonobo_Unknown
    example_moniker_resolve (BonoboMoniker               *moniker,
                 const Bonobo_ResolveOptions *options,
                 const CORBA_char            *requested_interface,
                 CORBA_Environment           *ev)
    {
        if (!strcmp (requested_interface, "IDL:Bonobo/Stream:1.0"))
            return handle_stream (moniker, options, ev);
        else
            return bonobo_moniker_use_extender (
                "OAFIID:Bonobo_MonikerExtender_stream",
                moniker, options, requested_interface, ev);
    }

The moniker extender essentialy resolves 'moniker' against stream and by some means ( not known when the moniker was written ) converts this to a new exotic interface - via. the PersistStream interface.

All standard moniker extenders are registered by adding a fragment like this:

Example 19. Oaf information for an extender

    1
    2
    3
    <oaf_attribute name="bonobo:moniker_extender" type="stringv">
        <item value="file:"/>
    </oaf_attribute>

to the .oaf file. This registers the extender with the system, such that when a moniker resolve fails an extender can be found for any of the monikers with prefix specified in the "bonobo:moniker_extender" stringv.

Implementing your own extender is extremely simple, much like BonoboMonikerSimple.

Example 20. Oaf information for an extender

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Bonobo_Unknown
    example_extender_resolve (BonoboMonikerExtender *extender,
                  const Bonobo_Moniker   m,
                  const Bonobo_ResolveOptions *options,
                  const CORBA_char      *display_name,
                  const CORBA_char      *requested_interface,
                  CORBA_Environment     *ev)
    {
        ... resolve 'm' against an interface we know it supports ...
        ... then use that interface to provide requested_interface ...
    }

It is registered again in much the same way in your factory:

Example 21. Creating a new simple moniker

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    static BonoboObject *
    bonobo_std_moniker_factory (BonoboGenericFactory *this,
                    const char           *object_id,
                    void                 *data)
    {
        g_return_val_if_fail (object_id != NULL, NULL);
        if (!strcmp (object_id, "OAFIID:Bonobo_MonikerExtender_file"))
            return BONOBO_OBJECT (bonobo_moniker_extender_new (
                example_extender_resolve, NULL));
        else
            return NULL;
    }

## Details

### BonoboMonikerExtender

    typedef struct _BonoboMonikerExtender BonoboMonikerExtender;

Implements a moniker extender: Bonobo::MonikerExtender.

### BonoboMonikerExtenderClass

    typedef struct {
    	BonoboObjectClass      parent_class;

    	POA_Bonobo_MonikerExtender__epv epv;

    	BonoboMonikerExtenderFn resolve;
    } BonoboMonikerExtenderClass;

BonoboMonikerExtender's class.

### BonoboMonikerExtenderFn ()

    Bonobo_Unknown      (*BonoboMonikerExtenderFn)          (BonoboMonikerExtender *extender,
                                                             const Bonobo_Moniker parent,
                                                             const Bonobo_ResolveOptions *options,
                                                             const CORBA_char *display_name,
                                                             const CORBA_char *requested_interface,
                                                             CORBA_Environment *ev);

Moniker resolution callback function.

`extender` : | extender (self)
`parent` : | parent moniker
`options` : | resolve options
`display_name` : | ? FIXME
`requested_interface` : | ? FIXME
`ev` : |
Returns : | the resolution resulting object

### bonobo_moniker_extender_new ()

    BonoboMonikerExtender * bonobo_moniker_extender_new     (BonoboMonikerExtenderFn resolve,
                                                             gpointer data);

This creates a new moniker extender.

`resolve` : | the resolve function that will be used to do the extension
`data` : | user data to be passed back to the resolve function.
Returns : | the extender object

### bonobo_moniker_find_extender ()

    Bonobo_MonikerExtender  bonobo_moniker_find_extender    (const gchar *name,
                                                             const gchar *interface,
                                                             CORBA_Environment *opt_ev);

This routine tries to locate an extender for our moniker by examining a registry of extenders that map new interfaces to certain moniker names.

`name` : | the name of the moniker we want to extend eg. 'file:'
`interface` : | the interface we want to resolve to
`opt_ev` : | an optional corba exception environment.
Returns : | an appropriate extender or CORBA_OBJECT_NIL.

### bonobo_moniker_use_extender ()

    Bonobo_Unknown      bonobo_moniker_use_extender         (const gchar *extender_oafiid,
                                                             BonoboMoniker *moniker,
                                                             const Bonobo_ResolveOptions *options,
                                                             const CORBA_char *requested_interface,
                                                             CORBA_Environment *opt_ev);

Locates a known extender via. OAFIID; eg. OAFIID:Bonobo_Moniker_Extender_file

`extender_oafiid` : | The IID of the extender to use
`moniker` : | the moniker to extend
`options` : | resolve options
`requested_interface` : | the requested interface
`opt_ev` : | optional corba environment
Returns : | the resolved result or CORBA_OBJECT_NIL.