How to Move from C++ to OSM

Technical Article

Abstract

This article explains to you how to move from C++ to OSM language to manage your catalog features.

Introduction

This migration is strongly recommended for several reasons

Catalogs are defined by writing a file containing OSM statements (the OSM file) and translated into CATfct catalogs with the CATfctEditorAssistant tool. The reverse is also possible: a CATfct can also be translated back to OSM.

Fig. 1 - From OSM to CATfct and back with CATfctEditorAssistant

Creation of new catalogs is not addressed in this article because it is not a migration case, see the appropriate article [2]

[Top]

Catalog Feature Changes

If you decide to use OSM language to define your StartUp, you can delete your source creating or updating them.  There are useless.

Catalog Update

First, obtain the OSM version of the CATfct with CATfctEditorAssistant:

$ CATfctEditorAssistant -generate-osm -client-id myid myCatalog.CATfct myCatalog.osm

Notes:

Next, edit the newly created OSM file (myCatalog.osm) to include the changes. For further information on OSM, please refer to the Modeling Feature StartUps article [1].

$ your_favorite_editor myCatalog.osm

Finally, upgrade the CATfct with the OSM file (myCatalog.osm):

$ CATfctEditorAssistant -upgrade-catalog -client-id myid myCatalog.CATfct myCatalog.osm

Notes:

This process is similar to the edit-compile cycle that you are probably very familiar with, except that you are not starting from scratch but from the OSM that corresponds to an existing CATfct. The three steps are illustrated in Fig. 2 below:

Fig. 2 - How to upgrade an existing catalog

[Top]

Catalog Migration

In this section you will find explanation about the reasons of the requirement and how to realize them:

Catalogs with StartUp Extensions

These catalogs can be migrated because this will allow extensions to be located at run-time without the need to open the catalog (See the AccessCatalog/AddExtension Pattern section). The OSM does not require any modification:

$ CATfctEditorAssistant -generate-osm -client-id myid myCatalog.CATfct myCatalog.osm
$ CATfctEditorAssistant -upgrade-catalog -client-id myid myCatalog.CATfct myCatalog.osm

You should also add the following lines to the extension CATRsc file, which will trigger the creation of the applicative container:

ExtensionFeature.ContType="CATFeatCont";
ExtensionFeature.ContSuperType="CATFeatCont";

As a consequence, applicative containers for extensions need not be created explicitly (See the AccessCatalog/AddExtension Pattern section).

Catalogs with Derivable StartUps

StartUps that are derivable used to be declared with CATCreatePublicSpecsInFile which then writes this information in CATSpecs files. This information must now be specified in OSM by adding the #inheritability(caa) facet on the corresponding StartUps.

For example, this is how the StartUp CAAOsmAdd is made derivable:

...
	feature CAAOsmAdd #startup #inheritability(caa) {
...

The migration steps for a catalog containing derivable StartUps:

$ CATfctEditorAssistant -generate-osm -client-id myid myCatalog.CATfct myCatalog.osm
$ .... # edit myCatalog.osm to add #inheritability(caa) on derivable StartUps
$ CATfctEditorAssistant -upgrade-catalog -client-id myid myCatalog.CATfct myCatalog.osm

Otherwise

You are strongly invited to upgrade any catalog in order to increase the instantiation's time.  If your Startup's catalog is updated, its instantation will be faster as described in the About CATOsmSUHandler section. The OSM does not require any modification.

$ CATfctEditorAssistant -generate-osm -client-id myid myCatalog.CATfct myCatalog.osm
$ CATfctEditorAssistant -upgrade-catalog -client-id myid myCatalog.CATfct myCatalog.osm

[Top]

Impacts on Run-time Code

In this section, we will explain how to migrate the run-time code that used APIs from Table 1. It must be converted to use a new class: CATOsmSUHandler. This new APIs will make the code simpler, sometimes replacing up to three calls with just a single one.

Table 1 - The StartUp retrieval APIs
Header File API Purpose
CATCatalogFactoryServices.h AccessCatalog Loads a catalog
CATICatalog.h RetrieveSU Retrieves a StartUp

