3D PLM Enterprise Architecture

Data Access - Database

Working with Objects and their Attributes

Performing basic operations on a new object and its attributes
Use Case

Abstract

This article shows how to use interfaces in the VPMXBom framework to create and work with a new data base object and its attributes.


What You Will Learn With This Use Case

This use case is intended to show you how to use some of the basic operations available with VPMXBom interfaces. These include: creating a new login session, retrieving a list of available modelers, creating a new object in one of the modelers, retrieving and valuating the attributes of this new object and finally, saving the new object in the data base.

[Top]

The CAAVxbGeneralXBom Use Case

CAAVxbGeneralXBom is a use case of the CAAVPMXBom.edu framework that illustrates VPMXBom framework capabilities.

[Top]

What Does CAAVxbGeneralXBom Do?

CAAVxbGeneralXBom first of all creates a new login session in the current application. Then it retrieves a list of all the available modelers and creates a new object of type "ENOVIA_Part" in the "INDEX" modeler. It then retrieves a list of all the attributes of this object and proceeds, for each, to valuate it, to validate the valuation, to retrieve its definition, and print out its name. Finally, the object is saved in the data base and the session is closed.

[Top]

How to Launch CAAVxbGeneralXBom

To launch CAAVxbGeneralXBom, you will need to set up the build time environment, then compile CAAVxbGeneralXBom along with its prerequisites, set up the run time environment, and then execute the use case. [1] The required interfaces can be found in the VPMXBom and VPMPersistency frameworks. Launch the use case by executing the following command:

mkrun -c "CAAVxbGeneralXBom"

[Top]

Where to Find the CAAVxbGeneralXBom Code

The CAAVxbGeneralXBom use case is made of a single file located in the CAAVxbGeneralXBom.m module of the CAAVPMXBom.edu framework:

Windows InstallRootDirectory\CAAVPMXBom.edu\CAAVxbGeneralXBom.m\
Unix InstallRootDirectory/CAAVPMXBom.edu/CAAVxbGeneralXBom.m/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

Before launching this use case, check for its prerequisites.

For demonstration purposes, the code from the CAAVxbGeneralXBom use case is shown here. There are nine logical steps in the CAAVxbGeneralXBom use case:

  1. Creating a Login Session
  2. Retrieving a List of Available Modelers
  3. Retrieving a Specific Modeler from the List
  4. Creating a New ENOVIA Object
  5. Retrieving the Object's Attributes
  6. Valuating the Object's Attributes
  7. Retrieving the Attribute's Definition Object
  8. Saving the Login Session in the Data Base
  9. Closing the Session

[Top]

Creating a Login Session

1. Retrieve the current ENOVIA application.

cout << "Create an ENOVIA Application" << endl;
ENOVIApplication * piApplication = NULL;
HRESULT rc = ::ENOVGetApplication (&piApplication);
if (FAILED(rc) || NULL == piApplication)
{
   cout << "Failed to retrieve ENOVIA application." << endl;
   return 1;
}
cout << "ENOVIA application retrieved successfully" << endl;  

...        

The first step in working with the XBom is retrieving an ENOVIA application. Use the ENOVGetApplication global function which returns an ENOVIApplication pointer. The ENOVIA application supports a secured multi-user mode. The interface may be shared by different users and is used to gain access to a login session.

[Top]

2. Create a new login session.

...
cout << "Create a login session" << endl;
const int networkCommunication = 1;
ENOVILoginSession *piLoginSession = NULL;
rc = piApplication -> login("MySelf",
                            "MyEncodedPsswd",
		       	    "MyRole",
		            networkCommunication,
			    &piLoginSession);

piApplication -> Release();
piApplication = NULL;

if(FAILED(rc) || NULL == piLoginSession)
{
    cout << "Failed to create Login session." << endl;
    return 2;
}
cout << "Login session creation successful" << endl;  	
...    

In order to create a new login session, use the login method of ENOVIApplication. This method is used to get the login session corersponding to a specific user or to create one if none exists. The input arguments are:

