Adding new IOR Parsers to TAO

# Introduction

#### What is an IOR Parser?

TAO supports several IOR formats, including `IOR:`, `corbaloc:`, `corbaname:` and `file:`. However, some applications may benefit from other formats, for example, `http:` could allow applications to download an object reference from a web server.

Adding new IOR formats to the ORB is a simple task, the ORB takes advantage ACE's Service Configurator to dynamically load new IOR Parsers. The implementation of `string_to_object()` queries each available IOR Parser to convert an string into an object reference. Application developers can implement their own parsers and dynamically (or statically) add them to the ORB, without any need to recompile TAO.

#### Why aren't the IOR parsers in TAO enough?

TAO provides a basic set of IOR parsers, but it would be detrimental to TAO's footprint to implement a huge collection of IOR parsers into the ORB. Moreover, the DOC group does not have the ability to create all possible IOR parsers: many applications will use proprietary databases to configure the ORB.

#### Why should I use an IOR parser?

Using an IOR parser is more convenient than, say, setting up the ad-hoc configuration code in `main()`. It also allows for easier integration with other TAO components, such as the `-ORBInitRef` options.

# Implementation

# How do you Implement an IOR Parser?

Implementing an IOR parser is easy, you must implement a class derived from `TAO_IOR_Parser`. As an example we will develop an HTTP IOR parser, the class declaration will probably look like this:

    class HTTP_Parser : public TAO_IOR_Parser
    {
    public:
      virtual int match_prefix (const char *ior_string) const;
      virtual CORBA::Object_ptr parse_string (const char *ior,
                                              CORBA::ORB_ptr orb,
                                              CORBA::Environment &)
          ACE_THROW_SPEC ((CORBA::SystemException));
    };

For maximal portability this class uses the alternative mapping for exception handling, if you are not familiar with the alternative mapping you can safely ignore the `CORBA::Environment` argument. Please read the exception handling documentation for more details.

- match_prefix This method must recognize all the IOR prefixes that this parser supports. Normally this is a single prefix, a typical implementation will look like this:

      int
      HTTP_Parser::match_prefix (const char *ior_string) const
      {
        static char http_prefix[] = "http:";
        int cmp = ACE_OS::strncmp (ior_string, http_prefix, sizeof(http_prefix));
        return (cmp == 0);
      }

- parse_string This method implements the real string parsing, you can safely assume that the string has been validated by the `match_prefix()` method. Typically, this method will obtain the IOR string, in our example by downloading the document from the web server, and then uses `string_to_object()` to return the object reference:

      CORBA::Object_ptr
      HTTP_Parser::parse_string (const char *ior,
                                 CORBA::ORB_ptr orb,
                                 CORBA::Environment &ACE_TRY_ENV)
          ACE_THROW_SPEC ((CORBA::SystemException))
      {
        // Parse IOR as if it was an http:-URL
        ACE_URL_Addr *url_addr =
          ACE_URL_Addr::create_addr (ior);

        ACE_HTTP_Addr *http_addr =
          ACE_dynamic_cast(ACE_HTTP_Addr*,url_addr);

        // Connect to the remote host and download the web page, store the
        // contents in:
        char *document_contents = ...;

        return orb->string_to_object (document_contents, ACE_TRY_ENV);
      }

#### How do you add an IOR Parser to the ORB?

As we mentioned above, TAO uses the ACE Service Configurator framework to find (dynamically or statically) the IOR parsers. You may want to read the ACE tutorial on this subject, but the process is mostly mechanic, and described here.

First you must declare, in the header file, a factory method and a description of the service, this is easily accomplished via the following ACE macros:

    ACE_FACTORY_DECLARE (Export_Prefix, HTTP_Parser)
    ACE_STATIC_SVC_DELCARE_EXPORT (Export_Prefix, HTTP_Parser)

If you are only going to use Unix-like compilers and linkers, then you can simply use `TAO` in place of `Export_Prefix`. However, under Microsoft Windows variants, this string must be the prefix of the DLL export/import macros used by your library. If you are going to statically link your IOR Parser into the application you will also need to add `ACE_STATIC_SVC_REQUIRE`, as follows:

    ACE_FACTORY_DECLARE (Export_Prefix, HTTP_Parser)
    ACE_STATIC_SVC_DELCARE_EXPORT (Export_Prefix, HTTP_Parser)
    ACE_STATIC_SVC_REQUIRE (HTTP_Parser)

Next you must implement the services defined above, using some other group of helper macros, in your source file you should add:

    ACE_STATIC_SVC_DEFINE (HTTP_Parser,
                           ACE_TEXT ("HTTP_Parser"),
                           ACE_SVC_OBJ_T,
                           &ACE_SVC_NAME (HTTP_Parser),
                           ACE_Service_Type::DELETE_THIS |
                           ACE_Service_Type::DELETE_OBJ,
                           0)
    ACE_FACTORY_DEFINE (Export_Prefix, HTTP_Parser)

The second argument to `ACE_STATIC_SVC_DEFINE` is the name of the service in ACE's Service Configurator. It is customary, but not required, to use the name of the class.

Finally you can dynamically add your IOR parser to the ORB using the `-ORBIORParser` option in the Resource Factory (see Options for TAO Components for details about ORB and Resource Factory options), for example:

    # svc.conf file
    static Resource_Factory "-ORBIORPaser HTTP_Parser"

would add our new parser to the ORB.

#### Are there any complete examples?

Yes, the IOR parsers in the ORB can serve as complete examples, please check: `FILE_Parser.h`, `CORBALOC_Parser.h`, `CORBANAME_Parser.h`, or `DLL_Parser.h`. Unfortunately there are no examples that show how to dynamically add a new IOR parser into the ORB.

Last modified: Tue Feb 20 16:32:13 PST 2001