We will now illustrate how some of the most frequent patterns of usage can be converted:

[Top]

The AccessCatalog/RetrieveSU Pattern

The previous way of retrieving a StartUp was to first open a catalog with AccessCatalog to get a CATICatalog handle on it, and then using this handle to retrieve the StartUp with RetrieveSU:

	...
	HRESULT           rc;
	CATBaseUnknown    *piContainter = NULL;
	...
	CATUnicodeString  catalogName("CAAOsmCatalogSU.CATfct");
	CATUnicodeString  clientId("CAAOsmClientId");
	CATICatalog      *piStartUpCatalog = NULL;
	rc = ::AccessCatalog(&catalogName, &clientId, piContainer, &piStartUpCatalog);
	...
	CATBaseUnknown   *pNovelSU = NULL;
	CATUnicodeString  novelSUType("CAAOsmNovel");
	rc = piStartUpCatalog->RetrieveSU(&pNovelSU, &novelSUType, "CATISpecObject");
	...
	CATISpecObject   *piNovelSU = (CATISpectObject *) pNovelSU;
	...

This is now done by constructing a CATOsmSUHandler object with three parameters: the StartUp name, the client ID and the catalog name and then calling its RetrieveSU method :

	...
	HRESULT           rc;
	CATUnicodeString  catalogName("CAAOsmCatalogSU.CATfct");
	CATUnicodeString  clientId("CAAOsmClientId");
	CATUnicodeString  novelSUType("CAAOsmNovel");
	CATOsmSUHandler   novelSUHandler(novelSUType, clientId, catalogName);
	CATISpecObject_var spNovelSU = NULL_var;
	rc = novelSUHandler.RetrieveSU(spNovelSU);
	...

