3D PLM PPR Hub Open Gateway

Feature Modeler

Extension Features Migration

How to migrate extension features to the new pattern

Technical Article


Abstract

This article deals with how to migrate extension feature to the new more robust APIs.



To take advantage of this article you need to be familiar with the feature modeler and the extension feature concept. You can see article CAAOsmOverview [1] for the Feature Modeler overview and article CAAOsmHowToAddDataToAFeature [2] for the extension features with in addition the use cases CAAOsmCreateExtensions [3] and CAAOsmManageExtensions [4].

Why the migration is needed

First we will review the mechanism offered with old extension and highlight the weakness of this mechanism:

  1. Activation deactivation, this concept allows the user to switch "ON/OFF" data ans behaviors extensions on a base feature.
  2. Overload, those data are added using "Feature Modeler" APIs. They are integrated in "Feature Modeler" basic mechanisms. They usually are part of the data model and have their own semantic.

[Top]

Activation deactivation concept

The extension mechanism is based on applicative containers: within the working document, an extension is activated on a base feature in an applicative container. Activating an extension means that the base feature now has access to the extension's data and behaviors as to its own.  All of the extensions of a given applicative container can be activated or deactivated at once. Several extensions from different applicative containers can also be active at the same time.
Here we see that the activation deactivation concept may lead to hasardous behaviors depending on weither your extension is active or not.

It is important to note that the notion of active extensions is not persistent: when a document is opened, none of its previously active extensions is still current. In other words, it is necessary each time to specifically activate the necessary extension(s) in order for the base feature to be correctly extended in the given applicative context.
If you add an extension to a base feature you want it to be active by default. Here you need to find a way to activate your extensions as they are not active by default. It can lead to complex initialisation phases or the use a dedicated command to activate extensions.

Morover, basic operations such as Delete or Copy can corrupt the model if the extensions are not correctly activated.

[Top]

Overload

Adding an extension feature that implements an interface not implemented by the base feature will simulate the fact the base feature implements the interface. With a QueryInterface on the base feature you can retrieve a pointer on the extension feature implementation.
Adding an extension feature allow the base feature to access to attributes defined on the extension feature as they were defined on the base feature.
The interface CATISpecAttrAccess can retrieve the attributes defined on an active extension feature.
You can find next some examples to illustrate the potential issues.

[Top]

QueryInterface overload

AppA is implementing CATIxxx on its FeatExt_A.
AppB decides to implement CATIxxx on its FeatExt_B.
Murphy’s law makes the Base Feature having both extensions.
QueryInterface is no longer safe on those features.
Depending on the activation deactivation of extension feature the retrieved implmentation will change.



AppB is implementing CATIxxx on its FeatExt.
AppA decides to implement CATIxxx.
QueryInterface is no longer safe on those features.


[Top]

Attributes overload

AppB has an attribute dynamicTypeAttr on its FeatExt.
AppA decides to add an attribute dynamicTypeAttr on its Base Feature A.
GetAttribute is no longer safe on those features.



AppA and AppB have an attribute dynamicTypeAttr on their FeatExt
If the Base Feature is having both extensions
GetAttribute is no longer safe on those features:
Which value do I return ?
If those two attributes have different types, Set and Get operations have random results.



As implementation of an extension is completely independent of the base feature it can extends, it is impossible to control the behaviors with code review.

[Top]

What's new

To simplify activations mechanisms during open and avoid activation deactivation issues this concept is removed for the new extension feature. The new extension features are loaded at the same time as their base features.
This will make simpler the initialisation phases and protect the data against data corruption.
With new extension feature it's like all the extensions are activated by default.

Attribute and interface overload is removed from the new extension feature. The overload is no longer implicit, you need to access to your extension's attribute or interface's attribute explicitly from your extension.

New extensions' memory consumption is twice smaller.

[Top]

How to migrate

Model migration need to be analysed on two sides:

  1. Data, impacted data are data generated with former extensions (CATPart, CATProduct, CATDrawing, ...) and extension catalogs (CATFct).
  2. Code, all the code managing extensions.

Data legacy and extensions catalog

