作者上一篇文章SAPFiori注解@ObjectModel.readOnly工作原理分析,介绍了SAPFiori编程模型中@ObjectModel.readOnly注解的工作原理。SAPFiori注释是SAPFiori的ABAP编程模型的重要概念之一。所谓注解(annotation),Java和JavaScript开发者一定不会陌生。同样,CDS注释允许ABAP开发人员将ABAP和组件特定的元数据添加到任何CDS实体的源代码中。根据一致性和注解有效性评估的实现细节,SAPCDS视图的注解分为以下两类:ABAP注解:由ABAP运行时环境评估。组件注释:由相关的SAP框架评估。开发人员可以使用元数据扩展中的注释为CDS视图定义客户特定的元数据,而无需修改SAP自己发布的标准CDS实体。使用元数据扩展时,可以覆盖数据定义中定义的特定注解值,或者为实体添加额外的注解值。可以在CDS视图或视图字段上添加注释,这是一个示例:@AbapCatalog.sqlViewName:'CUSTOMER'@AccessControl.authorizationCheck:#NOT_REQUIRED@Metadata.allowExtensions:trueDEFINEVIEWcust_book_view_entityASSELECTFROMscustomJOINsbookONscustom.id=sbook.customid{@EndUserText.label:'客户ID'scustom.id,@EndUserText.label:'客户姓名'scustom.name,@EndUserText.label:'客户预订ID'sbook.bookid}本文继续探讨另一个注释@OData.publish是如何工作的。在SAP官网ABAPProgrammingModelforSAPFiori的帮助文档中,ODataAnnotations目录下有这个注解的介绍。一旦激活带有该注解的CDS视图,就会自动生成一个OData服务。这个OData服务是如何自动生成的?这就是本文想要分享的内容。SAPFiori编程模型支持一种公开OData服务的新方法。该OData服务的模型定义和运行时基于服务适配描述语言(ServiceAdaptationDescriptionLanguage,简称SADL)。下面是一个示例:@AbapCatalog.sqlViewName:'SQL_VIEW_SAMPLE'..@OData.publish:truedefineviewCDS_VIEW_NAMEasselectfrom...}使用SAPABAP开发工具打开CDS视图源代码编辑页面。在CDS视图中添加OData注解后,即可触发整个DDL源码的激活。ABAP开发工具将激活请求委托给SADL框架。SADL生成若干SAPGateway工件(Artifacts),这些工件作为ABAP存储在应用服务器的后端,是在SAPGatewayhub系统中激活和运行OData服务所必需的。以上就是通过CDS视图暴露OData服务的理论知识。假设我们不知道激活带有该注解的CDS视图后自动生成的OData服务的详细信息,那么我们从哪里入手进行研究呢?我创建了一个名为zjerrytest20160311的视图,然后添加了这个注解并激活了它。根据我的经验,按照SAP的惯例,自动生成的OData服务的名称也应该包含字符串0311。激活后尝试以0311为关键字在OData服务的注册事务码/IWFND/MAINT_SERVICE中搜索,找到了对应生成的OData服务:笔者之前的Class(类)设计原理分析ABAP编程语言一文中提到,根据0311查询ABAPNetweaver的注册表TADIR,发现CDS视图激活后,除了OData服务本身,还自动生成了以下对象:IWMO:SAPGatewayBusinessSuiteEnablement对应模型IWSV:SAPGatewayBusinessSuiteEnablement对应的服务CLAS:OData服务的实现类ZCL_ZJERRYTEST20160311做了实验。当我将OData.publish的值设置为false并再次激活时,发现IWMO和IWSV类型的对象从注册表TADIR中消失了,这再次证实了这两个是在注解OData.publish后激活CDS视图生成的设置为真。那么如何研究CDS视图激活时这两个对象的自动生成逻辑呢?打开事务码ST05,进入跟踪模式,激活CDS视图,在数据库跟踪结果中,找到了将自动生成的对象名插入注册表TADIR的OPENSQL语句。在ABAP中,在插入数据库表的OPENSQL语句之前,必须有插入数据的生成逻辑。点击ST05中的蓝色眼镜图标,自动跳转到OPENSQL语句。设置断点,激活CDS视图,触发断点:从当前调用栈回溯,发现第21个调用栈帧是自动生成OData服务的地方:CL_WB_DDLS_SECOBJ_HNDLR_SINGLE->IF_DDIC_WB_DDLS_SECOBJ_HANDLER~ON_ACTIVATION这个方法首先判断是基于ondelta_state需要删除,添加或更新的对象列表存储在下图中第12到14行的三个输出参数中。比如我在一个激活的CDS视图源码上添加@OData.publish:true注解,然后激活,这个注解的EDIT_STATE是N(New),而其他的注解没有任何变化,标记为U(不变)。这里会根据EDIT_STATE的值进入相应的分支。EDIT_STATE值为N的分支执行OData服务的创建,通过CL_SADL_GTK_ODATA_SERVICE_GEN完成,后缀GEN代表Generation。从调试器可以看出,名为ZJERRYTEST20160311的OData服务是通过create_via_exposure方法创建的。完整的调用栈:这篇文章其实是另一个具体的例子,如何在不知道一段逻辑(不管是框架层面还是应用层面)的情况下,使用工具ST05找到设置断点的代码位置,从而找到问题分析的根源突破口。总结本文从开发人员的角度深入介绍了SAPFiori注释@OData.publish的工作原理。同时也展示了如何使用事务码ST05定位到ABAP框架自动生成的OData服务资源的准确代码位置。
