前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >29. 如何通过 ABAP 代码给 SAP OData 元数据增添注解

29. 如何通过 ABAP 代码给 SAP OData 元数据增添注解

作者头像
Jerry Wang
发布2022-12-23 08:34:40
3190
发布2022-12-23 08:34:40
举报

笔者的这篇 SAP UI5 开发教程文章,* SAP UI5 应用开发教程之一百二十九 - 如何给 SAP UI5 SmartField 添加 Value Help 功能,有朋友留言:

你好,请教一个问题,请问如何在odata里面通过annotations添加一个自定义注解?

你好,请问可以不可以在odata里面通过什么设置,从而自动给metadata.xml中加上注解,实现value help的功能,还是说每次需要在metadata.xml中修改?

这位朋友实际咨询的就是如何维护 metadata.xml 文件里这种 Annotations 标签。

在 OData 元数据里生成自定义注解的方式有很多种,比如在 CDS view 里维护注解,然后基于 CDS view 生成 OData 服务。对于本系列到目前为止采取 SEGW 事物码开发的 OData 服务来说,我们没有 CDS view 模型,因此可以采取另一种办法,即在 MPC_EXT 类里手动编写 ABAP 代码的方式来维护注解。

我们先看下效果,在 MPC_EXT 类的 DEFINE 方法里编写 ABAP 代码之后,用 Postman 使用 url 访问 OData metadata,在返回的数据里,能看到我们用 ABAP 代码添加的自定义注解。

代码语言:javascript
复制
<Annotations Target="ZJERRY.Book" xmlns="http://docs.oasis-open.org/odata/ns/edm">
                <Annotation Term="UI.HeaderInfo">
                    <Record>
                        <PropertyValue Property="TypeName" String="Book"/>
                        <PropertyValue Property="TypeNamePlural" String="Books"/>
                    </Record>
                </Annotation>
                <Annotation Term="UI.LineItem">
                    <Collection>
                        <Record Type="UI.DataField">
                            <PropertyValue Property="Label" String="Book"/>
                            <PropertyValue Property="Value" Path="Book"/>
                        </Record>
                    </Collection>
                </Annotation>
            </Annotations>

下面是详细的实现步骤讲解。

我们的 MPC_EXT 类里有一个属性 VOCAB_ANNO_MODEL, 要使用 ABAP 代码创建注解,就需要调用这个属性的 API 方法。

自定义注解的运行时载体是一系列拥有前缀 /iwbep/if_mgw_vocan 的对象实例,这些对象实例的列表,笔者已经在下面的代码里列出来了:

代码语言:javascript
复制
DATA: lo_ann_target  TYPE REF TO /iwbep/if_mgw_vocan_ann_target.   " Vocabulary Annotation Target
    DATA: lo_ann_target2 TYPE REF TO /iwbep/if_mgw_vocan_ann_target.   " Vocabulary Annotation Target
    DATA: lo_annotation  TYPE REF TO /iwbep/if_mgw_vocan_annotation.   " Vocabulary Annotation
    DATA: lo_collection  TYPE REF TO /iwbep/if_mgw_vocan_collection.   " Vocabulary Annotation Collection
    DATA: lo_function    TYPE REF TO /iwbep/if_mgw_vocan_function.     " Vocabulary Annotation Function
    DATA: lo_fun_param   TYPE REF TO /iwbep/if_mgw_vocan_fun_param.    " Vocabulary Annotation Function Parameter
    DATA: lo_property    TYPE REF TO /iwbep/if_mgw_vocan_property.     " Vocabulary Annotation Property
    DATA: lo_record      TYPE REF TO /iwbep/if_mgw_vocan_record.       " Vocabulary Annotation Record
    DATA: lo_simp_value  TYPE REF TO /iwbep/if_mgw_vocan_simple_val.   " Vocabulary Annotation Simple Value
    DATA: lo_url         TYPE REF TO /iwbep/if_mgw_vocan_url.          " Vocabulary Annotation URL
    DATA: lo_label_elem  TYPE REF TO /iwbep/if_mgw_vocan_label_elem.   " Vocabulary Annotation Labeled Element
    DATA: lo_reference   TYPE REF TO /iwbep/if_mgw_vocan_reference.    " Vocabulary Annotation Reference

本例我们为 OData 元数据创建一些位于命名空间 com.sap.vocabularies.UI.v1 之下的注解

代码语言:javascript
复制
lo_reference = vocab_anno_model->create_vocabulary_reference( iv_vocab_id = '/IWBEP/VOC_UI' iv_vocab_version = '0001').

lo_reference->create_include( iv_namespace = 'com.sap.vocabularies.UI.v1' iv_alias = 'UI' ).

上述代码,首先定义了一个指向 id 为 /IWBEP/VOC_UI 的词汇引用,然后为命名空间 com.sap.vocabularies.UI.v1 声明了一个别名 UI. 这样一来,我们稍后可以直接在代码里使用 UI 的简写形式,来指代 com.sap.vocabularies.UI.v1 了。

上述代码最终效果体现在元数据里如下图所示:

代码语言:javascript
复制
    lo_ann_target = vocab_anno_model->create_annotations_target( 'Book' ).
    lo_ann_target->set_namespace_qualifier( 'ZJERRY' ).    "change the namespace to the SRV namespace

上面的代码,给名叫 Book 的 Entity Type 创建注解,并且设置命名空间为 ZJERRY. 最后在元数据里生成的注解如下图所示:

继续为上图的注解创建更多的元素。