Data legacy as feature catalogs(.CATfct) are not impacted by the new APIs. In other words former extension features can be manipulated with new APIs.
But new extension features can only be created and manipulated with the new APIs.

Never re-create your extension feature catalog but use the new API to create new extension.

[Top]

Code migration

This migration has two main difficulties:

  1. QueryInterface overload
  2. The Activation code

QueryInterface overload is not supported by new extension feature. This means that you have to check all QueryInterface on interfaces implemented on the extension features and replace them with CATIOsmExtendable::QueryExtension if they are called on the base feature. You also have to check all QueryInterface on interfaces implemented on the base features. If the QueryInterface is called on the extension feature then insert a CATIOsmExtension::QueryBaseObject to call the QueryInterface on the base feature.

The activation/deactivation mechanism is mixed with the creation/removal of extension feature.
You need to identify and separate the creation/removal code from the activation/deactivation code. The creation/removal code can be easily migrated with the new APIs.
With new extension feature it's like all the extensions are activated by default. As this behavior is not available with former extension features, they still need to be "manually" activated. So if you have to manage documents containing former extension features you need to keep the activation code. Then to stick with the new extension feature behavior you have to drop the deactivation code.

The code migration can be done in three phases:

First, you need to replace the include files.

CATExtensionFactory.h
CATIOsmExtensionFactory.h
CATIExtension.h CATIOsmExtension.h
CATIExtendable.h CATIOsmExtendable.h
CATExtensionServices.h CATOsmExtensionServices.h

Then proceed the methods migration except the CATIExtendable::ActivateExtension in CATIOsmExtendable::AddExtension migration.

Second, you need to check all QueryInterface on interfaces implemented on the extension features and replace them with CATIOsmExtendable::QueryExtension if they are called on the base feature.
In the same spirit, all access to extension features attributes with CATISpecAttrAccess must be reviewed to check that they are made on the extension feature and not the base feature.

From this point first tests can be made to check the behavior of using the new APIs with former extension features.

Last, complete the migration by replacing CATIExtendable::ActivateExtension with CATIOsmExtendable::AddExtension.

Only if you have former extension in production:
If you already have some documents in production that contain former extension features to support those document you need to keep the activation code using CATOsmExtensionServices::CATActivateExtensions.

[Top]



Summary of Essential Tasks

Former Method on CATExtensionServices:
New Method on CATOsmExtensionServices: Comment:
CATActivateExtensions CATActivateExtensions Use only if you have to manage existing documents containing former extension features.
CATDeactivateExtensions none We don't recommend the use of activation/deactivation mechanism.
CATListUserExtensionsFromCatalog CATOsmListUserExtensionsFromCatalog Unchanged.
CATMakeExtensionLocal none This can be defined directly in the ressource file.
Former Method on CATIExtensionFactory: New Method on CATIOsmExtensionFactory:
CreateExtension CreateExtension Unchanged.
Former Method on CATIExtension: New Method on CATIOsmExtension:
GetID GetID New method returns HRESULT.
IsActive none We recommend that you activate all extensions as soon as you use them.
QueryBaseObject QueryBaseObject Unchanged.
QueryExtensionRepresentative none The use of representative is useless.
Former Method on CATIExtendable: New Method on CATIOsmExtendable:
ActivateExtension (Creation mode) AddExtension Add a new extension to a base feature.
ActivateExtension (Activation mode)
none
To merge former extension concepts with the new pattern it is recommended to activate all extension features with CATOsmExtensionServices::CATActivateExtensions
and avoid the usage of activation deactivation mechanisms
ReactivateExtension none See ActivateExtension.
DeactivateExtension (Remove mode)
RemoveExtension Remove extension from a base feature.
DeactivateExtension (Deactvation mode)
none See ActivateExtension.
IsExtensionActive none See ActivateExtension.
QueryAllExtensions QueryAllExtensions or QueryApplicativeExtension
Small changes.

[Top]


References

[1] Feature Modeler Conceptual Overview
[2] How to Add Data to a Feature
[3] Creating Feature Extensions
[4] Working with Feature Extensions
[Top]

History

Version: 1 [Fev 2005] Document created
Version: 2 [Nov 2005] Clarifications about data legacy


[Top]

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