The method returns an ENOVILoginSession pointer to the login session. This is the entry point for all user dependant actions: once a pointer to this interface has been obtained, it is assumed that the user has been authenticated and that the implementation of the interface keeps track of the user's permissions.

Note that the ENOVIApplication pointer is now released as it will no longer be used.

[Top]

Retrieving a List of Available Modelers

...
cout << "Retrieve the list of modelers" << endl;
ENOVIModelers *piModelerList = NULL;
rc = piLoginSession -> get_Modelers (&piModelerList);
if (FAILED(rc) || NULL == piModelerList)
{
    cout << "Failed to retrieve the list of modelers." << endl;
    piLoginSession -> Release();
    piLoginSession = NULL;
    VPMSession::CloseSession();
    return 3;
}
cout << "List of modelers retrieved OK" << endl;
... 

Using the ENOVILoginSession pointer retrieved previously, retrieve the list of available modelers. The role of a modeler is to manage a set of persistent object types. It is sometimes referred to as a "domain". The get_Modelers method returns a pointer to the ENOVIModelers interface. This interface has a double role:

In short, if a modeler which is accessed by name has not been accessed before, it will be instantiated, but only the previously accessed (and, therefore, instantiated) modeler can be accessed by index.

[Top]

Retrieving a Specific Modeler from the List

...
cout << "Retrieve INDEX modeler" << endl;
ENOVIModeler *piModeler = NULL;
rc = piModelerList -> Item ("INDEX",
                            &piModeler);

piModelerList -> Release();
piModelerList = NULL;

if (FAILED(rc) || NULL == piModeler)
{
    cout << "Failed to retrieve the INDEX modeler." << endl;
    piLoginSession -> Release();
    piLoginSession = NULL;
    VPMSession::CloseSession();
    return 4;
}
cout << "INDEX modeler retrieved OK" << endl;
... 

The "INDEX" modeler is retrieved from the list of modelers by specifying its name in the Item method of the ENOVIModelers interface. As explained above, the modeler is thus instantiated and could later be accessed by index. Note that the ENOVIModelers pointer is now released since it will no longer be needed.

[Top]

Creating a New ENOVIA Object

...
cout << "Create a new ENOVIA object" << endl;
CATUnicodeString type ("ENOVIA_Part");
ENOVIObject *piObject = NULL;
rc = piModeler -> CreateObject (&type,
                                &piObject);

piModeler -> Release();
piModeler = NULL;

if (FAILED(rc) || NULL == piObject)
{
    cout << "Failed to create a new ENOVIA object." << endl;
    piLoginSession -> Release();
    piLoginSession = NULL;
    VPMSession::CloseSession();
    return 5;
}
cout << "ENOVIA object created OK" << endl;
...

In order to create a new instance of one of the object types managed by this modeler, use the CreateObject method of the ENOVIModeler interface. The list of types which can be passed in the first parameter can be retrieved using the get_ListOfObjectTypeNames method of the same interface. In this case, a new "ENOVIA_Part" object is created in the "INDEX" modeler. The CreateObject method takes the type of object to be created as input and returns an ENOVIObject pointer to the newly-created object. Note that the ENOVIModeler pointer is now released as it will no longer be used.

[Top]

Retrieving the Object's Attributes

1. Retrieve a list of the object's attributes.

...    
cout << "Get attributes" << endl;
ENOVIAttributeValues * piAttrList = NULL;
rc = piObject -> get_Attributes(&piAttrList);

piObject -> Release();
piObject = NULL;

if (FAILED(rc) || NULL == piAttrList)
{
    cout << "Failed to get Attributes" << endl;
    piLoginSession -> Release();
    piLoginSession = NULL;
    VPMSession::CloseSession();
    return 6;
}
cout << "Attributes retrieved: OK" << endl;
...		

A list of the object's attributes is retrieved using the get_Attributes method of the ENOVIBase interface, from which ENOVIObject derives. This method retrieves an ENOVIAttributeValues pointer to the list of attributes. Note that the ENOVIObject pointer is now released as it will no longer be needed.

[Top]

2. Get the number of attributes belonging to the object.

...
long nbAttr;
cout << "Get the number of attributes" << endl;
ret = piAttrList -> get_Count(&nbAttr);
if (ret != S_OK)
{
    cout << "Failed to get count of Attributes" << endl;
    piLoginSession -> Release();
    piLoginSession = NULL;
    piAttrList -> Release();
    piAttrList = NULL;
    VPMSession::CloseSession();
    return 7;
}	
cout << "Number of Attributes = "<< nbAttr << endl;
...

Using the ENOVIAttributeValues pointer, execute the get_Count method of the ENOVIBase interface from which ENOVIAttributeValues derives, to find out how many attributes are defined for the given object type. The output comment reads:

Number of Attributes = 3

[Top]

3. Retrieve each attribute from the list.

...
CORBAAny putData, getData;
ENOVIAttributeValue * piAttribute = NULL;
for (long iAttr = 1; iAttr <= nbAttr; iAttr++)
{
   // Get the Attribute
   rc = piAttrList -> Item(iAttr,
	                   &piAttribute);

   if (rc != S_OK)
   {
      cout << "Failed to get attribute for Index " << iAttr << " Attribute" << endl;
      piLoginSession -> Release();
      piLoginSession = NULL;
      piAttrList -> Release();
      piAttrList = NULL;
      VPMSession::CloseSession();
      return 8;
    }
    else 
      cout << "Attribute for Index " << iAttr << ": OK" << endl;
    ...

Retrieve the attribute corresponding to the current index from the list of attributes using the Item method of ENOVIAttributeValues. This method returns an ENOVIAttributeValue pointer to the attribute corresponding to the inputted index value.

[Top]

Valuating the Object's Attributes

1. Set a new attribute value.

    ...
    putData << "Howdy";
    cout << "Put data value in an attribute" << endl;
    rc = piAttribute -> put_Data(&putData); 
    if (FAILED(rc))
    {
	cout << "put_Data for attribute at Index " << iAttr << " failed " << endl;
        piLoginSession -> Release();
	piLoginSession = NULL;
	piAttrList -> Release();
	piAttrList = NULL;
	piAttribute -> Release();
	piAttribute = NULL;
	VPMSession::CloseSession();
	return 9;
    }
    cout << "put_Data for attribute at Index " << iAttr << " : OK" << endl;
    ...

Set a new value to an attribute by using the put_Data method of ENOVIAttributeValue.

[Top]

2. Retrieve the attribute value.

    ...
    cout << "Get data value from an attribute" << endl;
    rc = piAttribute -> get_Data(&getData); 
    if (FAILED(rc))
    {
        cout << "get_Data for attribute at Index " << iAttr << " failed" << endl;
        piLoginSession -> Release();
	piLoginSession = NULL; 
        piAttrList -> Release();
	piAttrList = NULL;
	piAttribute -> Release();
	piAttribute = NULL;
	VPMSession::CloseSession();
	return 10;
    }
    cout << "Index " << iAttr << " Attribute get_Data OK" << endl;
    if (putData != getData) cout << "Attribute values not equal KO" << endl;
    else cout << "Attribute values are equal OK" << endl;
		
    ...   

Retrieve the value of an attribute by using the get_Data method of ENOVIAttributeValue. Compare it to the value just set on the same attribute to confirm that the attribute has been correctly valuated.

[Top]

Retrieving the Attribute's Definition Object

1. Retrieve the attribute's definition object.

    ...
    ENOVIAttributeDefinition * piAttrDef = NULL;
    cout << "Get definition for an attribute" << endl;
    rc = piAttribute -> get_Definition(&piAttrDef); 
    if (FAILED(rc) || NULL == piAttrDef)
    {
	cout << "get_Definition for attribute at Index " << iAttr << " failed" << endl;
        piLoginSession -> Release();
	piLoginSession = NULL; 
	piAttrList -> Release();
	piAttrList = NULL;
	piAttribute -> Release();
	piAttribute = NULL;
	VPMSession::CloseSession();
	return 11;
    }
    cout << "get_Definition for attribute at Index " << iAttr << " : OK" << endl;
		
    ...

Use the get_Definition method of ENOVIAttributeValue to retrieve the attribute's definition object. This method returns an ENOVIAttributeDefinition pointer. This pointer can be used to set or retrieve various information concerning the attribute: its name, its type, its mandatory or unique flags, its authorized values, its default value, etc.

[Top]

2. Retrieve the attribute's name from its definition object.

    ...
    CATUnicodeString attributeName("");
    rc = piAttrDef -> get_AttributeName (&attributeName);
    if (FAILED(rc))
    {
	cout << "get_AttributeName for attribute at Index " << iAttr << " failed" << endl;
    }
    cout << "get_AttributeName for attribute at Index " << iAttr << " = " << attributeName.CastToCharPtr() << endl;

    piAttrDef -> Release();
    piAttrDef = NULL;
    piAttribute -> Release();
    piAttribute = NULL;
	
} // end for each Attribute	

