orkungedik/SAP-basis-dataset huggingface dataset:
## 4.2.15.16.1  Core Principles
The design of the XCO library is based on the following core principles:
## · Modules
The XCO library is organized as a collection of (largely) independent modules (corresponding to ABAP packages). The public API of each module is exposed via a special class, called the API 'class' of the module. It is distinguished from all other XCO classes and interfaces in that it starts with 'XCO\_CP\_' . The API class acts as the single point of entry for the functionality offered by a given module. Starting with the API class, code completion can be used to easily discover the scope of a given module.
<!-- image -->
## · Enumerated Values
In the XCO library enumerated values are represented by pre-created objects which can be accessed via the API class of the module they belong to. Besides offering a strongly typed way to work with fixed values they also provide additional properties specific to the enumeration as well as access to the underlying primitive value.
<!-- image -->
## · Exception Handling
All XCO modules follow a uniform error propagation strategy. Unless the caller of an API can be expected to recover from an error situation (e.g. when attempting to acquire an exclusive lock), all error situations are handled through no\_check exceptions.
Any runtime exception that is raised explicitly by the XCO library is a subclass of
CX\_XCO\_RUNTIME\_EXCEPTION (cf. section Exception philosophy in Standard Library [page 1689]).
## 4.2.15.16.3  ABAP Repository
## 4.2.15.16.3.1  Query APIs
The XCO ABAP Repository module provides Query APIs that allow to easily navigate through the ABAP Repository.
## Context
To this extent, an object selection functionality is provided that is based on the following two central abstractions:
- Object source: An entity that can naturally act as a source of ABAP repository objects, e.g. a package or a transport or even the complete ABAP repository
- Object filter: An encapsulation for any kind of filter that can be applied to a selection of ABAP Repository objects. Examples are software or application components or type specific properties like foreign key attributes of database table fields
The entry point for retrieving a collection of objects from the ABAP Repository is XCO\_CP\_ABAP\_REPOSITORY=&gt;OBJECTS. Note that independently of any filters, the visible ABAP Repository objects are those which either have been explicitly released by SAP or which belong to customer software components. The overall usage is illustrated by two examples below.
In the first example, all repository objects of the whole ABAP Repository whose software component is ZLOCAL and whose name contains the fragment CAL are retrieved. As no explicit object type is specified the retrieved objects have the type IF\_XCO\_AR\_OBJECT:
```
 Sample Code DATA(lo_software_component_filter) = xco_cp_system=>software_component->get_filter( xco_cp_abap_sql=>constraint->equal( 'ZLOCAL' ) ). DATA(lo_name_filter) = xco_cp_abap_repository=>object_name->get_filter( xco_cp_abap_sql=>constraint->contains_pattern( '%CAL%' ) ). DATA(lt_objects) = xco_cp_abap_repository=>objects->where( VALUE #( ( lo_software_component_filter ) ( lo_name_filter ) ) )->in( xco_cp_abap=>repository )->get( ). LOOP AT lt_objects INTO DATA(lo_object). DATA(lv_object_type) = lo_object->type->value. DATA(lv_object_name) = lo_object->name->value. " ... ENDLOOP.
```
In the second example all database tables of the package Z\_MY\_OBJECTS that have at least one field which has a foreign key whose check table is ZHOLIDAY are retrieved. As in this case the object type (database table) is explicitly specified the retrieved objects are of type IF\_XCO\_DATABASE\_TABLE:
```
 Sample Code DATA(lo_package) = xco_cp_abap_repository=>package->for( 'Z_MY_OBJECTS' ). DATA(lo_filter) = xco_cp_table=>field_property->foreign_key_check_table->get_filter( xco_cp_abap_sql=>constraint->equal( 'ZHOLIDAY' ) ). DATA(lt_database_tables) = xco_cp_abap_repository=>objects->tabl->database_tables->where( VALUE #( ( lo_filter ) ) )->in( lo_package )->get( ). LOOP AT lt_database_tables INTO DATA(lo_database_table). DATA(lv_name) = lo_database_table->name. " ... ENDLOOP.
```
## 4.2.15.16.3.2.2  Reading AMDP Attributes of a Method Implementation
Given a class with an AMDP method implementation such as
```
 Sample Code CLASS zcl_xco_doc_cp_amdp DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb. METHODS: amdp_method. ENDCLASS. CLASS zcl_xco_doc_cp_amdp IMPLEMENTATION. METHOD amdp_method BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING zxco_amdp_dbt. SELECT * FROM zxco_amdp_dbt WHERE id = '001'; ENDMETHOD. ENDCLASS.
```
the AMDP attributes of the method implementation can be read out as follows:
```
 Sample Code "! Code sample for reading the AMDP attributes of a method implementation. "! "! IMPORTANT: The values of the constants CO_CLASS_NAME and CO_METHOD_NAME "! must be replaced with the name of an existing class and a method that is "! implemented in this class. CLASS zcl_xco_doc_cp_read_amdp DEFINITION PUBLIC FINAL INHERITING FROM cl_xco_cp_adt_simple_classrun CREATE PUBLIC. PROTECTED SECTION. METHODS: main REDEFINITION. PRIVATE SECTION. CONSTANTS: co_class_name  TYPE sxco_ao_object_name VALUE 'ZCL_XCO_DOC_CP_AMDP',
```
```
co_method_name TYPE sxco_clas_method_name VALUE 'AMDP_METHOD'. ENDCLASS. CLASS zcl_xco_doc_cp_read_amdp IMPLEMENTATION. METHOD main. DATA(lo_method_implementation) = xco_cp_abap=>class( co_class_name )->implementation->method( co_method_name ). " LS_METHOD_IMPLEMENTATION will contain both the AMDP attributes and the source " code of the method implementation. DATA(ls_method_implementation) = lo_method_implementation->content( )>get( ). out->write( ls_method_implementation ). " The AMDP database type is represented as an object of type CL_XCO_AMDP_DB_TYPE. " Supported AMDP database types are available via XCO_CP_AMDP=>DATABASE_TYPE. DATA(lo_amdp_database_type) = ls_method_implementation-amdp-database_type. out->write( lo_amdp_database_type ). " The AMDP database language is represented as an object of type CL_XCO_AMDP_DB_LANGUAGE. " Supported AMDP database languages are available via XCO_CP_AMDP=>DATABASE_LANGUAGE. DATA(lo_amdp_database_language) = ls_method_implementation-amdp-database_language. out->write( lo_amdp_database_language ). " The AMDP database options are represented as objects of type CL_XCO_AMDP_DB_OPTION. " Supported AMDP database options are available via XCO_CP_AMDP=>DATABASE_OPTION. DATA(lt_amdp_database_options) = ls_method_implementation-amdp-database_options. out->write( lt_amdp_database_options ). " An AMDP database entity is represented as object of type IF_XCO_AMDP_DATABASE_ENTITY. " The IF_XCO_PRINTABLE~GET_TEXT method can be used to obtain the string value for a database " entity. LOOP AT ls_method_implementation-amdp-database_entities INTO DATA(lo_amdp_database_entity). DATA(lv_amdp_database_entity) = lo_amdp_database_entity->if_xco_printable~get_text( )->get_lines( )->join( )->value. out->write( lv_amdp_database_entity ). ENDLOOP. ENDMETHOD. ENDCLASS.
```
## 4.2.15.16.3.2.4  Reading a Transformation
Given a transformation (i.e. an XSLT object), its contents can be read and written to the console as follows:
```
 Sample Code "! Code sample for reading the contents of a transformation (XSLT object). "! "! IMPORTANT: The value of the constant CO_TRANSFORMATION_NAME must be replaced with "! the name of an existing transformation for which the content shall be read. CLASS zcl_xco_doc_cp_read_trnsfrmtn DEFINITION PUBLIC FINAL INHERITING FROM cl_xco_cp_adt_simple_classrun CREATE PUBLIC. PROTECTED SECTION. METHODS: main REDEFINITION. PRIVATE SECTION. CONSTANTS: co_transformation_name TYPE sxco_tf_object_name VALUE 'ZMY_TRANSFORMATION'. ENDCLASS. CLASS zcl_xco_doc_cp_read_trnsfrmtn IMPLEMENTATION. METHOD main. DATA(lo_transformation) = xco_cp_abap_repository=>object->xslt>for( co_transformation_name ). out->write( lo_transformation ). " LS_TRANSFORMATION will contain both the short description and the source code of the " transformation. DATA(ls_transformation) = lo_transformation->content( )->get( ). out->write( ls_transformation ). " The source code of the transformation is represented as an object of type IF_XCO_TF_SOURCE_CODE. " Via the IF_XCO_TEXT~GET_LINES method the source code can also be easily obtained as a string_table. DATA(lt_source_code) = ls_transformation-source_code->if_xco_text~get_lines( )->value. out->write( lt_source_code ). ENDMETHOD. ENDCLASS.
```
## 4.2.15.16.3.3  Generation APIs
The XCO Generation APIs are the part of the XCO library that allows the programmatic creation, update and deletion of ABAP repository objects. It consists of high-level and strongly typed APIs for the following objects types:
- BDEF (Behavior Definitions)
- CLAS (Classes)
- DCLS (Access Controls)
- DDLS (Data Definitions)
- DDLX (Metadata Extensions)
- DESD (Logical External Schema)
- DEVC (Packages)
- DOMA (Domains)
- DRTY (CDS Type Definitions)
- DTEL (Data Elements)
- EVTB (Event Bindings)
- FUGR (Function Groups)
- INTF (Interfaces)
- MSAG (Message Classes)
- NONT (SAP Object Node Types)
- RONT (SAP Object Types)
- SRVB (Service Bindings)
- SRVD (Service Definitions)
- TABL (Structures, Database Tables and Global Temporary Tables)
- TTYP (Table Types)
- XSLT (Transformations)
The following kinds of operations are supported:
- POST Create the object according to a provided specification
- PUT Create or update the object according to a provided specification
- PATCH Update the object according to a provided specification
- DELETE Delete the object
The matrix below shows which kinds of operations are supported for which object types:
|      | PUT   | POST   | PATCH   | DELETE   |
|------|-------|--------|---------|----------|
| BDEF | X     |        |         | X        |
| CLAS | X     |        | X       | X        |
| DCLS | X     |        |         | X        |
| DDLS | X     |        |         | X        |
| DDLX | X     |        |         | X        |
| DESD | X     |        |         | X        |
| DEVC | X     |        |         | X        |
| DOMA | X     |        | X       | X        |
| DRTY | X     |        |         | X        |
| DTEL | X     |        | X       | X        |
| EVTB | X     |        | X       | X        |
| FUGR |       | X      | X       | X        |
| INTF | X     |        | X       | X        |
| MSAG | X     |        | X       | X        |
| NONT | X     |        | X       | X        |
| RONT | X     |        | X       | X        |
| SRVB | X     |        |         | X        |
|      | PUT   | POST   | PATCH   | DELETE   |
|------|-------|--------|---------|----------|
| SRVD | X     |        |         | X        |
| TABL | X     |        |         | X        |
| TTYP | X     |        |         | X        |
| XSLT | X     |        |         | X        |
## 4.2.15.16.3.3.3  Generation Error Handling
Each type of operation within the XCO Generation APIs defines its own exception class that can be used to deal with errors that were encountered during the execution of the operation:
- CX\_XCO\_GEN\_POST\_EXCEPTION for POST operations
- CX\_XCO\_GEN\_PUT\_EXCEPTION for PUT operations
- CX\_XCO\_GEN\_PATCH\_EXCEPTION for PATCH operations
- CX\_XCO\_GEN\_DELETE\_EXCEPTION for DELETE operations
The following code sample shows how the findings of a failed PUT operation can be extracted:
## 
```
Sample Code "! Code sample for handling errors of a PUT operation. "! "! IMPORTANT: The values of the constants CO_PACKAGE and CO_TRANSPORT must be replaced "! with an existing package and a modifiable Workbench transport matching the transport "! target of the package.
```
```
CLASS zcl_xco_doc_cp_cs_gen_error DEFINITION PUBLIC FINAL INHERITING FROM cl_xco_cp_adt_simple_classrun CREATE PUBLIC. PUBLIC SECTION. METHODS: constructor. PROTECTED SECTION. METHODS: main REDEFINITION. PRIVATE SECTION. CONSTANTS: co_package   TYPE sxco_package VALUE 'ZXCO_CP_PACKAGE', co_transport TYPE sxco_transport VALUE 'X08K900164', co_doma_name TYPE sxco_ad_object_name VALUE 'ZXCO_CP_NON_EXISTENT_DOMAIN', co_dtel_name TYPE sxco_ad_object_name VALUE 'ZXCO_CP_INVALID_DTEL', co_ttyp_name TYPE sxco_ad_object_name VALUE 'ZXCO_CP_INVALID_TTYP'. DATA: mo_environment TYPE REF TO if_xco_cp_gen_env_dev_system. ENDCLASS. CLASS zcl_xco_doc_cp_cs_gen_error IMPLEMENTATION. METHOD constructor. super->constructor( ). mo_environment = xco_cp_generation=>environment->dev_system( co_transport ). ENDMETHOD. METHOD main. DATA(lo_put_operation) = mo_environment->create_put_operation( ). " Add an invalid data element DATA(lo_dtel_specification) = lo_put_operation->for-dtel->add_object( co_dtel_name )->set_package( co_package )->create_form_specification( ). lo_dtel_specification->set_short_description( 'My data element' ). lo_dtel_specification->set_data_type( xco_cp_abap_dictionary=>domain( co_doma_name ) ). " Add an invalid table type DATA(lo_ttyp_specification) = lo_put_operation->for-ttyp->add_object( co_ttyp_name )->set_package( co_package )->create_form_specification( ). lo_ttyp_specification->set_short_description( 'My table type' ). lo_ttyp_specification->set_row_type( xco_cp_abap_dictionary=>data_element( co_dtel_name ) ). TRY. lo_put_operation->execute( ). CATCH cx_xco_gen_put_exception INTO DATA(lx_put_exception). " Get all findings. out->plain->write( |Findings:| ). out->write_news( lx_put_exception ). " Get only the TTYP findings. out->plain->write( |Table type findings:| ). out->write_news( lx_put_exception->findings->for->ttyp ). ENDTRY. ENDMETHOD. ENDCLASS.
```
## 4.2.15.16.3.3.4  Generating and Reading CDS Abstract Entities
The following code sample illustrates how abstract entities can be generated and read with the XCO Library:
```
"! <p class="shorttext synchronized" lang="EN"> "!  XCO Documentation CP: Abstract entities "! </p> "! "! Code sample for generating and reading CDS abstract entities. "! "! IMPORTANT: The values of the constants CO_PACKAGE and CO_TRANSPORT must be replaced "! with an existing package and a modifiable Workbench transport matching the transport "! target of the package. CLASS zcl_xco_doc_cp_cs_abs_ent DEFINITION PUBLIC FINAL INHERITING FROM cl_xco_cp_adt_simple_classrun CREATE PUBLIC. PUBLIC SECTION. METHODS: constructor. PROTECTED SECTION. METHODS: main REDEFINITION. PRIVATE SECTION. CONSTANTS: co_package              TYPE sxco_package VALUE 'ZXCO_CP_PACKAGE', co_transport            TYPE sxco_transport VALUE 'X08K900164', co_abstract_entity_name TYPE sxco_ao_object_name VALUE 'ZXCO_DEMO_PRODUCT'. DATA: mo_environment TYPE REF TO if_xco_cp_gen_env_dev_system. METHODS: put_ddls. ENDCLASS. CLASS zcl_xco_doc_cp_cs_abs_ent IMPLEMENTATION. METHOD constructor. super->constructor( ). mo_environment = xco_cp_generation=>environment->dev_system( co_transport ). ENDMETHOD. METHOD main. put_ddls( ). out->write( |PUT operation executed successfully.| ). DATA(lo_abstract_entity) = xco_cp_cds=>abstract_entity( co_abstract_entity_name ). DATA(ls_abstract_entity) = lo_abstract_entity->content( )->get( ). out->write( ls_abstract_entity ). LOOP AT lo_abstract_entity->fields->all->get( ) INTO DATA(lo_field). out->write( |Field { lo_field->name }:| ). DATA(ls_field) = lo_field->content( )->get( ). out->write( ls_field ). ENDLOOP. ENDMETHOD. METHOD put_ddls. DATA(lo_put_operation) = mo_environment->create_put_operation( ). DATA(lo_form_specification) = lo_put_operation->for-ddls->add_object( co_abstract_entity_name )->set_package( co_package )->create_form_specification( ). DATA(lo_abstract_entity) = lo_form_specification->set_short_description( 'Product' )->add_abstract_entity( ). DATA(lo_parameter) = lo_abstract_entity->add_parameter( 'p_language' )->set_data_type( xco_cp_abap_dictionary=>built_in_type->lang ). DATA(lo_id_field) = lo_abstract_entity->add_field( xco_cp_ddl=>field( 'ID' ) ).
```
```
lo_id_field->set_key( ). lo_id_field->set_type( xco_cp_abap_dictionary=>built_in_type->char( 30 ) ). lo_id_field->add_annotation( 'UI.lineItem' )->value->build( )->begin_array( )->begin_record( )->add_member( 'position' )->add_number( 1 )->add_member( 'label' )->add_string( 'Product' )->end_record( )->end_array( ). DATA(lo_description_field) = lo_abstract_entity->add_field( xco_cp_ddl=>field( 'description' ) ). lo_description_field->set_type( xco_cp_abap_dictionary=>built_in_type->char( 60 ) ). lo_description_field->add_annotation( 'UI.lineItem' )->value->build( )->begin_array( )->begin_record( )->add_member( 'position' )->add_number( 2 )->add_member( 'label' )->add_string( 'Description' )->end_record( )->end_array( ). lo_put_operation->execute( ). ENDMETHOD. ENDCLASS.
```
## 4.2.15.16.3.3.11  Updating the Source Code of a Function Module
The following code sample illustrates the source code of an already existing function module that can be updated:
## 
```
Sample Code "! Code sample for updating the source code of an existing function module.
```
```
"! "! IMPORTANT: The function module referred to by the constant CO_FUNCTION_MODULE_NAME needs to "! exist prior to executing this code sample and must not already be locked on a transport "! request. CLASS zcl_xco_doc_cp_cs_chg_fm DEFINITION PUBLIC FINAL INHERITING FROM cl_xco_cp_adt_simple_classrun CREATE PUBLIC. PUBLIC SECTION. METHODS: constructor. PROTECTED SECTION. METHODS: main REDEFINITION. PRIVATE SECTION. CONSTANTS: co_function_module_name TYPE sxco_fm_name VALUE 'ZMY_FUNCTION_MODULE'. DATA: mo_function_module TYPE REF TO if_xco_function_module. METHODS: generate_transport_request IMPORTING out                         TYPE REF TO if_xco_adt_classrun_out RETURNING VALUE(ro_transport_request) TYPE REF TO if_xco_cp_tr_request, release_transport_request IMPORTING io_transport_request TYPE REF TO if_xco_cp_tr_request out                  TYPE REF TO if_xco_adt_classrun_out. ENDCLASS. CLASS zcl_xco_doc_cp_cs_chg_fm IMPLEMENTATION. METHOD constructor. super->constructor( ). mo_function_module = xco_cp_abap=>function_module( co_function_module_name ). ENDMETHOD. METHOD main. DATA(lo_transport_request) = generate_transport_request( out ). DATA(lo_patch_operation) = xco_cp_generation=>environment->dev_system( lo_transport_request->value )->for-fugr->create_patch_operation( ). DATA(lo_function_group) = mo_function_module->get_function_group( ). lo_patch_operation->add_object( lo_function_group->name )->for-update->add_function_module( mo_function_module->name )->set_source_code( xco_cp=>strings( VALUE #( ( `  " New source code goes here...` ) ) ) ). lo_patch_operation->execute( ). release_transport_request( io_transport_request = lo_transport_request out                  = out ). ENDMETHOD. METHOD generate_transport_request. DATA(lo_transport_target) = mo_function_module->get_function_group(
```
```
)->if_xco_ar_object~get_package( )->read( )-property-transport_layer->get_transport_target( ). ro_transport_request = xco_cp_cts=>transports>workbench( lo_transport_target->value )->create_request( 'Generated transport request' ). out->write( |Using newly generated transport request { ro_transport_request->value }.| ). ENDMETHOD. METHOD release_transport_request. DATA(lt_tasks) = io_transport_request->get_tasks( ). LOOP AT lt_tasks INTO DATA(lo_task). lo_task->release( ). ENDLOOP. io_transport_request->release( ). out->write( |Transport request { io_transport_request->value } has been released.| ). ENDMETHOD. ENDCLASS.
```
## 4.2.15.16.3.3.13  Generating Transformations
The XCO Generation APIs offer support for PUT and DELETE operations for transformations (XSLT objects).
The first code sample below illustrates how a transformation can be generated via a PUT operation and directly invoked dynamically to extract data from a provided XML string as well as present data as XML (making use of XCO Standard Library functionality to conveniently translate between strings and xstrings based on UTF-8).
```
 Sample Code DATA(lv_transport_request) = CONV sxco_transport( '...' ). DATA(lv_transformation_name) = CONV sxco_tf_object_name( 'ZMY_TRANSFORMATION' ). DATA(lo_put_operation) = xco_cp_generation=>environment->dev_system( lv_transport_request )->create_put_operation( ). DATA(lo_specification) = lo_put_operation->for-xslt->add_object( lv_transformation_name )->set_package( 'Z_MY_PACKAGE' )->create_form_specification( ). lo_specification->set_short_description( 'Generated transformation' )->set_source( VALUE #( ( |<tt:transform xmlns:tt="http://www.sap.com/transformationtemplates">| ) ( |  <tt:root name="ROOT"/>| ) ( |  <tt:template>| ) ( |    <record>| ) ( |      <tt:attribute name="text" value-ref="root.text"/>| ) ( |    </record>| ) ( |  </tt:template>| ) ( |</tt:transform>| ) ) ). lo_put_operation->execute( ). " At this point a transformation with the name ZMY_TRANSFORMATION exists in the system in active " state.
```
```
TYPES: BEGIN OF ts_record, text TYPE string, END OF ts_record. DATA ls_record TYPE ts_record. " Using the generated transformation, it is now possible to dynamically apply it to provided XML " data. DATA(lv_xml_string) = |<?xml version="1.0" encoding="UTF-8"?><record text="Hello World"/>|. " Converts 'string' to 'xstring' using 'UTF-8' code page. DATA(lv_xml_xstring) = xco_cp=>string( lv_xml_string )->as_xstring( xco_cp_character=>code_page->utf_8 )->value. CALL TRANSFORMATION (lv_transformation_name) SOURCE XML lv_xml_xstring RESULT root = ls_record. " At this point the TEXT component of the structure LS_RECORD will have the value Hello World " In the same manner, an XML string can be also be obtained from the ABAP data object. ls_record-text = 'Hello XCO'. CALL TRANSFORMATION (lv_transformation_name) SOURCE root = ls_record RESULT XML lv_xml_xstring. " Converts 'xstring' to 'string' using 'UTF-8' code page. lv_xml_string = xco_cp=>xstring( lv_xml_xstring )->as_string( xco_cp_character=>code_page->utf_8 )->value. " Now the variable LV_XML_STRING will have the value <?xml version="1.0" encoding="UTF-8"?><record text="Hello XCO"/>.
```
Just as with other object types, transformations can also be deleted:
##  Sample Code
```
DATA(lv_transport_request) = CONV sxco_transport( '...' ). DATA(lv_transformation_name) = CONV sxco_tf_object_name( 'ZMY_TRANSFORMATION' ). DATA(lo_delete_operation) = xco_cp_generation=>environment->dev_system( lv_transport_request )->for-xslt->create_delete_operation( ). lo_delete_operation->add_object( lv_transformation_name ). lo_delete_operation->execute( ).
```
## 4.2.15.16.3.3.14  Changing the Content of Existing Domains
Using PATCH operations, it's possible to change the content of an existing domain. The following changes can be specified:
- Changes to header-level properties, such as the format of a domain or its output length
- Insertions, updates, or deletions of fixed values
The code sample below illustrates how the following changes can be performed with a single PATCH operation:
- Update the short description, case-sensitive indicator, and output style
- Update an existing fixed value
- Delete an existing fixed value
- Insert a new fixed value
##  Sample Code
```
DATA(lv_transport) = CONV sxco_transport( '...' ). DATA(lv_domain_name) = CONV sxco_ad_object_name( 'MY_DOMAIN' ). DATA(lo_patch_operation) = xco_cp_generation=>environment->dev_system( lv_transport )->for-doma->create_patch_operation( ). DATA(lo_change_specification) = lo_patch_operation->add_object( lv_domain_name )->create_change_specification( ). " Change header-level properties. lo_change_specification->for-update->set_short_description( 'My new short description' )->set_case_sensitive( abap_true )->set_output_style( xco_cp_domain=>output_style->normal ). " Update the description of fixed value "A". lo_change_specification->for-update->add_fixed_value( 'A' )->set_description( 'Fixed Value A' ). " Delete fixed value "B". lo_change_specification->for-delete->add_fixed_value( 'B' ). " Insert fixed value "C". lo_change_specification->for-insert->add_fixed_value( 'C' )->set_description( 'Fixed Value C' ). lo_patch_operation->execute( ).
```
## 4.2.15.16.3.3.15  Changing the Content of Existing Data Elements
Using PATCH operations, it's possible to change the content of an existing data element. The following changes can be specified:
- Changes to header-level properties, such as the data type or the field labels
The code sample below illustrates how the following changes can be performed with a single PATCH operation:
- Update the short description
- Update the data type
- Update the short field label
```
 Sample Code DATA(lv_transport) = CONV sxco_transport( '...' ). DATA(lv_data_element_name) = CONV sxco_ad_object_name( 'MY_DATA_ELEMENT' ). DATA(lo_patch_operation) = xco_cp_generation=>environment->dev_system( lv_transport )->for-dtel->create_patch_operation( ). DATA(lo_change_specification) = lo_patch_operation->add_object( lv_data_element_name )->create_change_specification( ). " Change header-level properties. lo_change_specification->for-update->set_short_description( 'My new short description' )->set_data_type( xco_cp_abap_dictionary=>built_in_type->int4 )->field_label-short->set_text( 'Sh. FL' )->set_length( 10 ). lo_patch_operation->execute( ).
```
## 4.2.15.16.3.3.16  Generating CDS Type Definitions
The following code sample illustrates how you can generate a CDS simple type with the XCO library by means of running a PUT operation:
```
 Sample Code DATA(lo_put_operation) = xco_cp_generation=>environment->dev_system( '$TRANSPORT_REQUEST$' )->create_put_operation( ). DATA(lo_form_specifation) = lo_put_operation->for-drty->add_object( 'ZMY_CDS_TYPE_DEFINITION' )->set_package( 'ZMY_PACKAGE' )->create_form_specification( ). lo_form_specifation->set_short_description( 'Generated CDS Type Definition' ). DATA(lo_simple_type_definition) = lo_form_specifation->add_simple_type_definition( ). lo_simple_type_definition->add_annotation( 'EndUserText.label' )->value>build( )->add_string( 'My CDS type definition' ). lo_simple_type_definition->set_type( xco_cp_abap_dictionary=>built_in_type->char( 10 ) ). lo_put_operation->execute( ).
```
Running this PUT operation will produce the CDS type definition ZMY\_CDS\_TYPE\_DEFINITION with the following source:
## 
```
Sample Code @EndUserText.label: 'My CDS type definition' define type  ZMY_CDS_TYPE_DEFINITION : abap.char( 10 )
```
In general, the following objects are eligible to be used as the type for a simple type definition:
- ABAP dictionary built-in type (objects of type CL\_XCO\_AD\_BUILT\_IN\_TYPE )
- Data elements (objects of type IF\_XCO\_AD\_DATA\_ELEMENT )
- CDS type definitions (objects of type IF\_XCO\_CDS\_TYPE\_DEFINITION )
CDS type definitions can also be deleted again, as is illustrated by the following code sample:
## 
```
Sample Code DATA(lo_delete_operation) = xco_cp_generation=>environment->dev_system( '$TRANSPORT_REQUEST$' )->for-drty->create_delete_operation( ). lo_delete_operation->add_object( 'ZMY_CDS_TYPE_DEFINITION' ). lo_delete_operation->execute( ).
```
## 4.2.15.16.3.3.17  Patching Structures and Database Tables
Using PATCH operations, it's possible to change the content of an existing structure or database table. The following changes can be specified:
- Choose to update the type and/or the currency and/or the quantity information of an existing database table field or structure component
- Update of the structure of an existing include of a database table or a structure
The following code sample illustrates how the changes described above can be applied to an existing database table:
```
 Sample Code DATA(lv_transport) = CONV sxco_transport( '...' ). DATA(lv_database_table_name) = CONV sxco_dbt_object_name( 'ZMY_DBT' ). DATA(lo_patch_operation) = xco_cp_generation=>environment->dev_system( lv_transport )->create_patch_operation( ). DATA(lo_change_specification) = lo_patch_operation->for-tabl-for-database_table->add_object( lv_database_table_name )->create_change_specification( ). " Update the type of field DATA_FIELD to abap.char( 10 ) lo_change_specification->for-update->add_field( 'DATA_FIELD' )->set_type( xco_cp_abap_dictionary=>built_in_type->char( 10 ) ). " Update the currency/quantity reference information for field CURR_QUAN lo_change_specification->for-update->add_field( 'CURR_QUAN' )->currency_quantity->set_reference_table( 'ZMY_REF_TABLE' )->set_reference_field( 'ZMY_REF_FIELD' ).
```
```
" Update the structure that is used for the first include of the " database table. lo_change_specification->for-update->add_include( 1 )->set_structure( 'ZMY_INCL_STR' ). lo_patch_operation->execute( ).
```
The same changes could also be applied to an existing structure by adding a structure to the PATCH operation created above:
```
 Sample Code lo_patch_operation->for-tabl-for-structure->add_object( 'ZMY_STRUCTURE' ).
```
Note that the PATCH operation obtained via
XCO\_CP\_GENERATION=&gt;ENVIRONMENT → DEV\_SYSTEM( LV\_TRANSPORT ) → CREATE\_PATCH\_OPERATION( ) is a mass-enabled operation which can contain several objects at once. Upon execution, first, the specified changes will be applied to all objects that have been added to the PATCH operation, and afterwards, all objects will be activated together in a single mass activation. Currently, the following object types are enabled for mass PATCH operations:
- DOMA (Domains)
- DTEL (Data Elements)
- TABL (Database Tables and Structures)
## 4.2.15.16.3.3.18  Generating CDS External Entities
The following code sample shows how you can generate a CDS external entity with the XCO library by running a PUT operation:
```
 Sample Code DATA(lo_put_operation) = xco_cp_generation=>environment->dev_system( '$TRANSPORT_REQUEST$' )->create_put_operation( ). DATA(lo_form_specification) = lo_put_operation->for-ddls->add_object( 'ZMY_CDS_EXT_ENTITY' )->set_package( 'ZMY_PACKAGE' )->create_form_specification( ). DATA(lo_external_entity) = lo_form_specification->set_short_description( 'Generated CDS External Entity' )->add_external_entity( ). lo_external_entity->set_with_federated_data( )->set_dynamic_access( )->set_on_unlinked_fail( ). lo_external_entity->add_annotation( 'EndUserText.label' ##NO_TEXT )->value->build( )->add_string( 'My external entity' ). lo_external_entity->data_source->set_remote_object_name( 'My remote object name' ).
```
```
lo_external_entity->add_field( xco_cp_ddl=>field( 'key_field' ) )->set_key( )->set_type( xco_cp_abap_dictionary=>built_in_type->int1 ). lo_external_entity->add_field( xco_cp_ddl=>field( 'field' ) )->set_type( xco_cp_abap_dictionary=>built_in_type->char( 10 ) )->set_external_name( 'My field external name' ). lo_put_operation->execute( ).
```
Running this PUT operation will produce the CDS external entity ZMY\_CDS\_EXT\_ENTITY with the following source:
```
 Sample Code @EndUserText.label: 'My external entity' define external entity ZMY_CDS_EXT_ENTITY external name "My remote object name" { key key_field : abap.int1; field : abap.char(10) external name "My field external name"; } WITH FEDERATED DATA PROVIDED AT RUNTIME ON UNLINKED FAIL
```
To connect to an external system, you will also need a logical external schema. It can be generated like this:
##  Sample Code
```
DATA(lo_put_operation) = xco_cp_generation=>environment->dev_system( '$TRANSPORT_REQUEST$' )->create_put_operation( ). DATA(lo_form_specification) = lo_put_operation->for-desd->add_object( 'ZMY_LOGICAL_EXT_SCHEMA' )->set_package( 'ZMY_PACKAGE' )->create_form_specification( ). lo_form_specification->set_short_description( 'Generated Logical External Schema' )->set_default_remote_schema_name( 'My Schema Name' ). lo_put_operation->execute( ).
```
## Related Information
CDS External Entities
## 4.2.15.16.3.5  API Release Framework
Find out how to set the API state.
Setting and getting API states programmatically is supported for the following objects:
- Classes (IF\_XCO\_AO\_CLASS)
- Entities of data definitions (IF\_XCO\_CDS\_ENTITY)
- Domains (IF\_XCO\_DOMAIN)
- Data elements (IF\_XCO\_AD\_DATA\_ELEMENT)
- Function modules of function groups (IF\_XCO\_FUNCTION\_MODULE)
- Interfaces (IF\_XCO\_AO\_INTERFACE)
- Structures (IF\_XCO\_AD\_STRUCTURE)
- Database tables (IF\_XCO\_DATABASE\_TABLE)
- Table types (IF\_XCO\_AD\_TABLE\_TYPE)
- Transformations (IF\_XCO\_TRANSFORMATION)
Each of the above interfaces defines the two methods SET\_API\_STATE and GET\_API\_STATE to programmatically set or get the API state of the represented object. For data elements, for example, this looks like:
```
 Sample Code DATA(lo_transport) = xco_cp_cts=>transport->for( '...' ). DATA(lo_api_state) = xco_cp_ars=>api_state->released( VALUE #( ( xco_cp_ars=>visibility->sap_cloud_platform ) ) ). DATA(lo_data_element) = xco_cp_abap_repository=>object->dtel>for( 'ZMY_DATA_ELEMENT' ). lo_data_element->set_api_state( io_change_scenario = lo_transport io_api_state       = lo_api_state
```
## 4.2.15.16.3.8  Object Type References
## 4.2.15.16.3.9  Miscellaneous Code Samples
## 4.2.15.16.3.9.1  Getting the Text Table of a Database Table
The XCO standard abstraction for database tables ( IF\_XCO\_DATABASE\_TABLE ) provides a convenient way to determine the text table of a given database table (if it has one):
```
 Sample Code DATA(lo_database_table) = xco_cp_abap_dictionary=>database_table( 'ZMY_DBT' ). " From a database table handle (in this case LO_DATABASE_TABLE) we can obtain " the handle for its text table. DATA(lo_text_table) = lo_database_table->text_table( ). " Using this text table handle, we can first check if a text table exists at all " (for the previously fixed database table) and if so, obtain information about " it. DATA(lv_text_table_exists) = lo_text_table->exists( ). IF lv_text_table_exists EQ abap_true. " The name of the text table that belongs to database table ZMY_DBT. DATA(lv_text_table_name) = lo_text_table->get( )->name. " We can also use the text table handle to get the name of the check field of the " database table/text table relationship. DATA(lv_check_field_name) = lo_text_table->get_check_field( )->name. ENDIF.
```
## 4.2.15.16.3.9.2  Retrieving a List of All Classes Implementing an Interface
The standard abstraction provided by the XCO library for ABAP interfaces ( IF\_XCO\_AO\_INTERFACE ) can be used to retrieve a list of all implementations of a given interface:
```
 Sample Code DATA(lo_interface) = xco_cp_abap=>interface( 'ZMY_INTERFACE' ). " From an interface handle (in this case LO_INTERFACE) we can easily obtain " access to its implementations via the IMPLEMENTATIONS data member. Obtaining " a list of all implementations for an interface can be accomplished like this: DATA(lt_implementations) = lo_interface->implementations->all->get( ). " Once the previous statement has been executed, LT_IMPLEMENTATIONS will be a " table of IF_XCO_AO_CLASS objects which can then subsequently be used to e.g. " read the content of each class. Note that only those implementations will be " considered which are either C1-released or part of a customer software component. " Additionally, if only the names of the classes implementing the interface
```
```
" shall be obtained the following statement can be used: DATA(lt_implementation_names) = lo_interface->implementations->all->get_names( ).
```
## 4.2.15.16.3.9.3  Retrieving a List of all Subclasses of a Given Class
Find out how to retrieve a list of all subclasses of a given class.
The standard abstraction provided by the XCO library for ABAP classes ( IF\_XCO\_AO\_CLASS ) can be used to retrieve a list of all subclasses (including both direct and indirect subclasses) of a given class:
```
 Sample Code DATA(lo_class) = xco_cp_abap=>class( 'ZMY_CLASS' ). " From a class handle (in this case LO_CLASS) we can easily obtain access to " its subclasses via the SUBCLASSES data member. Accessing all subclasses " via SUBCLASSES->ALL will resolve the subclasses of the class recursively " along the inheritance tree, i.e. all subclasses including subclasses of " subclasses and so forth will be included. DATA(lt_subclasses) = lo_class->subclasses->all->get( ). " Once the previous statement has been executed, LT_SUBCLASSES will be a " table of IF_XCO_AO_CLASS objects which can then subsequently be used to " e.g. read the content of each class. Furthremore, note that only those " subclasses will be considered which are either C1-released or part of a " customer software component. If only the names of the subclasses shall be " obtained, the following variation can be used: DATA(lt_subclass_names) = lo_class->subclasses->all->get_names( ).
```
## 4.2.15.16.4.1  ADT
By having a class implement the interface IF\_OO\_ADT\_CLASSRUN it is possible to easily write programs that can be run directly within ADT using the console as output.
The XCO library provides an abstract implementation of this interface via CL\_XCO\_CP\_ADT\_SIMPLE\_CLASSRUN that exposes all the original functionality of IF\_OO\_ADT\_CLASSRUN but adds several additional functionalities that enable a natural integration of XCO library abstractions with
ADT classruns.
The following sample class illustrates how the OUT object provided by CL\_XCO\_CP\_ADT\_SIMPL\_CLASSRUN can be used to flexibly write complex data structures or even object references to the console. Using the interface IF\_XCO\_PRINTABLE any object can define a text that is used when the object is written to the console.
```
 Sample Code CLASS zcl_xco_doc_cp_std_adt DEFINITION PUBLIC FINAL INHERITING FROM cl_xco_cp_adt_simple_classrun CREATE PUBLIC. PROTECTED SECTION. METHODS: main REDEFINITION. ENDCLASS. CLASS zcl_xco_doc_cp_std_adt IMPLEMENTATION. METHOD main. TYPES: BEGIN OF ts_address, street       TYPE string, house_number TYPE n LENGTH 2, postal_code  TYPE n LENGTH 5, city         TYPE string, END OF ts_address, BEGIN OF ts_member, first_name TYPE string, last_name  TYPE string, address    TYPE ts_address, END OF ts_member, tt_member TYPE STANDARD TABLE OF ts_member WITH EMPTY KEY. " Print a JSON-style serialization (works for arbitrarily deep data structures) DATA(lt_members) = VALUE tt_member( ( first_name = 'John' last_name = 'Doe' address = VALUE #( street = 'Main street' house_number = 12 postal_code = 12345 city = 'City' ) ) ). " Will print: [{FIRST_NAME: John, LAST_NAME: Doe, ADDRESS: {STREET: Main street, HOUSE_NUMBER: 12, POSTAL_CODE: 12345, CITY: City}}] out->write( lt_members ). " IF_XCO_PRINTABLE example: Will print "WARNING" out->write( xco_cp_message=>type->warning ). " IF_XCO_PRINTABLE example: Will print "Field MY_FIELD of View entity MY_VIEW_ENTITY" DATA(lo_field) = xco_cp_cds=>view_entity( 'MY_VIEW_ENTITY' )->field( 'MY_FIELD' ). out->write( lo_field ). ENDMETHOD.
```
## ENDCLASS.
On top of the rich console writing functionalities, any NO\_CHECK exception that is not caught by the MAIN method of a class implementing CL\_XCO\_CP\_ADT\_SIMPLE\_CLASSRUN will be caught and written to the console with maximum information. This includes the raise position, messages and even the stack trace if the exception is carrying one (cf. explanation of CX\_XCO\_RUNTIME\_EXCEPTION above).
## 4.2.15.16.4.5  Regular Expression
Regular expressions can be used to match strings against patterns or extract substrings that match certain criteria.
The regular expression engines offered by XCO are based on the standards offered by CL\_ABAP\_REGEX:
- POSIX
- PCRE
- XPATH2
- XSD
In XCO, these regular expression standards are encapsulated in the IF\_XCO\_REGEX\_ENGINE abstraction which is accessible via the XCO\_CP\_REGULAR\_EXPRESSION API:
```
 Sample Code " Example for a POSIX regular expression engine (More configuration options are available " as optional parameters of the method POSIX). DATA(lo_posix_engine) = xco_cp_regular_expression=>engine->posix( iv_ignore_case = abap_true ). " Example for a PCRE regular expression engine (More configuration options are available " as optional parameters of the method PCRE). DATA(lo_pcre_engine) = xco_cp_regular_expression=>engine->pcre( iv_ignore_case      = abap_false iv_enable_multiline = abap_false ). " Example for an XPATH 2.0 regular expression engine (More configuration options are available " as optional parameters of the method XPATH2). DATA(lo_xpath2_engine) = xco_cp_regular_expression=>engine->xpath2( iv_ignore_case      = abap_true iv_enable_multiline = abap_false ). " Example for an XSD regular expression engine (More configuration options are available " as optional parameters of the method XSD). DATA(lo_xsd_engine) = xco_cp_regular_expression=>engine->xsd( iv_ignore_case      = abap_true iv_enable_multiline = abap_false
```
).
The parameters of the regular expression engine factory methods can be used to configure the behavior of the engine when it is used against a string. The default engine (which is used when no explicit engine is supplied) is POSIX in the default configuration as provided by CL\_ABAP\_REGEX.
A regular expression can be used to easily check if a given string matches a pattern
##  Sample Code
```
" LV_CASE_INSENSITIVE_MATCHES will have the value abap_true as " LO_POSIX_ENGINE is case insensitive (see above). DATA(lv_case_insensitive_matches) = xco_cp=>string( |abc| )->matches( iv_regular_expression = '^a.*C$' io_engine             = lo_posix_engine ). " LV_CASE_SENSITIVE_MATCHES will have the value abap_false as the " default POSIX engine is case sensitive. DATA(lv_case_sensitive_matches) = xco_cp=>string( |abc| )>matches( '^a.*C$' ).
```
or to retrieve certain parts from it
##  Sample Code
```
DATA(lo_name_parts) = xco_cp=>string( |John Doe| )->grep( '^(\S+)\s+(\S+)$' ). " LV_FIRST_NAME = John DATA(lv_first_name) = lo_name_parts->value[ 1 ]. " LV_LAST_NAME = Doe DATA(lv_last_name) = lo_name_parts->value[ 2 ].
```
## 4.2.15.16.4.7  System
With the XCO system module, you can easily request information about the current system.
## Namespaces
You can get a handle for a given namespace via the API XCO\_CP\_SYSTEM=&gt;NAMESPACE . Once obtained, you can use a namespace handle to find out whether the given namespace exists in the system and, if so, whether it's changeable:
## 
```
Sample Code " LO_NAMESPACE is a handle that can be used to request information " about namespace /ABC/. DATA(lo_namespace) = xco_cp_system=>namespace->for( '/ABC/' ).
```
```
" LV_NAMESPACE is an ABAP_BOOL value indicating whether the namespace " represented by LO_NAMESPACE exists or not. DATA(lv_namespace_exists) = lo_namespace->exists( ). " LV_NAMESPACE_IS_CHANGEABLE is an ABAP_BOOL value indicating whether the " namespace represented by LO_NAMESPACE is changeable or not. Note that, " before invoking this method, it should be ensured that the namespace exists " as otherwise a runtime exception will be raised. DATA(lv_namespace_is_changeable) = lo_namespace->is_changeable( ).
```
## 4.2.15.16.4.8  Tenant
The XCO tenant module provides standard abstractions for querying information about tenants, in particular the tenant associated with the current ABAP session.
The central abstraction IF\_XCO\_CP\_TENANT represents a tenant and is used to retrieve its public information. As of now, the following information can be retrieved:
- ID: The ID for the tenant
- GUID: The GUID for the tenant (represented as an IF\_XCO\_UUID)
- URL: The URL of the tenant for the given URL type (URL types are available via XCO\_CP\_TENANT=&gt;URL\_TYPE)
- Global Account ID: The ID of the global account associated with the tenant
- Subaccount ID: The ID of the subaccount associated with the tenant
The currently active tenant can be obtained via:
```
DATA(lo_current_tenant) = xco_cp=>current->tenant( ).
```
Note that depending on the overall system infrastructure and setup a current tenant doesn't necessarily exist, which would be indicated by an initial reference returned by the statement above. Once the current tenant has been obtained by the URL (in the example below for the type UI) along with its different components, the currently active tenant can be obtained as follows:
```
 Sample Code " UI URL of the current tenant. DATA(lo_ui_url) = lo_current_tenant->get_url( xco_cp_tenant=>url_type->ui ). " The protocol of the UI URL (Type string). DATA(lv_ui_url_protocol) = lo_ui_url->get_protocol( ). " The host (including the domain) of the UI URL (Type string). DATA(lv_ui_url_host) = lo_ui_url->get_host( ). " The port of the UI URL (Type i). DATA(lv_ui_url_port) = lo_ui_url->get_port( ).
```
In a similar way it's also possible to access the information about the associated global account and subaccount:
## 
```
Sample Code " The string value of the global account ID of the current tenant. DATA(lv_global_account_id) = lo_current_tenant->get_global_account_id( )->as_string( ). " The string value of the subaccount ID of the current tenant. DATA(lv_subaccount_id) = lo_current_tenant->get_subaccount_id( )->as_string( ).
```
## 4.2.15.16.4.10  UUID
To effectively work with UUIDs the XCO standard library provides a simple way to translate between different UUID formats:
```
 Sample Code DATA(lo_uuid) = xco_cp_uuid=>format->c36->to_uuid( '7cd44fff-036a-4155-b0d2f5a4dfbcee92' ). " LV_UUID_C32 will hold the value 7CD44FFF036A4155B0D2F5A4DFBCEE92 DATA(lv_uuid_c32) =  CONV sysuuid_c32( xco_cp_uuid=>format->c32->from_uuid( lo_uuid ) ).
```
## 4.2.15.16.4.12  XString
To offer a convenient way to incorporate standard operations on binary data into application logic, the XCO Library provides a standard abstraction for xstrings, IF\_XCO\_XSTRING , that is tightly integrated with the XCO string abstraction IF\_XCO\_STRING .
## Using the Base64 binary-to-text encoding
Built-in conversions are provided to support working with the Base64 binary-to-text encoding. Encoding raw binary data to its Base64 representation and decoding a given Base64 representation to its underlying binary data can be accomplished as follows:
```
 Sample Code " LV_XSTRING can store arbitrary binary data. DATA lv_xstring TYPE xstring. " LV_BASE64_ENCODING is of type STRING and contains the Base64 encoded version " of LV_XSTRING. DATA(lv_base64_encoding) = xco_cp=>xstring( lv_xstring )->as_string( xco_cp_binary=>text_encoding->base64 )->value. " LV_ORIGINAL_XSTRING is of type XSTRING and contains the binary data encoded " in LV_BASE64_ENCODING DATA(lv_original_xstring) = xco_cp=>string( lv_base64_encoding )->as_xstring( xco_cp_binary=>text_encoding->base64 )->value.
```
## Using code pages
An xstring can also be converted to a string by using a code page, e.g. UTF-8:
```
 Sample Code DATA(lv_string) = xco_cp=>xstring( lv_xstring )->as_string( xco_cp_character=>code_page->utf_8 )->value.
```
## 4.2.15.17  Metric Providers
The following objects were released for use in the ABAP environment:
| Object                  | Description                                                  |
|-------------------------|--------------------------------------------------------------|
| CL_GSM_API_TEST         | Convenience class to test the metric provider implementation |
| CX_GSM_API              | Metric provider exception class                              |
| IF_GSM_API_CONSTANTS    | Interface for metric provider constants                      |
| IF_GSM_API_METRIC       | Interface for metric definition                              |
| IF_GSM_API_METRIC_GROUP | Interface for metric group definition                        |
| IF_GSM_API_MODEL        | Interface for metric provider model definition               |
| IF_GSM_API_PROVIDER     | Interface for metric provider definition                     |
| IF_GSM_API_TEST         | Interface for metric provider testing                        |
| IF_GSM_API_TYPES        | Interface for metric provider type definitions               |
These objects are all related to the ABAP repository object called metric provider. You use metric providers as well as these released objects in ABAP Development Tools when you want to create your own metrics for health monitoring of the ABAP system.
## Related Information
Developing Metrics for Health Monitoring [page 1108]
## 4.2.15.18  Integration to SAP BTP Services
Integrating SAP Document Management Service [page 2998]
Proxy API for SAP Build Process Automation [page 1556]