摘要
本文讨论了CAAFmExtExtensionManagement用例。它主要处理扩展特征的相关操作。这些扩展特征是在《定义扩展特征》1中定义的。
理解本用例的先决条件是理解扩展特征的概念2。
您将通过本用例学习什么
本用例教授用户如何操作扩展特征。主要学习内容如下:
- 为基本特征添加、检索和删除扩展特征。
- 从任意扩展特征检索其基本特征。
- 理解管理扩展方法所需的最少凭据3。
CAAFmExtExtensionManagement 用例
CAAFmExtExtensionManagement 是 CAAFeatureModelerExt.edu 框架中的一个用例,用于展示 FeatureModelerExt 框架的能力。
CAAFmExtExtensionManagement 的功能
该用例首先创建一个 PLM 技术表达,并带有一个名为 CAAFmExtBaseFeatureCont的应用容器4。接着它实例化CAAOsmNovel的启动项。这个新实例(后续称为Novel或基本特征)就创建在这个新的容器CAAFmExtBaseFeatureCont中。
CAAOsmNovel启动项定义在CAAOsmCatalogSU特征目录里,该目录由用例5运行时生成。下面的图1 描绘了该启动项及其关联的属性。
图1: CAAOsmNovel基本特征
在创建 Novel 之后,我们开始为其添加扩展。
首先我们为其添加CAAOsmHistoricalNovel扩展。
这个扩展特征在CAAOsmExt1Catalog目录中定义1。下面的图2描绘了CAAOsmHistoricalNovel启动项。它有一个类型为字符串,默认值为Middle Ages的属性Epoch。
图2: CAAOsmHistoricalNovel特征
这个新扩展会自动实例化到应用容器中,该容器的名称CAAFmExtApplication1由扩展特征的资源文件定义1。
然后我们为Novel添加CAAOsmBiographicalNovel扩展。
这个派生自CAAOsmHistoricalNovel的扩展特征同样定义在CAAOsmExt1Catalog目录中。图 3 描绘了CAAOsmBiographicalNovel启动项。它有一个类型为字符串、默认值为Music的属性Domain。此外它还从其父特征(CAAOsmHistoricalNovel)继承了字符串类型的属性 Epoch。
图3: CAAOsmBiographicalNovel特征
这个新扩展同样会根据其资源文件的定义1,自动实例化到应用容器CAAFmExtApplication1中。
最后第三个扩展CAAOsmChildrensNovel被添加到Novel特征。
这个扩展特征在CAAOsmExt2Catalog特征目录中定义1。图 4 描绘了CAAOsmChildrensNovel启动项。它有一个类型为整数、默认值为 12 的属性AgeGroup。
图4: CAAOsmChildrensNovel特征
这个新扩展会自动实例化到应用容器中,该容器的名称 CAAFmExtApplication2由扩展特征的资源文件定义1。
上面的图 5 概括地展示了本用例的最终输出。
图 5:用例输出概览
数据创建完成后,我们使用不同的检索方法进行测试:
- 检索 CAAOsmChildrensNovel 扩展,并使用特征外观(
CATFmFeatureFacade)显示其AgeGroup属性的值。 - 检索 CAAOsmBiographicalNovel扩展,并使用由该扩展实现的接口显示其Epoch和Domain属性的值。
- 从CAAOsmChildrensNovel和CAAOsmBiographicalNovel中检索基本特征(Novel),您将看到根据凭据的不同,您可能获得也可能无法获得基本特征。
接下来用例会扫描应用容器"CAAFmExtApplication1"中由Novel扩展特征的特征。它输出了两个扩展特征(类型为CAAOsmHistoricalNovel和CAAOsmBiographicalNovel)。随后它移除了这两个扩展特征。因此最终在三个扩展特征实例中,我们只剩下一个。
最后它在所有应用容器中扫描由Novel扩展特征的特征。计数输出为1,因为我们只在应用容器CAAFmExtApplication2中有一个CAAOsmChildrensNovel扩展特征实例。
如何启动 CAAFmExtExtensionManagement
要启动CAAFmExtExtensionManagement您需要设置构建时环境,然后编译CAAFmExtExtensionManagement及其先决条件,设置运行时环境,最后执行该用例。这在参考文献6中有详细描述。启动用例时执行以下命令:
mkrun -c "CAAFmExtExtensionManagement Repository Server LoginTicket Environment"其中:
| 仓库 | PLM1 |
| 服务器 | 服务器地址,格式为Host:Port_number/RootURI |
| 登陆票据 | 表示登录票据的字符串 |
| 环境 | 一个包含 PLMProductDS(一个 PRODUCT 的自定义)的 PLM 环境 |
注意:目录(CAAOsmCatalogSU, CAAOsmExt1Catalog, CAAOsmExt2Catalog)必须在运行时目录下找到:当前工作空间 + os_directory + resources + graphic 目录。为了让目录能从运行时目录访问,它应位于CAAFeatureModelerExt.edu框架的CNext + resources + graphic 目录下,这样在更新运行时视图(mkrtv)时目录将自动移动到运行时目录。
在哪里可以找到 CAAFmExtExtensionManagement 代码
主要的CAAFmExtExtensionManagement代码位于CAAFeatureModelerExt.edu框架的CAAFmExtModeler.m、CAAFmExtExtensionDefinition.m和CAAFmExtExtensionManagement.m模块中。这些模块位于:
InstallRootFolder\CAAFmExtensionManagement.m其中InstallRootFolder6是您 API 安装的根文件夹。
CAAFmExtExtensionManagement.m模块主要包括以下两个文件,它们构成了用例的主体:
- CAAFmExtManageExtensionMain.cpp: 包含主程序。
- CAAFmExtManageExtensionUse.cpp: 包含全局程序CAAFmExtManageExtensions。它包含了所有与扩展特征相关的调用。主程序调用此程序。
CAAFmExtModeler.m模块包含CAAOsmNovel晚期类型(指接口在运行时才确定类型,属于晚期绑定)上CAAIFmExtNovel接口的实现,位于CAAEFmExtNovel.cpp中。
CAAFmExtensionDefinition.m模块包含CAAOsmBiographicalNovel晚期类型上CAAIFmExtBiogNovel接口的实现,位于CAAEFmExtBiogNovel.cpp中。
分步指南
CAAFmExtExtensionManagement包含十个逻辑步骤:
- 序幕
- 创建凭据对象
- 创建基本特征
- 为基本特征实例化扩展特征
- 检索扩展并通过特征外观使用它
- 检索扩展并通过接口使用它
- 从扩展特征检索基本特征
- 在应用容器内扫描基本特征的扩展特征
- 移除扩展特征
- 在任何应用容器中扫描基本特征的扩展特征
- 尾声
序幕
连接到输入仓库并创建批处理会话的基本步骤在文章《连接到 V6 服务器》7中有详细说明。该用例创建一个新的 PLM 技术表达——这是在用例8中讨论的主题——并带有一个应用容器9。这个容器通过一个CATFmContainerFacade实例类 MyContFacade 来处理。这个外观(外观模式是一种经典的设计模式,用于给复杂子系统提供简单的访问入口)是使用下面详述的凭据创建的。
创建凭据对象
要实例化一个特征,客户端应拥有定义该特征的目录。实例化的特征包括:
- CAAOsmNovel(基本特征),定义在CAAOsmCatalogSU目录中。
- CAAOsmHistoricalNovel和CAAOsmBiographicalNovel,这两个扩展特征定义在CAAOsmExt1Catalog中,其客户端 ID 是CAAOsmClientId1。
- CAAOsmChildrensNovel,一个扩展特征,定义在CAAOsmExt2Catalog目录中,其客户端 ID 是CAAOsmClientId2。
创建了一个唯一的凭据对象MyCredentials,它是CATFmCredentials类的一个实例,以满足用例的所有需求。
CATFmCredentials MyCredentials;...接着,声明我们是一个基于特征建模器基础设施的应用程序:
rc=MyCredentials.RegisterAsApplicationBasedOn(CATFmFeatureModelerID,"CAAFmExtFeatureModeler")最后,声明我们是不同目录的所有者:
CATUnicodeStringclientId("CAAOsmClientId");CATUnicodeStringiCatalogName("CAAOsmCatalogSU");MyCredentials.RegisterAsCatalogOwner(iCatalogName,clientId);...CATUnicodeStringclientId1("CAAOsmClientId1");CATUnicodeStringiCatalogName1("CAAOsmExt1Catalog");MyCredentials.RegisterAsCatalogOwner(iCatalogName1,clientId1);...CATUnicodeStringclientId2("CAAOsmClientId2");CATUnicodeStringiCatalogName2("CAAOsmExt2Catalog");MyCredentials.RegisterAsCatalogOwner(iCatalogName2,clientId2);CATFmCredentials类的RegisterAsCatalogOwner方法以追加方式添加客户端凭据,授权客户端访问不同目录中定义的启动项。
通过研究技术文章《理解凭据》3,用户将对凭据有更好的理解。
创建基本特征
CATFmStartUpFacadeMyStartUpFacade(MyCredential,"CAAOsmNovel");CATFmAttributeValue AttrValue;CATFmFeatureFacadeFeatFacadeOnNovelInstBaseFeat(MyCredential);rc=MyStartUpFacade.InstantiateIn(MyContFacade,FeatFacadeOnNovelInstBaseFeat);FeatFacadeOnNovelInstBaseFeat是 Novel 特征的外观,它新近在CAAFmExtBaseFeatureCont容器(由MyContFacade处理)中实例化。注意与新外观关联的凭据:MyCredential,它将允许我们内部访问基本特征,以便添加三个扩展特征。
实例化的步骤在用例《创建特征》10中有详细说明。
实例化扩展特征
我们开始为Novel特征(基本特征)实例化扩展特征。绑定到Novel特征的特征外观是上面刚刚创建的FeatFacadeOnNovelInstBaseFeat。在我们的用例中,与基本特征关联的凭据包含处理基本特征目录和扩展目录的权限。但通常您只拥有扩展目录的凭据。对于任何类型的基本特征,这都足以添加扩展。因此,基本特征的外观必须绑定到一个至少声明您是扩展目录所有者的凭据。
我们从CAAOsmHistoricalNovel扩展开始。
CATStringstrHistoricExtNovel("CAAOsmHistoricalNovel");rc=FeatFacadeOnNovelInstBaseFeat.AddExtension(strHistoricNovel,AttrValue);CATFmFeatureFacadeFeatFacadeOnHistNovelExtn(MyCredential,AttrValue);CATFmFeatureFacade类的AddExtension方法为基本特征实例化一个扩展特征。参数包括:
- strHistoricExtNovel: CATString类型,表示扩展特征的名称。
- FeatFacadeOnHistNovelExtn: 新创建的扩展特征的CATFmFeatureFacade类型。注意此外观没有凭据。它对AddExtension方法的结果没有影响。是基本特征的外观(FeatFacadeOnNovelInstBaseFeat)必须至少包含访问扩展目录的权限。
然后我们对CAAOsmBiographicalNovel扩展做同样的事情。
CATStringstrBiographicalExtNovel("CAAOsmBiographicalNovel");rc=FeatFacadeOnNovelInstBaseFeat.AddExtension(strBiographicalExtNovel,AttrValue);CATFmFeatureFacadeFeatFacadeOnBiogNovelExtn(MyCredential,AttrValue);最后是CAAOsmChildrensNovel扩展:
CATStringstrChildrensExtNovel("CAAOsmChildrensNovel");rc=FeatFacadeOnNovelInstBaseFeat.AddExtension(strChildrensExtNovel,AttrValue);CATFmFeatureFacadeFeatFacadeOnChildrensNovelExtn(MyCredential,AttrValue);在结束此步骤之前,我们应该补充四点:
- 能够添加这三个扩展特征,是因为用于创建FeatFacadeOnNovelInstBaseFeat的凭据包含处理每个扩展特征目录的权限。
- 与任何类型的特征一样,扩展特征也是在应用容器中实例化的。但您无需在代码中提供容器名称,因为特征建模器引擎会从与扩展特征关联的资源文件中检索此信息。包含应用容器的流是从基本特征推导出来的。实际上,基本特征及其扩展必须在同一个流中4。
- 当应用容器不存在时(CAAOsmHistoricalNovel和CAAOsmChildrensNovel就是这种情况),特征建模器会自动创建它。
- 返回的新扩展特征的外观是没有凭据的。这是用例的选择。
检索扩展并通过特征外观使用它
此步骤包括从基本特征中检索扩展(CAAOsmChildrensNovel),以便通过特征外观来操作它。
rc=FeatFacadeOnNovelInstBaseFeat.GetExtension(strChildrensExtNovel,AttrValue);CATFmFeatureFacadeFeatFacadeOnChildrenNovelExt(MyCredential,AttrValue);CATFmFeatureFacade的GetExtension方法返回一个扩展特征。参数包括:
- strChildrensExtNovel:CATString类型,表示扩展特征的名称。
- FeatFacadeOnChildrenNovelExt:CATFmFeatureFacade类型,表示CAAOsmChildrensNovel扩展特征输出之上的外观。
GetExtension成功是因为基本特征的外观FeatFacadeOnNovelInstBaseFeat至少包含处理定义了CAAOsmChildrensNovel启动项的目录的权限。
由于FeatFacadeOnChildrenNovelExt是使用MyCredential作为凭据创建的,因此我们可以内部访问扩展特征(MyCredential包含处理CAAOsmChildrensNovel特征目录的权限)。
CATFmAttributeNameAgeGroupAsName("AgeGroup");CATFmAttributeValue AgeGroupAsValue;rc=FeatFacadeOnChildrenNovelExt.GetValue(AgeGroupAsName,AgeGroupAsValue);if(FAILED(rc))return1;intAgeGroup=0;AgeGroupAsValue.GetInteger(AgeGroup);检索扩展并通过接口使用它
此步骤包括从基本特征中检索扩展特征(CAAOsmBiographicalNovel),以便通过由该扩展特征实现的接口来操作它。
rc=FeatFacadeOnNovelInstBaseFeat.GetExtension(strBiographicalExtNovel,AttrValue);CATFmFeatureFacadeFeatFacadeOnBiogNovelExt(MyCredential,AttrValue);首先,我们按照与上一步相似的方式检索CAAOsmBiographicalNovel特征,将其作为FeatFacadeOnBiogNovelExt(CATFmFeatureFacade类型)。但请注意这里的外观是在没有凭据的情况下创建的。我们将使用扩展特征指针(这是您总是可以自由地从外观中检索的数据)来工作。
我们的扩展特征通过CAAIFmExtBiogNovel接口公开其服务。因此下一步是检索此接口,然后调用其服务。
CAAIFmExtBiogNovel*piBiogNovelOnFeatExt=NULL;rc=FeatFacadeOnBiogNovelExt.QueryInterfaceOnFeature(IID_CAAIFmExtBiogNovel,(void**)&piBiogNovelOnFeatExt);CATFmFeatureFacade类的QueryInterfaceOnFeature调用返回用户选择的、底层特征之上的接口类型。在当前情况下我们检索piBiogNovelOnFeatExt,这是我们扩展特征上的一个CAAIFmExtBiogNovel接口指针。我们接着调用由我们扩展特征公开的各种服务。
CATUnicodeStringepoch("");rc=piBiogNovelOnFeatExt->GetEpoch(&epoch);epoch="Renaissance";rc=piBiogNovelOnFeatExt->SetEpoch(epoch);CAAIFmExtBiogNovel接口的GetEpoch()方法简单地检索我们"CAAOsmBiographicalNovel"特征的Epoch属性值,而SetEpoch()方法则设置Epoch属性值。
类似地,我们也检索并评估Domain属性。
检索基本特征
目标是从扩展特征检索其基本特征(Novel)。
首先,我们尝试从上一步“检索扩展并通过接口使用它”中检索到的CAAOsmBiographicalNovel扩展的外观FeatFacadeOnBiogNovelExt进行检索。
CATFmAttributeValue TheBaseFeatureAsValue;rc=FeatFacadeOnBiogNovelExt.GetBaseFeature(TheBaseFeatureAsValue);if(SUCCEEDED(rc))return1;GetBaseFeature失败,因为FeatFacadeOnBiogNovelExt没有凭据。
然后,我们尝试从上一步“检索扩展并通过特征外观使用它”中检索到的CAAOsmChildrensNovel扩展的外观FeatFacadeOnChildrenNovelExt进行检索。
TheBaseFeatureAsValue.Clear();rc=FeatFacadeOnChildrenNovelExt.GetBaseFeature(TheBaseFeatureAsValue);这种情况下的GetBaseFeature成功了,因为FeatFacadeOnChildrenNovelExt包含了作为定义CAAOsmChildrensNovel启动项的目录所有者的凭据。
添加了Clear方法以确保TheBaseFeatureAsValue不包含底层特征(不应该是这种情况,因为之前的GetBaseFeature失败了)。
CATBaseUnknown_var MyBaseFeatureAsFeature=TheBaseFeatureAsValue.GetFeature();CAAIFmExtNovel*pBaseFeatureAsIFmExtNovel=NULL;rc=MyBaseFeatureAsFeature->QueryInterface(IID_CAAIFmExtNovel,(void**)&pBaseFeatureAsIFmExtNovel);最后一部分只是确认检索到的基本特征是CAAOsmNovel特征。从包含基本特征的外观MyBaseFeatureAsFeature中,我们获得底层特征pBaseFeatureAsIFmExtNovel,然后我们在由 CAAOsmNovel实现的特定接口CAAIFmExtNovel上调用查询接口。
在应用容器内扫描基本特征的扩展特征
接下来,我们检索基本特征(CAAOsmNovel)的扩展,这些扩展存在于应用容器CAAOsmApplication1内。我们期望有2个(CAAOsmBiographicalNovel.1和CAAOsmHistoricalNovel.1)。
CATFmFeatureIterator oExtensionsIterator;CATStringCAAFmExtApplication1ID("CAAFmExtApplication1");rc=FeatFacadeOnNovelInstBaseFeat.ScanExtensionsInContainer(CAAFmExtApplication1ID,oExtensionsIterator);在基本特征FeatFacadeOnNovelInstBaseFeat上调用的CATFmFeatureFacade类的ScanExtensionsInContainer方法,检索其在提供的标识符对应的应用容器内的扩展特征。
返回结果是一个特征迭代器(oExtensionsIterator,CATFmFeatureIterator类型)。CATFmFeatureIterator的Next方法允许我们扫描迭代器以检索扩展特征。
intiCountOfExtns=0;CATFmFeatureFacadeFeatFacadeOnExtn(MyCredential);rc=oExtensionsIterator.Next(FeatFacadeOnExtn);while(SUCCEEDED(rc)){CATUnicodeString oDisplayName;rc=FeatFacadeOnExtn.GetDisplayName(oDisplayName);if(SUCCEEDED(rc)){iCountOfExtns++;rc=oExtensionsIterator.Next(FeatFacadeOnExtn);...}if(2!=iCountOfExtns)return1;CATFmFeatureFacade的GetDisplayName方法检索扩展特征的显示名称 [11]。
关于凭据:
- ScanExtensionsInContainer总是成功的,但返回的扩展可能或多或少。这里,由于FeatFacadeOnNovelInstBaseFeat(基本特征)的凭据至少包含处理基本特征的权限,您将获得此基本特征的所有扩展。如果凭据没有处理基本特征的权限,迭代器只返回您被授权处理的扩展3。
- GetDisplayName`成功是因为FeatFacadeOnExtn包含处理我们用例中任何特征的权限。
移除扩展特征
我们有选择地移除实例化在应用容器CAAOsmApplication1中的扩展特征。
CATFmFeatureIterator ListExtensionToDelete;rc=FeatFacadeOnNovelInstBaseFeat.ScanExtensionsInContainer(CAAFmExtApplication1ID,ListExtensionToDelete);...CATFmFeatureFacade FeatFacadeOnExtensionToDelete;while(SUCCEEDED(rc)&&SUCCEEDED(ListExtensionToDelete.Next(FeatFacadeOnExtensionToDelete))){rc=FeatFacadeOnNovelInstBaseFeat.RemoveExtension(FeatFacadeOnExtensionToDelete.GetFeatureAsValue());}首先,我们从基本特征获得扩展列表(我们可以重用上一步的迭代器)。然后,对于列表中的每个扩展,我们将其删除。这里您可以看到,用于从列表中检索每个扩展的外观(FeatFacadeOnExtensionToDelete)是没有凭据的。这是无用的,因为FeatFacadeOnNovelInstBaseFeat包含基本特征的凭据。因此,无论扩展外观的凭据如何,RemoveExtension都会成功。
这将移除类型分别为CAAOsmHistoricalNovel和CAAOsmBiographical的两个扩展特征。
请记住关于凭据:如果您只是扩展启动项的所有者,当在基本特征上调用RemoveExtension时,您只能删除该基本特征上的此类扩展。至少有一个外观(基本特征或扩展特征)必须包含正确的凭据。
在任何应用容器中扫描基本特征的扩展特征
接下来,我们检索基本特征(Novel)的扩展。我们总共实例化了三个扩展特征。其中,我们在前面的步骤中移除了应用容器CAAFmExtApplication1内的两个扩展特征。因此,我们现在只剩下一个类型为CAAOsmChildrensNovel的扩展特征,位于应用容器CAAFmExtApplication2内。
CATFmFeatureIterator oExtensionsIterator1;rc=FeatFacadeOnNovelInstBaseFeat.ScanExtensions(oExtensionsIterator1);在基本特征(FeatFacadeOnNovelInstBaseFeat)上调用的 CATFmFeatureFacade类的ScanExtensions方法,检索其所有扩展特征。
返回结果是一个特征迭代器(oExtensionsIterator1,CATFmFeatureIterator类型)。CATFmFeatureIterator的Next方法允许我们扫描迭代器以检索扩展特征。
iCountOfExtns=0;CATFmFeatureFacade FeatFacadeOnExtn1;rc=oExtensionsIterator1.Next(FeatFacadeOnExtn1);while(SUCCEEDED(rc)){CATUnicodeString oDisplayName1;rc=FeatFacadeOnExtn1.GetDisplayName(oDisplayName1);iCountOfExtns++;rc=oExtensionsIterator1.Next(FeatFacadeOnExtn1);}if(1!=iCountOfExtns)return1;CATFmFeatureFacade的GetDisplayName方法检索扩展特征的名称。
我们确认扩展特征的数量是1。
关于凭据:
- ScanExtensions总是成功的,但返回的扩展可能或多或少。这里,由于FeatFacadeOnNovelInstBaseFeat(基本特征)的凭据至少包含处理基本特征的权限,您将获得此基本特征的所有扩展。如果凭据没有处理基本特征的权限,迭代器只返回您被授权处理的扩展。
- GetDisplayName成功是因为FeatFacadeOnExtn包含处理我们用例中任何特征的权限。
尾声
有关保存会话时需要经历的步骤的详细描述,请参阅参考文献7。
简而言之
本用例中调用的FeatureModelerExt框架内CATFmFeatureFacade类的CAA服务如下:
- AddExtension:向基本特征添加扩展。
- GetExtension:从基本特征检索扩展,扩展 ID 作为输入。
- ScanExtensionsInContainer:在指定容器内扫描基本特征的扩展。
- RemoveExtensionsInContainer:在指定容器内移除基本特征的扩展。
- ScanExtensions: 扫描基本特征的所有扩展。
版本历史
版本 1 [2001年2月]: 文档创建
版本 2 [2003年9月]: 更新以添加指向《在应用容器中创建特征》文章的链接
版本 3 [2005年2月]: 文档更新以集成新的扩展特征API
版本 4 [2007年7月]: 集成 CATOsmSUHandler
版本 5 [2009年12月]: 迁移到外观认证机制
定义扩展特征 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
理解扩展特征 ↩︎
理解凭据 ↩︎ ↩︎ ↩︎
理解应用容器 ↩︎ ↩︎
在目录中创建启动项 ↩︎
构建和启动用例 ↩︎ ↩︎
连接到 V6 服务器 ↩︎ ↩︎
创建 PLM 技术表达 ↩︎
使用应用容器 ↩︎
创建特征 ↩︎