Jump to content

Object-Oriented Programming Using SOM and DSOM/Making Your Objects Persistent

From EDM2
Revision as of 00:31, 8 June 2013 by Martini (talk | contribs) (Created page with "The Persistence SOM (PSOM) Framework allows you to make all or part of a SOM object persistent. This means you can p1·eserve the state of an object, ever after the process that ...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The Persistence SOM (PSOM) Framework allows you to make all or part of a SOM object persistent. This means you can p1·eserve the state of an object, ever after the process that creates the object terminates. The Framework provides services that allow you to store an object to a file system or another form of per sistent store. It also provides services that permit you restore objects from the persistent storage.

Most applications already use some form of persistence. For example, a spreadsheet or a word processor stores user data in a file. The implementation of a spreadsheet typically contains logic that converts the data in the cells into some format that can be written to a file for storage. When an existing spread sheet is loaded, the reverse takes place. The logic converts the external data back to the cell format so the user can work with it.

The PSOM Framework simplifies these operations by providing a uniform interface to storage. A cell in a spreadsheet can be implemented as a persistent object, and its data can be stored and restored, using the services in the PSOM Framework. Any flattening and unflattening of data can be eliminated. Applications can also avoid writing low level I/O routines and therefore become more portable.

PSOM OVERVIEW??

To use the PSOM Framework, both the object and the client program that accesses the object must be PSOM aware. What doest.his mean? From the object perspective, it must be derived from a special persistent class and the persistent data must be specified explicitly. This is different from the DSOM approach where an object does not have to know in advance whether it is going to be distributed. The PSOM client is typically responsible for managing persistence by controlling when the persistent data is stored or restored.

The PSOM Framework can store and restore objects that are arbitrarily complex. This means that if an object contains pointers to other objects, the PSOM Framework can save and restore those referenced objects as well. In a hierarchy of objects, the client can control whether or not an object should be stored or restored with its children.

It should be noted that OMG is in the process of releasing a Persistence Service Specification. The goal of the Persistence Service Specification is to provide common interfaces to the mechanisms used for retaining and managing the persistent state of objects. It is expected that the next release of PSOM will comply with the OMG Persistence Service Specification. It is quite likely that the interfaces described in this chapter will change with the next release. However, the concepts behind them should remain the same. More on this can be found in Chapter 10.

The development of a PSOM application involves the following steps.

  1. Define the interface for your persistent objects, and write code to implement your objects.
  2. Create a client program that accesses and manages the objects.
  3. Build your classes and register them with the Interface Repository.
  4. Run the client program.

The following sections provide details on each of the above steps.

DEFINE AND IMPLEMENT A PERSISTENT OBJECT

To create a persistent object, we must first create a class that is derived from the SOMPPersistentObject class. The parent class for SOMPPersistentObject class is SOMObject. Therefore, your persistent object is still a SOM object, only it can potentially become persistent because it is dervied from the SOMPPersistentObject class.

All data that is to be stored persistently must be declared as an attribute of CORBA type. The persistent modifier must be set for each of these attributes in the implementation section of the IDL.

The following Person class is potentially persistent and contains two persistent and one non-persistent attributes.

#include <po.idl>
interface Person: SOMPPersistentObject
{
   attribute string name ;
   attribute string birthdate: 
   attribute short age;

   #ifdef _SOMIDL_
   implementation
   {
      releaseorder : _get_name , _set_ name.
                     _get_birthdate, _set_birthdate,
                     _get_age, _set_age;

      somplsDirty:override;

      name: persistent;
      birthdate: persistent ;
    };
    #end if
} ;
#end if


The SOMPPersistentObject class provides the somplsDirty method, which is called by the PSOM Framework, to determine if an object has been changed. The PSOM Framework is optimized so it will only write out changed objects. Since the defauJt implementation of sompl sDirty always returns TROE, it is typically redefined by subclasses so that they can indicate whether an object has been changed. The implementation can invoke the s ompGe tDirty method to deter mine if the object h as been changed. An example of overriding this method is given in the Persistent Calendar application in Section 6.6 on page 148.

CLIENT PROGRAM

Although n ot absolutely necessary, the storing and r estoring of persistent objects is normally controlled by the client of the objects, so the client can decide when to store or restore the persistent state. To save and restor e persistent objects, a client program mu st initialize the PSOM Framework, manage t h e assignment of persisten t ID to t he persistent object, and invoke the save or the restor e methods.


PSOM Initialization

Every PSOM client must include the file <somp.xh> (or <somp.h> if using the C bindings). This file includes the constants, globaJ variables, and run-time interfaces that are used by PSOM. The client al so has to initialize the P SOM Framework by cr eating a Persistent Storage Manager object. The Persistent Storage Manager provides the interfaces for clients to save and restore persistent objects. The Persistent Storage Manager is created by instantiating the SOMPPersistentStorageMgr class using the SOMP PersistentStorageMgrNewO m acro or the new operator.

There is only one instance of a Persistent Storage Manager object for a process. Therefore, it does not matter how many times you invoke new on the SOMPPersistentStorageMgr class. It is quite normal to invoke new on the SOMPPersistentStorageMgr class locally in each procedure instead of passing the pointer to this object around. You must not free the Persistent Storage Manager object. If you do, the PSOM Framework will forget about previously initialized and restored objects.

A typical implementation of PSOM initialization is presented below:

#include <somp.Xh>
main()
{
     Environment                 *ev;
     SOMPPersistentStorageMgr    *psm;

     ev = SOM_CreatelocalEnVJronment();    //create and initialize an Environment structure
     psm =new SOMPPersistentStorageMgr();  // initialize Persistent Storage Manager
     ...
     SOM_DestroylocalEnvironment(ev);      //Free Environment structure

 }

The Persistent ID

In order for a persistent object to be saved or restored, it must be assigned an ID. The ID you assign to a persistent object tells the Framework how and where to store the object. The persistent ID is an object with a string val ue. The string has the following format.

<IOGroupMgrClassNarne>:<IOGroupName>:<GroupOffset>

The first part of the string identifies what data store the object will be stored in. The second part of the string is a name that is understandable to the data store specified in the first part. The third part is an offset that identifies the object within a group of objects. An example of a persistent ID string is given below:

SOMPAscii: \\sample\\test.dat:O

The first part of the string "SOMPAscii" identifies that the object is to be stored in a file using ASCII format. The second part, "\ \ sample\\ test. dat", is a file name that indicates the file in which the object will be stored. The third part of the string, "O", is a number that identifies the object within the file where it is stored.

The PSOM Framework provides two 110 Group Manager classes. You can either use the SOMPAscii 110 Group Manager to store data in a ASCII format, or you can use the SOMPBinary 110 Group Manager to store data in a binary format. You can choose which format by setting the first part of the persistent ID string accordingly. The following persistent ID indicates the object that is assigned to it will be stored using binary format.

SOMPBinary:\\sarnple\\test.dat:O

The PSOM Framework is available on both AIX and 08/2. The notation for specifying the file name is different on the two systems. The file name that is s p ecified above uses the 08/2 notation. If the same string ID is to be created on AIX, the slashes need to be modified to the following.

SOMPAscii:/sample/test.dat:O

Assigning a Persistent ID to a Persistent Object

Typically, a client will create a persistent ID, initialize its string ID, and assign it to the object. The SOMPPersistentld class is responsible for creating the persistent ID and provides methods to initialize the string value in the persistent ID. The SOMPPersistentObject class provides methods to assign a persistent ID to a persistent object. Since all persistent objects must be derived from SOMPPersistentObject, it follows that every persistent object supports the methods for setting its persistent ID.

The SOMPPersistentld class provides the method somutSetid String for setting the string value for a persistent ID. The following code segment shows how to create a persistent ID and assigns the string "SOMPAscii:\ \sample\ \test.dat:O" to it:

SOMPPersistentld *pid;

pid = new SOMPPersistentld();
pid->somutSetldString( ev, "SOM PAscii :\ \sample\\test.dat:O");

The SOMPPersistentObject class provides three methods for assigning a persistent ID to a persistent object. You can assign a persistent object to a specific ID, to a system-gener ated ID, or to an ID that is near some other specified object. The three methods are s ompinitGiv enld, s ompinitNextAvail, and somplnitNearObject. The choice depends on how much control the client needs over the storage of the object. The client-assigned ID provides the most control while the system-generated ID might be more convenient in other cases.


The somplnitGlvenld Method

The sompinitGive nld meth od assigns a persistent object to a specific persistent ID. The syntax for the method in C is given below:

 _sompInitGivenId(persistentObject,     // pointer to persistent object
                  env,                  // pointer to persistent ID object
                  pid);                 // pointer to persistent ID object

The parameter persistentObject is a pointer to the persistent object to which the specified persistent ID is to be assigned. The parameterpid is a pointer to a persistent ID object.

Below is bow you would use the somplnitGivenid method to assign a persistent ID. The class Document is derived from the SOMPPersistentObject class.

Document *doc;
SOMPPersistentld •pid ;

pid =new SOMPPersistentId() ;
pid->somutSetIdString(ev, "SOMPAscii:\\sample\\doc .dat :O");

doc = new Document() ;
doc ->sompInitGiven Id(ev,pid);

The object doc is assigned the persistent ID whose value is "SOMPAscii:\\sample\doc.dat:O". This means that if a store operation is invoked on the doc object, it will be stored in the ASCII file "\sample\ doc.dat".

The somplnitNextAvoll Method

The somplnitNextAvail method assigns a system-generated ID to a persistent object. The ID must be generated using the SOMPldAssigner class. The SOMPIdAssignerClass implements a method sompGetSystemAssignedld, which generates an ID, using a simple algorithim based on a path name and a file name. If the environment variable SOMP_PERSIST is set, it will be used as the path name. Otherwise, it will default to the current directory. The file name is the string "p" concatenated with a seven digit hex number. The number is read from a file called "somplast.id" which is updated everytime with the last generated ID. The offset portion of the persistent ID is always set to 0. You can change the default algorithm by subclassing from SOMPldAssigner and override sompGetSystem. Assignedld.

The syntax for the somplnitNextAvail method is given below:

_sompInitNextAvail(persistentObject,    //pointer to persistent object
                   env,                 //pointer to Environment structure
                   genPid) ;            //pointer to the next available PIO object

The parameter persistentObject is a pointer to the persistent object to which the specified persistent ID is to be assigned. The parameter genPid is a pointer to an object of class SOMPidAssigner, which represents the next available persistent ID.

Here is how you would use the sompInitNextAvail method to assign a persistent ID to the above Document class:

 Document *doc;
 SOMPIdAssigner *pid;  
 
 pid =new SOMPldAssigner(); 
 
 doc = new Document();
 doc->somplnitNextAvail( ev,pid);

Assuming the environment variable SOMP PERSIST is not set and the file "somplast.id" does not exist yet, the ID that is generated above would be:

SOMPAscii:.\\pOOOOOOO:O

And the file "somplast.id" is created in the current directory with the following entry:

0000001

The somplnitNearObject Method

The somplnitNearObject method gives a specified persistent object a persistent ID that is nearby the ID of another specified persistent object. This method is useful when you have composite objects you want to store near to the root object. You can initalize your parent object using either of the above methods and then use somplnitNearObject to initialize the children objects. The syntax for the method in C is given below:

 _somplnitNearObject(persistentObject,   // pointer to persistent object
                     env,                // pointer to Environment structure
                     nearObj);           // pointer to nearby persistent object

The parameter persistentObject is a pointer to the persistent object to which a persistent ID is to be assigned. The parameter, nearObj,is a pointer to another persistent object with a persistent ID.

The following shows how to use sompInitNearObject to set the persistent ID for the doc2 object.

Document            *doc1, *doc2;
SOMP PersistentId   *pid;
 
pid = new SOMPPersistentId();
pid->somutSetIdString(ev, "SOMPAscii:\\sample\\doc.dat:O");
doc1 =new Document():
doc2 =new Document();
doc1->sompInitGivenld(ev,pid);
doc2->sompInitNear0bject(ev, doc1 );     //set doc2 persistent ID to be near doc1

The sompStoreObjectWithoutChildren method stores a persistent object but does not store any of the persistent objects to which it points. It has the same signature as sompStoreObject.