代码语言:javascript
复制
lo_annotation = lo_ann_target->create_annotation( iv_term = 'UI.HeaderInfo' ).
lo_record = lo_annotation->create_record( ).

lo_record->create_property( 'TypeName' )->create_simple_value( )->set_string('Book').

lo_record->create_property( 'TypeNamePlural' )->create_simple_value( )->set_string( 'Books').

ZJERRY.Book 这个 Entity Type 创建名叫 UI.HeaderInfo 的注解,然后创建 Record 子节点。在 Record 子节点内,创建名叫 TypeName 和 TypeNamePlural 的属性,分别附上属性值 Book 和 Books.

这些注解都是为 Fiori Elements 的 List Report 页面使用的,在元数据里的效果如下图所示:

剩下的代码原理同已经讲解的相同,这里不再赘述:

代码语言:javascript
复制
lo_annotation = lo_ann_target->create_annotation( iv_term = 'UI.LineItem' ).
    lo_collection = lo_annotation->create_collection( ).

    lo_record = lo_collection->create_record( iv_record_type = 'UI.DataField' ).
    lo_property = lo_record->create_property( 'Label' ).
    lo_simp_value = lo_property->create_simple_value( ).
    lo_simp_value->set_string( 'Book' ).
    lo_property = lo_record->create_property( 'Value' ).
    lo_simp_value = lo_property->create_simple_value( ).
    lo_simp_value->set_path( 'Book' ).

上述代码在 OData 元数据里产生的效果:

注意,大家把上述代码粘贴到 Define 方法中,激活之后,使用 Postman 发起元数据请求,可能无法看到编写的代码立即生效。

究其原因,是因为这篇文章里介绍的 OData 缓存在起作用:

27. SAP OData 框架里的缓存(Cache)设计专题讲座

只需要按照笔者文章里介绍的步骤,执行 /IWFND/CACHE_CLEANUP/IWBEP/CACHE_CLEANUP 两个事物码清除前台服务器和后台服务器的缓存即可:

Define 方法的完整代码:

代码语言:javascript
复制
  method DEFINE.
    super->define( ).

    DATA(lo_entity_type) = model->get_entity_type( iv_entity_name = 'File' ).
    IF lo_entity_type IS BOUND.
      lo_entity_type->set_is_media( iv_is_media = abap_true ).
      lo_entity_type->get_property( iv_property_name = 'mimetype' )->set_as_content_type( ).
    ENDIF.

    DATA: lo_ann_target  TYPE REF TO /iwbep/if_mgw_vocan_ann_target.   " Vocabulary Annotation Target
    DATA: lo_ann_target2 TYPE REF TO /iwbep/if_mgw_vocan_ann_target.   " Vocabulary Annotation Target
    DATA: lo_annotation  TYPE REF TO /iwbep/if_mgw_vocan_annotation.   " Vocabulary Annotation
    DATA: lo_collection  TYPE REF TO /iwbep/if_mgw_vocan_collection.   " Vocabulary Annotation Collection
    DATA: lo_function    TYPE REF TO /iwbep/if_mgw_vocan_function.     " Vocabulary Annotation Function
    DATA: lo_fun_param   TYPE REF TO /iwbep/if_mgw_vocan_fun_param.    " Vocabulary Annotation Function Parameter
    DATA: lo_property    TYPE REF TO /iwbep/if_mgw_vocan_property.     " Vocabulary Annotation Property
    DATA: lo_record      TYPE REF TO /iwbep/if_mgw_vocan_record.       " Vocabulary Annotation Record
    DATA: lo_simp_value  TYPE REF TO /iwbep/if_mgw_vocan_simple_val.   " Vocabulary Annotation Simple Value
    DATA: lo_url         TYPE REF TO /iwbep/if_mgw_vocan_url.          " Vocabulary Annotation URL
    DATA: lo_label_elem  TYPE REF TO /iwbep/if_mgw_vocan_label_elem.   " Vocabulary Annotation Labeled Element
    DATA: lo_reference   TYPE REF TO /iwbep/if_mgw_vocan_reference.    " Vocabulary Annotation Reference

    lo_reference = vocab_anno_model->create_vocabulary_reference( iv_vocab_id = '/IWBEP/VOC_UI' iv_vocab_version = '0001').

    lo_reference->create_include( iv_namespace = 'com.sap.vocabularies.UI.v1' iv_alias = 'UI' ).

    lo_ann_target = vocab_anno_model->create_annotations_target( 'Book' ).
    lo_ann_target->set_namespace_qualifier( 'ZJERRY' ).    "change the namespace to the SRV namespace

    lo_annotation = lo_ann_target->create_annotation( iv_term = 'UI.HeaderInfo' ).
    lo_record = lo_annotation->create_record( ).
    lo_record->create_property( 'TypeName' )->create_simple_value( )->set_string('Book').
    lo_record->create_property( 'TypeNamePlural' )->create_simple_value( )->set_string( 'Books').

    lo_annotation = lo_ann_target->create_annotation( iv_term = 'UI.LineItem' ).
    lo_collection = lo_annotation->create_collection( ).

    lo_record = lo_collection->create_record( iv_record_type = 'UI.DataField' ).
    lo_property = lo_record->create_property( 'Label' ).
    lo_simp_value = lo_property->create_simple_value( ).
    lo_simp_value->set_string( 'Book' ).
    lo_property = lo_record->create_property( 'Value' ).
    lo_simp_value = lo_property->create_simple_value( ).
    lo_simp_value->set_path( 'Book' ).

  endmethod.
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档