Skip to content

Instantly share code, notes, and snippets.

@mbtools
Created April 22, 2025 09:02
Show Gist options
  • Save mbtools/160545159155e044a03479ee44676867 to your computer and use it in GitHub Desktop.
Save mbtools/160545159155e044a03479ee44676867 to your computer and use it in GitHub Desktop.
Basic concept for BOBF implementation (abapGit v1.131.0)
* This is an *untested and incomplete* implementation for supporting Business Object Models in abapGit
* It's based on https://github.com/abapGit/abapGit/issues/165
* The syntax works with the developer version of abapGit v1.131.0 and SAP Basis 7.50 or higher
*
* To add this to core abapGit, the following todos must be completed:
* - Syntax downport to 7.02
* - Replace all /BOPF/* classes and DDIC with dynamic ABAP (they don't exist in 7.02)
* - Add error handling (evaluate EO_MESSAGE of BOPF calls)
* - Add test case to https://github.com/abapGit-tests
CLASS zcl_abapgit_object_bobf DEFINITION
PUBLIC
INHERITING FROM zcl_abapgit_objects_super
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PROTECTED SECTION.
PRIVATE SECTION.
CONSTANTS c_xml_element_model TYPE string VALUE 'MODEL'.
METHODS get_conf_model_api
RETURNING
VALUE(ro_api) TYPE REF TO /bobf/cl_conf_model_api_adt
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_bobf IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_ABAPGIT_OBJECT_BOBF->GET_CONF_MODEL_API
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RO_API TYPE REF TO /BOBF/CL_CONF_MODEL_API_ADT
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD get_conf_model_api.
ro_api = NEW /bobf/cl_conf_model_api_adt( iv_package = ms_item-devclass ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~CHANGED_BY
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_EXTRA TYPE STRING(optional)
* | [<-()] RV_USER TYPE SYUNAME
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~DELETE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_PACKAGE TYPE DEVCLASS
* | [--->] IV_TRANSPORT TYPE TRKORR
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~delete.
get_conf_model_api( )->delete_business_object(
EXPORTING
iv_business_object_name = CONV #( ms_item )
IMPORTING
eo_message = DATA(lo_message)
ev_success = DATA(lv_success) ).
IF lv_success EQ abap_false.
zcx_abapgit_exception=>raise( 'Error deleting object' ).
ENDIF.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~DESERIALIZE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_PACKAGE TYPE DEVCLASS
* | [--->] IO_XML TYPE REF TO ZIF_ABAPGIT_XML_INPUT
* | [--->] IV_STEP TYPE ZIF_ABAPGIT_OBJECTS=>TY_DESERIALIZATION_STEP
* | [--->] II_LOG TYPE REF TO ZIF_ABAPGIT_LOG
* | [--->] IV_TRANSPORT TYPE TRKORR
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~deserialize.
DATA ls_model TYPE /bobf/s_conf_model_adt_bo.
io_xml->read( EXPORTING iv_name = c_xml_element_model
CHANGING cg_data = ls_model ).
DATA(lo_api) = get_conf_model_api( ).
LOOP AT ls_model-nodes ASSIGNING FIELD-SYMBOL(<ls_root_node>) WHERE node-parent_node_key IS INITIAL.
EXIT.
ENDLOOP.
ASSERT <ls_root_node> IS NOT INITIAL.
lo_api->create_business_object(
EXPORTING
iv_business_object_name = ls_model-header-bo_name
iv_description = ls_model-header-description
iv_constant_interface = ls_model-header-const_interface
iv_root_name = CONV #( <ls_root_node>-node-node_name )
iv_root_description = <ls_root_node>-node-description
iv_root_data_type = <ls_root_node>-node-data_type
iv_root_data_data_type = <ls_root_node>-node-data_data_type
iv_root_data_data_type_t = <ls_root_node>-node-data_data_type_t
iv_root_data_table_type = <ls_root_node>-node-data_table_type
iv_root_database_table = <ls_root_node>-node-database_table
IMPORTING
ev_bo_key = ls_model-header-bo_key
ev_version_key = DATA(lv_version_key)
ev_success = DATA(lv_bo_created) ).
* This generated a root node. Now we need to replace the node key of the root node imported with the one created
lo_api->get_business_object(
EXPORTING
iv_business_object_name = ls_model-header-bo_name
IMPORTING
es_business_object = DATA(ls_just_created_model) ).
ASSERT lines( ls_just_created_model-nodes ) = 1.
DATA(ls_new_root_node) = ls_just_created_model-nodes[ 1 ].
DELETE ls_model-nodes WHERE node-node_key = <ls_root_node>-node-node_key.
LOOP AT ls_model-nodes ASSIGNING FIELD-SYMBOL(<ls_node>).
<ls_node>-node-parent_node_key = ls_new_root_node-node-node_key.
ENDLOOP.
INSERT ls_new_root_node INTO TABLE ls_model-nodes.
* also, we need to "move" all model elements below the just created version node
* TODO!
lo_api->update_business_object(
EXPORTING
is_business_object = ls_model
* iv_update_active_version = ABAP_FALSE
* iv_cleanup_transaction = ABAP_TRUE
* iv_write_generation_info = " Categories of writing generation infos
IMPORTING
eo_message = DATA(lo_message)
ev_success = DATA(lv_model_imported)
et_modification = DATA(lt_mod) ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~EXISTS
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RV_BOOL TYPE ABAP_BOOL
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~exists.
get_conf_model_api( )->get_business_object(
EXPORTING
iv_business_object_name = CONV #( ms_item-obj_name )
iv_header_only = abap_true
IMPORTING
ev_success = rv_bool ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~GET_COMPARATOR
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RI_COMPARATOR TYPE REF TO ZIF_ABAPGIT_COMPARATOR
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~get_comparator.
RETURN.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~GET_DESERIALIZE_ORDER
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_ALL_OBJECTS TYPE ZIF_ABAPGIT_DEFINITIONS=>TY_ITEMS_TT
* | [<-()] RT_OBJECTS_BEFORE TYPE ZIF_ABAPGIT_DEFINITIONS=>TY_ITEMS_TT
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~get_deserialize_order.
RETURN.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~GET_DESERIALIZE_STEPS
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RT_STEPS TYPE ZIF_ABAPGIT_OBJECTS=>TY_DESERIALIZATION_STEP_TT
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~get_deserialize_steps.
APPEND zif_abapgit_object=>gc_step_id-abap TO rt_steps.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~GET_METADATA
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RS_METADATA TYPE ZIF_ABAPGIT_DEFINITIONS=>TY_METADATA
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~IS_ACTIVE
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RV_ACTIVE TYPE ABAP_BOOL
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~is_active.
rv_active = is_active( ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~IS_LOCKED
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RV_IS_LOCKED TYPE ABAP_BOOL
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~JUMP
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_EXTRA TYPE STRING(optional)
* | [<-()] RV_EXIT TYPE ABAP_BOOL
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~jump.
RETURN.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_ABAPGIT_OBJECT_BOBF=>ZIF_ABAPGIT_OBJECT~MAP_FILENAME_TO_OBJECT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_FILENAME TYPE STRING
* | [--->] IV_PATH TYPE STRING(optional)
* | [--->] IO_DOT TYPE REF TO ZCL_ABAPGIT_DOT_ABAPGIT(optional)
* | [--->] IV_PACKAGE TYPE DEVCLASS(optional)
* | [<-->] CS_ITEM TYPE ZIF_ABAPGIT_DEFINITIONS=>TY_ITEM
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~map_filename_to_object.
RETURN.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_ABAPGIT_OBJECT_BOBF=>ZIF_ABAPGIT_OBJECT~MAP_OBJECT_TO_FILENAME
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_ITEM TYPE ZIF_ABAPGIT_DEFINITIONS=>TY_ITEM
* | [--->] IV_EXT TYPE STRING
* | [--->] IV_EXTRA TYPE CLIKE
* | [<-->] CV_FILENAME TYPE STRING
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~map_object_to_filename.
RETURN.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ABAPGIT_OBJECT_BOBF->ZIF_ABAPGIT_OBJECT~SERIALIZE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_XML TYPE REF TO ZIF_ABAPGIT_XML_OUTPUT
* | [!CX!] ZCX_ABAPGIT_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD zif_abapgit_object~serialize.
get_conf_model_api( )->get_business_object(
EXPORTING
iv_business_object_name = CONV #( ms_item-obj_name )
IMPORTING
es_business_object = DATA(ls_model) ).
io_xml->add( iv_name = c_xml_element_model
ig_data = ls_model ).
ENDMETHOD.
ENDCLASS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment