ABAP Keyword Documentation → ABAP - Dictionary → ABAP CDS in ABAP Dictionary → ABAP CDS - Annotations
ABAP CDS - Evaluation of Annotations
When an object defined in the CDS source code is activated, the annotations defined in the CDS annotation syntax there are saved in internal database tables in ABAP Dictionary. These tables can then be accessed to evaluate the data. This is done for every annotation with correct syntax regardless of name and value.
Other versions:
7.31 | 7.40 | 7.54
System Class CL_DD_DDL_ANNOTATION_SERVICE
The following documented system class is provided for evaluations of the annotations of CDS entities:
CL_DD_DDL_ANNOTATION_SERVICE
The methods of this class return the annotations of CDS entities. By default, the annotations are returned from metadata extensions first, and then from the CDS entity itself. In the latter case, a distinction can be made between direct, derived and inherited annotations, while in the case of inherited annotations the metadata extensions (if present) are handled first. More specifically, an initial annotation value is returned in cases where an annotation has no values specified, rather than any default value defined in the annotation definition.
Notes
- The method GET_ANNOTATIONS of the class CL_DD_DDL_ANALYZE also returns the annotations of CDS entities. It must be noted, however, that these only analyze the associated DDL source code. Annotations from metadata extensions, derived and inherited annotations, and the translations of annotations for translatable texts are ignored.
- When the system class CL_DD_DDL_ANNOTATION_SERVICE is used to evaluate annotations, the annotations of the CDS entities are also respected, as specified in their DDL source code in CDS annotation syntax. The associated annotation definitions are ignored by CL_DD_DDL_ANNOTATION_SERVICE. The validity of an annotation must be checked by the responsible framework.
- ADT supports the specification of valid annotations (namely annotations with an annotation definition) by using colors in the source code and code completion.
Executable Example
Metadata Extensions
Metadata extensions add further annotations to a CDS entity or override existing annotations. Currently metadata extensions can only be defined for CDS views and abstract CDS entities. Only specific annotations can be added to metadata extensions. These annotations are ignored when the CDS entity is activated.
The methods of the class CL_DD_DDL_ANNOTATION_SERVICE (except GET_DIRECT_ANNOS_...) respect by default the existing metadata extensions in the current AS ABAP when the annotations of a CDS entity are evaluated. There can be multiple metadata extensions for an entity. These extensions can be distinguished by assignments to various layers, such as industry, partner, and customer, and by the association with CDS variants. The methods of the class CL_DD_DDL_ANNOTATION_SERVICE collect all annotations belonging to the CDS entity in the following order:
- Annotations from metadata extensions
- Direct annotations from the data definition
- Indirect annotations (derived and inherited annotations)
Here every annotation is only returned once for its scope. If annotations have the same name, the priority is determined first by the explicit specification of a CDS variant when the method is called, and then by the layers of the involved metadata extensions. The evaluation is performed using the following steps:
- First the metadata extensions of the specified variant are evaluated. Here, an annotation of a higher level overrides the annotation of a lower layer.
- Then the metadata extensions are evaluated, which are not linked to any variants. Once again, higher levels override lower levels.
- Finally, the direct and indirect annotations of the CDS entity are evaluated. In the evaluation of the annotations inherited from the other CDS entities, any metadata extensions are taken into account first.
Annotations found in an earlier evaluation level always have the higher priority. An annotation from a later level is only returned if it has already been found in an earlier level. The results of the class CL_DD_DDL_ANNOTATION_SERVICE show where an annotation was specified.
Notes
- Annotations from metadata extensions are not stored in the same system tables as annotations from the DDL source code of a CDS entity. They can only be made accessible by using the class CL_DD_DDL_ANNOTATION_SERVICE. Other classes ignore metadata extensions.
- For more information and examples related to evaluation, see metadata extensions and evaluation of metadata extensions.
- The program ABAP_DOCU_MDE_ANNOS shows all annotations that can be specified in metadata extensions.
Caution
CDS variants are not currently released for general use. It is not possible to define standalone CDS variants and the use of CDS variants in metadata extensions produces a syntax check warning.
Direct, Inherited, and Derived Annotations
In the evaluation of annotations of a CDS entity using methods of the class CL_DD_DDL_ANNOTATION_SERVICE, which cannot be overridden by metadata extensions, it is possible to distinguish between the following types of annotations:
- Direct annotations
- Indirect annotations
- Inherited annotations
If these annotations are not specified explicitly in the DDL source code of the CDS entity, they are taken from the dictionary objects used in the CDS entity, in accordance with the rules described in the class documentation of CL_DD_DDL_ANNOTATION_SERVICE. When other CDS entities are accessed, their annotations specified in metadata extensions, direct annotations, and derived annotations are inherited. Other dictionary objects, such as database tables and classic views, do not have any direct annotations. However, their annotations derived from assigned data elements are inherited. The view annotation Metadata.ignorePropagatedAnnotations can be used to specify whether the class CL_DD_DDL_ANNOTATION_SERVICE takes into account or ignores inherited annotations.
- Derived annotations
If these annotations are not explicitly specified or inherited in the DDL source code of the CDS entity, they are derived (if possible) from assigned data elements of ABAP Dictionary. The relevant annotations are the element and parameter annotations @EndUserText.Label, @EndUserText.QuickInfo and @EndUserText.Heading, which are supplied with texts according to rules (described in the class documentation CL_DD_DDL_ANNOTATION_SERVICE) from the field labels of assigned data elements. The annotation @EndUserText.Heading is only currently possible as an implicit annotation for this purpose. If specified directly in the DDL source code of a data definition, an annotation is not recognized as a language-dependent text. @EndUserText.Heading is also not allowed in the DDLX source code of a metadata extension.
Notes
- Inheritances apply especially to those element annotations of CDS associations published in the SELECT list using a path expression path_expr. A publication of a CDS association specified in a different CDS view inherits the element annotations of preceding publications.
- Annotations derived from data elements depend on the assignment of data elements to elements of the current CDS entity. This assignment is performed in the internal metadata of a CDS entity and is not dependent on inheritance.
- The annotations types described here apply especially to evaluations using the class CL_DD_DDL_ANNOTATION_SERVICE. Other APIs can evaluate the underlying metadata differently.
Example
The following three pieces of DDL source code define three views; the first two views access the third view. The only difference between the first two views is the specification of annotation @Metadata.ignorePropagatedAnnotations:true. Every view contains an element with a direct element annotation @EndUserText.label.
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view demo_cds_anno_inheritance_1
as select from
demo_cds_anno_inheritance_2
{
@EndUserText.label: 'XXXXXXXXXX'
key id,
key carrier,
key flight,
departure,
destination
}
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.ignorePropagatedAnnotations: true
define view demo_cds_anno_inheritance_1A
as select from
demo_cds_anno_inheritance_2
{
@EndUserText.label: 'XXXXXXXXXX'
key id,
key carrier,
key flight,
departure,
destination
}
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view demo_cds_anno_inheritance_2
as select from
spfli
join scarr on
scarr.carrid = spfli.carrid
{
key spfli.carrid as id,
key scarr.carrname as carrier,
@EndUserText.label: 'YYYYYYYYYY'
key spfli.connid as flight,
spfli.cityfrom as departure,
cast( spfli.cityto as demo_destination ) as destination
}
The program DEMO_CDS_DERIVED_INHERIT_ANNOS uses a method of the class CL_DD_DDL_ANNOTATION_SERVICE to read the element annotations of the first two CDS views:
- Almost all element annotations in this example are from annotations derived from data elements. This applies especially to the annotation @EndUserText.heading, which cannot be specified in the source code. The texts of the element destination originate from data element demo_destination, which overrides the automatic assignment to S_TO_CITY in a CAST expression.
- Without the annotation @Metadata.ignorePropagatedAnnotations:true, the derived annotations are inherited from the used objects. The SOURCEOBJECT column contains the names of the objects.
- If annotation @Metadata.ignorePropagatedAnnotations:true is used, the derivation is performed in the current view and the column SOURCEOBJECT only displays names.
- The value of annotation @EndUserText.label of element id originates from the annotation specified directly in the first two views.
- The value of annotation @EndUserText.label of element flight originates in the first view from the annotation, which it inherits from the second view. In the second view, this inheritance is suppressed by the annotation @Metadata.ignorePropagatedAnnotations:true.
The ABAPCATALOG.INTERNAL.ISMANDT annotation that is visible in the output is an internal annotation, which indicates the client field of a client-specific CDS entity.
Subannotations
In the annotation syntax, subannotations are specified either as comma-separated lists in curly brackets or using structured names. The way this metadata is saved internally is independent of the way it is specified and the methods of the class CL_DD_DDL_ANNOTATION_SERVICE always return subannotations as an individual annotation with a structured name.
Example
Subannotations specified as followed
subAnno2: { subAnno1: 1,
subAnno2: { subAnno1: 1,
subAnno2: 2 } } }
are the same as those specified as follows
@DemoAnno.subAnno2.subAnno1: 1
@DemoAnno.subAnno2.subAnno2.subAnno1: 1
@DemoAnno.subAnno2.subAnno2.subAnno2: 2
Evaluating either of the above using the method GET_DIRECT_ANNOS_4_ENTITY of the class CL_DD_DDL_ANNOTATION_SERVICE produces the following
ANNONAME | VALUE |
---|---|
DEMOANNO.SUBANNO1 | true |
DEMOANNO.SUBANNO2.SUBANNO1 | 1 |
DEMOANNO.SUBANNO2.SUBANNO2.SUBANNO1 | 1 |
DEMOANNO.SUBANNO2.SUBANNO2.SUBANNO2 | 2 |
Annotation Arrays
In the annotation syntax, annotation arrays are created using comma-separated lists in square brackets after a specified annotation. When this metadata is saved internally, the elements of annotation arrays are saved as individual annotations. Here, they are saved under the name of the array. A consecutive index enclosed in $ characters $1$, $2$, ... is appended to this array. Accordingly, the methods of the class CL_DD_DDL_ANNOTATION_SERVICE return an array as individual annotations.
Note
For annotation arrays, the annotation syntax in DDL source code for CDS entities is not as strict as the syntax of DEFINE ANNOTATION for annotation definitions.
- Array elements do not always have to have the same type in the annotation syntax.
- Arrays can be nested directly in the annotation syntax.
In the internal metadata (and hence in the results of the methods of the class CL_DD_DDL_ANNOTATION_SERVICE), array elements with non-matching types are returned just as specified in the annotation syntax. Directly nested arrays are not saved but they are counted when the elements are indexed.
Example
The annotation array specified as follows is valid annotation syntax, but it cannot have an annotation definition.
[1,2,3],
{ subAnno1:1, subAnno2:2} ]
The elements of the error do not have matching types and the second element is a directly nested array. The method GET_DIRECT_ANNOS_4_ENTITY of the class CL_DD_DDL_ANNOTATION_SERVICE produces the following:
ANNONAME | VALUE |
---|---|
DEMOANNO$1$ | true |
DEMOANNO$3$.SUBANNO1 | 1 |
DEMOANNO$3$.SUBANNO2 | 2 |
It should be noted that the nested array is counted but not returned.
Null Values
For each element annotation of a CDS entity that is not part of an annotation array, the special value null can be specified (without quotation marks). The value null leads to a syntax error at other positions. The value null means that the annotation is not returned by default by the methods of the class CL_DD_DDL_ANNOTATION_SERVICE. The default setting can be changed with the method input parameter NULL_VALUES.
Notes
- Null values are only intended to hide unwanted, derived and inherited annotations in the evaluation of the annotations of a CDS entity.
- A null value is inherited like every value. A direct annotation of a CDS entity overwrites the annotations taken from used dictionary objects. This means any values can be overwritten with the null value; a null value itself can also be overwritten.
- In the DDLX source code of CDS metadata extensions, null values can be specified in exactly the same way as in the DDL source code of a CDS entity.
- The evaluation only filters the annotations out, if a null value has been specified for their identifiers.
- If specified, @annotation.annotation1:null only affects the identifier @annotation.annotation1 but does not affect, for example, @annotation.annotation1.annotation2.
- If the null value is specified for an annotation array, this value affects the entire array. @annot:null specified for an inherited annotation array @annot:[ ..., ..., ...] is applied to all elements of the array.
- The evaluation filters annotations with null values - completely regardless of whether they are predefined SAP annotations or not.
Example
The following two CDS source codes define two views; the second view accesses the first view. In the first view, @EndUserText annotations with literal values are specified for every element of the SELECT list. In the second view, some of these values are overwritten with the value null. This occurs in the first view for the special annotation @EndUserText.heading.
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view demo_cds_anno_null_value_1
as select from
spfli
join scarr on
scarr.carrid = spfli.carrid
{
@EndUserText.heading: null
@EndUserText.label: 'ID'
@EndUserText.quickInfo: 'ID'
key spfli.carrid as id,
@EndUserText.label: 'Carrier'
@EndUserText.quickInfo: 'Carrier'
key scarr.carrname as carrier,
@EndUserText.label: 'Flight'
@EndUserText.quickInfo: 'Flight'
key spfli.connid as flight
}
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view demo_cds_anno_null_value_2
as select from
demo_cds_anno_null_value_1
{
@EndUserText: null
key id,
@EndUserText.heading: null
@EndUserText.label: null
key carrier,
@EndUserText.heading: null
@EndUserText.quickInfo: null
key flight
}
The program DEMO_CDS_NULL_ANNOS uses a method of the class CL_DD_DDL_ANNOTATION_SERVICE to read the element annotations of the two CDS views. Annotations containing the value null in the second view are not reset.
- The annotation @EndUserText: null is ignored in front of the element id. This annotation does not filter out all @EndUserText annotations of this element. This annotation would overwrite an element annotation @EndUserText: ... of the first view, which is not specified there since it is not a valid ABAP annotation.
- The annotations @EndUserText.label: null and @EndUserText.quickInfo:
null in front of the elements
carrier
or flight overwrite the values of the annotations, which were inherited from the first view. They are not returned by the evaluation.
- The derived annotation @EndUserText.Heading is assigned the value null for every element. This occurs for in the first view for the element id. For this view, the evaluation returns the annotation for the other two elements. In the second view, the value null is also set for this view and the evaluation does not return the annotation @EndUserText.Heading for any of the elements of the CDS view.
Annotations for Translatable Texts
The annotation values of annotations for which this is defined in their annotation definition (using the annotation @LanguageDependency) are used to define translatable semantic texts for a CDS object.
The value of an annotation like this is saved in special tables that have a language key and that are translatable. The value specified in the source code should consist of text in the original language of the CDS source code and is translated into the required languages. The methods of the class CL_DD_DDL_ANNOTATION_SERVICE read these texts as specified by an input parameter for the language. If no language is passed to the input parameter, the text environment language is used as the default. If no text is found for the language, the secondary language in AS ABAP is used.
Notes
- Even in metadata extensions, the annotations for translatable texts are handled specially and are created in special tables, which are connected to the translation.
- The program ABAP_DOCU_TRANSLATABLE_ANNOS shows all annotations for translatable texts.
Example
The following CDS source code, which defines a CDS view, contains the specific ABAP annotations that are introduced using EndUserText.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@AbapCatalog.sqlViewName: 'DEMO_VIEW_TEXTS'
define view demo_cds_text_annotations
with parameters
@EndUserText.label:'Eingabeparameter'
param : abap.int4
as select from
demo_expressions
{
@EndUserText:{ label:'Ein Element', quickInfo:'Feld' }
id
}
The program DEMO_CDS_DDL_TEXTS uses methods of the class CL_DD_DDL_ANNOTATION_SERVICE to access the associated texts (in a language-dependent way). The original language of the view is German and the German texts must be available in every system. If an English translation exists, this is also read and displayed.
Performing the Evaluation
ABAP annotations and framework-specific annotations are evaluated in different ways:
- ABAP annotations
- Framework-specific annotations
Annotations that are not evaluated by the ABAP runtime environment or by frameworks of other software components are usually ignored.