As you can see the new code is simpler: one call instead of two. You must note that the StartUp is now returned as a smart pointer to its CATISpecObject interface (previously it was a pointer to CATBaseUnknown that had to be cast into a CATISpecObject). Due to the fact that it is now a smart pointer, a Release is not required (it will be Release'd once its scope ends). This also means that an AddRef is necessary if the smart pointer continues to be used outside of its scope (like when returning it to a caller function for example).

[Top]

The AccessCatalog/RetrieveSU/Instanciate Pattern

This pattern is similar to the one above, with the additional step of instantiating the StartUp retrieved:

	...
	HRESULT           rc;
	CATBaseUnknown    *piContainter = NULL;
	...
	CATUnicodeString  catalogName("CAAOsmCatalogSU.CATfct");
	CATUnicodeString  clientId("CAAOsmClientId");
	CATICatalog      *piStartUpCatalog = NULL;
	rc = ::AccessCatalog(&catalogName, &clientId, piContainer, &piStartUpCatalog);
	...
	CATBaseUnknown   *pNovelSU = NULL;
	CATUnicodeString  novelSUType("CAAOsmNovel");
	rc = piStartUpCatalog->RetrieveSU(&pNovelSU, &novelSUType, "CATISpecObject");
	...
	CATISpecObject   *piNovelSU = (CATISpectObject *) pNovelSU;
	...
	CATISpecObject   *piNovelInst1 = piNovelSU->Instanciate(CATUnicodeString("CAAOsmNovel1"),
	                                                        piContainer);
	...

The replacement is still done with CATOsmSUHandler but with its Instanciate method. If the handle on the StartUp is not required, the call to RetrieveSU can be skipped.

	...
	HRESULT           rc;
	CATBaseUnknown    *piContainter = NULL;
	...
	CATUnicodeString  catalogName("CAAOsmCatalogSU.CATfct");
	CATUnicodeString  clientId("CAAOsmClientId");
	CATUnicodeString  novelSUType("CAAOsmNovel");
	CATOsmSUHandler   novelSUHandler(novelSUType, clientId, catalogName);
	CATISpecObject_var spNovelInst = NULL_var;
	rc = novelSUHandler.Instanciate(spNovelInst, piContainer, CATUnicodeString("CAAOsmNovel1"));
	...

Since the instance is returned as a smart pointer to its CATISpecObject, the same life-cycle rule applies as with the StartUp retrieved via RetrieveSU.

About CATOsmSUHandler  

The last argument of the CATOsmSUHandler  class, the name of the catalog of the feature to instantiate, can be useless if the catalog has been upgrated since V5R18SP2. If the catalog has been migrated, that you refer or not the catalog name, the instantiation will be faster.

	...
	HRESULT           rc;
	CATBaseUnknown    *piContainter = NULL;
	...
	CATUnicodeString  catalogName("CAAOsmCatalogSU.CATfct");  // this line is useless
	CATUnicodeString  clientId("CAAOsmClientId");
	CATUnicodeString  novelSUType("CAAOsmNovel");
	CATOsmSUHandler   novelSUHandler(novelSUType, clientId , catalogName);
	...

[Top]

The AccessCatalog/AddExtension Pattern

A catalog containing Feature Extensions is opened via AccessCatalog with an applicative container. Another feature can then add one of these extensions by calling the AddExtension method of its CATIOsmExtendable interface. Added extensions are created in the applicative container.

	...
	HRESULT           rc;
         CATIOsmExtendable *piExtendable = NULL;
	...
	//
  	// Applicative container creation
	//
	CATBaseUnknown    *piContainter = NULL;
	...
	CATUnicodeString  catalogName("CAAOsmExt2Catalog.CATfct");
	CATUnicodeString  clientId("CAAOsmClientId1");
	CATICatalog      *piExtensionsCatalog = NULL;
	rc = ::AccessCatalog(&catalogName, &clientId, piContainer, &piExtensionsCatalog);
	...
	rc = piExtentable->AddExtension("CAAOsmChildrensNovel");
	...

With OSM, it is no longer necessary to open the extensions catalog. As the catalog have been migrated the Feature Modeler will be able to locate the extension by its name. Both the AccessCatalog call and the applicative container creation code are discarded:

	...
	HRESULT           rc;
         CATIOsmExtendable *piExtendable = NULL;
	...
	rc = piExtentable->AddExtension("CAAOsmChildrensNovel");
	...

Please note that the container creation code is suppressed because the following lines are added in the CATRsc file of the Feature Extension:

ExtensionFeature.ContType="CATFeatCont";
ExtensionFeature.ContSuperType="CATFeatCont";

In summary, the AddExtension method of CATIOsmExtendable no longer requires the catalog to be opened, provided it has been migrated. The container creation code can also be removed if the container type and supertype are defined in the CATRsc file.

[Top]

Useless APIs

For your reference, Table 2 lists all the APIs that are useless as the result in the introduction of OSM:

Table 2 - Suppressed APIs
Header File API Purpose Usage Patterns
CATCatalogFactoryServices.h AccessCatalog Loads a catalog AccessCatalog/RetrieveSU
AccessCatalog/RetrieveSU/Instanciate
AccessCatalog/AddExtension
CreateCatalog Creates a catalog  
SaveCatalog Saves a catalog  
UpgradeCatalog Loads a catalog to be updated  
CATICatalog.h CreateSUInCatalog Creates a StartUp  
OpenPrereqCatalog Opens a catalog  
RetrieveSU Retrieves a StartUp AccessCatalog/RetrieveSU
SetClientId Assigns a client ID  
CATIOsmExtensionFactory.h CreateExtension Creates an Extension StartUp  
CATOsmSUFactory.h CATOsmSUFactory Creates a StartUp  
CATPublicSpecsDef.h      
CATPublicSpecsFileServices.h CATCreatePublicSpecsInFile Declare public and derivable StartUps  
CATAddPublicAttributeToFile Declare public attributes  

[Top]

In Short

This article shows how OSM impacts your existing catalogs and run-time code:

  1. Existing catalogs are updated by generating the OSM, modify it and finally use it to upgrade the catalog
  2. Code that implements the AccessCatalog/RetrieveSU/Instanciate pattern should be converted to the new and simpler CATOsmSUHandler/RetrieveSU and/or CATOsmSUHandler/Instantiate.

[Top]

References

[1] Modeling Feature StartUps
[2] Managing StartUp Catalogs

[Top]

History

Version: 1 [Oct 2009] Document created

[Top]