piAttrList -> Release();
piAttrList = NULL;
	
...

The attribute's name is retrieved using the get_AttributeName method of the ENOVIAttributeDefinition interface. The output comment reads, for each attribute in turn:

get_AttributeName for attribute at Index 1 = id
get_AttributeName for attribute at Index 2 = name
get_AttributeName for attribute at Index 3 = description

Note that the ENOVIAttributeDefinition pointer, piAttrDef, and the ENOVIAttributeValue pointer, piAttribute, are released for each attribute. After exiting the loop, the ENOVIAttributeValues pointer, piAttrList, retrieved from the get_Attributes method, is also released, as it will no longer be used.

[Top]

Saving the Login Session in the Data Base

...   
cout << "Save new object in DataBase" << endl;
rc = piLoginSession -> Save();
if (FAILED(rc))
{
    cout << "Save: KO" << endl;
    VPMSession::CloseSession();
    return 13;
}
cout << "Save OK" << endl;

piLoginSession -> Release();
piLoginSession = NULL;
...

Save the login session including the new object created by executing the Save method of the ENOVILoginSession interface. Also do not forget to release the ENOVILoginSession pointer.

[Top]

Closing the Session

...  
cout << "CloseSession" << endl;
rc = VPMSession::CloseSession();
if (FAILED(rc))
{
    cout << " Close Session failed.  " << endl;
    return 14;
}
cout << "Close Session successful. " << endl;
 	
return 0;

Close the session using the CloseSession method of VPMSession. Then return a 0 value for a successful completion.

[Top]


In Short

This use case has illustrated how create a new ENOVIA object in a login session and how to retrieve and valuate the attributes of the new object. Initially, the login session is created using ENOVGetApplication::login. A list of available modelers is returned using the ENOVILoginSession::get_Modelers method. Then, a specific modeler is instantiated using the ENOVIModelers::Item method. The new ENOVIA object is created using the ENOVIModeler::CreateObject method. Using the ENOVIObject pointer which derives from ENOVIBase, execute the get_Attributes method to retrieve a list of the object's attributes. Using the ENOVIAttributeValues::Item method, retrieve an ENOVIAttributeValue pointer to each attribute. Perform the put_Data and get_Data methods of this interface in order to valuate and validate each attribute. Finally, retrieve an ENOVIAttributeDefinition pointer using the ENOVIAttributeValue::get_Definition method in order to access various attribute characteristics. Use the Save method of the ENOVILoginSession interface to save the new object in the data base.

[Top]


References

[1] Building and Launching a CAA V5 Use Case
[Top]

History

Version: 1 [May 2001] Document created
[Top]

Copyright © 2001, Dassault Systèmes. All rights reserved.