3D PLM PPR Hub Open Gateway |
Feature Modeler |
Extension Features Migration
|
Technical Article |
AbstractThis 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].
First we will review the mechanism offered with old extension and highlight the weakness of this mechanism:
[Top]
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]
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.
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.
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.
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]
Model migration need to be analysed on two sides:
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.
This migration has two main difficulties:
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]
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]
[1] | Feature Modeler Conceptual Overview |
[2] | How to Add Data to a Feature |
[3] | Creating Feature Extensions |
[4] | Working with Feature Extensions |
[Top] |
Version: 1 [Fev 2005] | Document created |
Version: 2 [Nov 2005] | Clarifications about data legacy |
[Top] |
Copyright © 2005, Dassault Systèmes. All rights reserved.