CLASS zcl_abapgit_object_ecatt_super DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super ABSTRACT CREATE PUBLIC . PUBLIC SECTION. INTERFACES zif_abapgit_object . METHODS constructor IMPORTING !is_item TYPE zif_abapgit_definitions=>ty_item !iv_language TYPE spras !io_files TYPE REF TO zcl_abapgit_objects_files OPTIONAL !io_i18n_params TYPE REF TO zcl_abapgit_i18n_params OPTIONAL RAISING zcx_abapgit_exception. PROTECTED SECTION. METHODS: get_object_type ABSTRACT RETURNING VALUE(rv_object_type) TYPE etobj_type, get_upload ABSTRACT RETURNING VALUE(ro_upload) TYPE REF TO cl_apl_ecatt_upload, get_download ABSTRACT RETURNING VALUE(ro_download) TYPE REF TO cl_apl_ecatt_download, get_lock_object ABSTRACT RETURNING VALUE(rv_lock_object) TYPE eqeobj. PRIVATE SECTION. TYPES: BEGIN OF ty_last_changed, luser TYPE syuname, ldate TYPE d, ltime TYPE t, END OF ty_last_changed. CONSTANTS: BEGIN OF c_name, version TYPE string VALUE 'VERSION' ##NO_TEXT, versions TYPE string VALUE 'VERSIONS' ##NO_TEXT, END OF c_name, c_default_version TYPE etobj_ver VALUE '1' ##NO_TEXT. CLASS-METHODS: is_change_more_recent_than IMPORTING is_currently_changed TYPE ty_last_changed is_last_changed TYPE ty_last_changed RETURNING VALUE(rv_is_change_more_recent) TYPE abap_bool. DATA: mv_object_name TYPE etobj_name. METHODS: get_changed_date IMPORTING ii_document TYPE REF TO if_ixml_document RETURNING VALUE(rv_changed_date) TYPE d, get_changed_time IMPORTING ii_document TYPE REF TO if_ixml_document RETURNING VALUE(rv_changed_time) TYPE t, get_changed_by_user IMPORTING ii_document TYPE REF TO if_ixml_document RETURNING VALUE(rv_changed_by_user) TYPE syuname, get_change_information IMPORTING is_version_info TYPE etversinfo RETURNING VALUE(rs_change_information) TYPE ty_last_changed RAISING cx_ecatt_apl zcx_abapgit_exception, clear_attributes CHANGING ci_document TYPE REF TO if_ixml_document, clear_elements CHANGING ci_document TYPE REF TO if_ixml_document, get_version_from_node IMPORTING ii_node TYPE REF TO if_ixml_node RETURNING VALUE(rv_version) TYPE string, deserialize_version IMPORTING ii_version_node TYPE REF TO if_ixml_node iv_package TYPE devclass RAISING zcx_abapgit_exception, serialize_version IMPORTING iv_version TYPE etversinfo-version CHANGING ci_node TYPE REF TO if_ixml_element RAISING cx_ecatt zcx_abapgit_exception, clear_element IMPORTING iv_name TYPE csequence CHANGING ci_document TYPE REF TO if_ixml_document, clear_element_collection IMPORTING iv_name TYPE csequence CHANGING ci_document TYPE REF TO if_ixml_document, serialize_versions IMPORTING it_version_info TYPE etversinfo_tabtype CHANGING ci_document TYPE REF TO if_ixml_document RAISING cx_ecatt zcx_abapgit_exception. ENDCLASS. CLASS zcl_abapgit_object_ecatt_super IMPLEMENTATION. METHOD clear_attributes. DATA: li_element TYPE REF TO if_ixml_element, lv_object_type TYPE etobj_type. lv_object_type = get_object_type( ). li_element = ci_document->find_from_name( |{ lv_object_type }| ). li_element->remove_attribute( |SAPRL| ). li_element->remove_attribute( |DOWNLOADDATE| ). li_element->remove_attribute( |DOWNLOADTIME| ). ENDMETHOD. METHOD clear_element. DATA: li_element TYPE REF TO if_ixml_element. li_element = ci_document->find_from_name( iv_name ). IF li_element IS BOUND. li_element->set_value( || ). ENDIF. ENDMETHOD. METHOD clear_elements. clear_element( EXPORTING iv_name = |FUSER| CHANGING ci_document = ci_document ). clear_element( EXPORTING iv_name = |FDATE| CHANGING ci_document = ci_document ). clear_element( EXPORTING iv_name = |LUSER| CHANGING ci_document = ci_document ). clear_element( EXPORTING iv_name = |LDATE| CHANGING ci_document = ci_document ). clear_element( EXPORTING iv_name = |LTIME| CHANGING ci_document = ci_document ). clear_element( EXPORTING iv_name = |TWB_RESP| CHANGING ci_document = ci_document ). clear_element( EXPORTING iv_name = |DEVCLASS| CHANGING ci_document = ci_document ). clear_element( EXPORTING iv_name = |TADIR_RESP| CHANGING ci_document = ci_document ). " Clearing just VAR_EXT_PATH will lead to diffs in batch clear_element( EXPORTING iv_name = |ETVAR_EXT| CHANGING ci_document = ci_document ). " SORTLNR is part of ETPAR_VARI and causing diffs " We can clear it since it's automatically filled during deserialize clear_element_collection( EXPORTING iv_name = |SORTLNR| CHANGING ci_document = ci_document ). ENDMETHOD. METHOD clear_element_collection. DATA: lo_node_collection TYPE REF TO if_ixml_node_collection, lo_node TYPE REF TO if_ixml_node, lv_index TYPE i. lo_node_collection = ci_document->get_elements_by_tag_name( iv_name ). lv_index = 0. WHILE lv_index < lo_node_collection->get_length( ). lo_node = lo_node_collection->get_item( lv_index ). lo_node->set_value( '' ). lv_index = lv_index + 1. ENDWHILE. ENDMETHOD. METHOD constructor. super->constructor( is_item = is_item iv_language = iv_language io_files = io_files io_i18n_params = io_i18n_params ). mv_object_name = ms_item-obj_name. ENDMETHOD. METHOD deserialize_version. DATA: ls_object TYPE etmobjects, lo_upload TYPE REF TO cl_apl_ecatt_upload, li_upload TYPE REF TO zif_abapgit_ecatt_upload, lv_xml TYPE xstring, li_document TYPE REF TO if_ixml_document, lv_version TYPE string, lx_error TYPE REF TO cx_ecatt. lv_version = get_version_from_node( ii_version_node ). IF lv_version IS INITIAL. RETURN. ENDIF. lo_upload = get_upload( ). li_upload ?= lo_upload. li_document = cl_ixml=>create( )->create_document( ). li_document->append_child( ii_version_node->get_first_child( ) ). lv_xml = cl_ixml_80_20=>render_to_xstring( li_document ). li_upload->set_stream_for_upload( lv_xml ). ls_object-d_obj_name = mv_object_name. ls_object-s_obj_type = get_object_type( ). ls_object-d_devclass = iv_package. ls_object-d_obj_ver = lv_version. ls_object-d_overwrite = abap_true. TRY. lo_upload->upload( CHANGING ch_object = ls_object ). CATCH cx_ecatt INTO lx_error. zcx_abapgit_exception=>raise( lx_error->get_text( ) ). ENDTRY. ENDMETHOD. METHOD get_changed_by_user. rv_changed_by_user = ii_document->find_from_name( 'LUSER' )->get_value( ). ENDMETHOD. METHOD get_changed_date. DATA: lv_changed_date_external TYPE string. lv_changed_date_external = ii_document->find_from_name( 'LDATE' )->get_value( ). REPLACE ALL OCCURRENCES OF '-' IN lv_changed_date_external WITH ''. rv_changed_date = lv_changed_date_external. ENDMETHOD. METHOD get_changed_time. DATA: lv_changed_time_external TYPE string. lv_changed_time_external = ii_document->find_from_name( 'LTIME' )->get_value( ). REPLACE ALL OCCURRENCES OF ':' IN lv_changed_time_external WITH ''. rv_changed_time = lv_changed_time_external. ENDMETHOD. METHOD get_change_information. DATA: li_document TYPE REF TO if_ixml_document, lv_xml TYPE xstring, lo_download TYPE REF TO cl_apl_ecatt_download, lv_object_type TYPE etobj_type. lo_download = get_download( ). lv_object_type = get_object_type( ). lv_xml = zcl_abapgit_ecatt_helper=>build_xml_of_object( iv_object_name = mv_object_name iv_object_version = is_version_info-version iv_object_type = lv_object_type io_download = lo_download ). li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xml ). rs_change_information-ldate = get_changed_date( li_document ). rs_change_information-ltime = get_changed_time( li_document ). rs_change_information-luser = get_changed_by_user( li_document ). ENDMETHOD. METHOD get_version_from_node. TRY. rv_version = ii_node->get_first_child( )->get_first_child( )->get_first_child( )->get_first_child( )->get_value( ). CATCH cx_sy_ref_is_initial. RETURN. ENDTRY. ENDMETHOD. METHOD is_change_more_recent_than. IF is_currently_changed-ldate > is_last_changed-ldate OR ( is_currently_changed-ldate = is_last_changed-ldate AND is_currently_changed-ltime > is_last_changed-ltime ). rv_is_change_more_recent = abap_true. ENDIF. ENDMETHOD. METHOD serialize_version. DATA: li_document TYPE REF TO if_ixml_document, lv_xml TYPE xstring, li_node TYPE REF TO if_ixml_element, lo_download TYPE REF TO cl_apl_ecatt_download, lv_object_type TYPE etobj_type. lo_download = get_download( ). lv_object_type = get_object_type( ). lv_xml = zcl_abapgit_ecatt_helper=>build_xml_of_object( iv_object_name = mv_object_name iv_object_version = iv_version iv_object_type = lv_object_type io_download = lo_download ). IF lv_xml IS INITIAL. zcx_abapgit_exception=>raise( |ECATT, empty xml, { mv_object_name }| ). ENDIF. li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xml ). clear_attributes( CHANGING ci_document = li_document ). clear_elements( CHANGING ci_document = li_document ). li_node = li_document->create_element( c_name-version ). li_node->append_child( li_document->get_root_element( ) ). ci_node->append_child( li_node ). ENDMETHOD. METHOD serialize_versions. DATA: li_versions_node TYPE REF TO if_ixml_element. FIELD-SYMBOLS: LIKE LINE OF it_version_info. li_versions_node = ci_document->create_element( c_name-versions ). IF lines( it_version_info ) > 0. LOOP AT it_version_info ASSIGNING . serialize_version( EXPORTING iv_version = -version CHANGING ci_node = li_versions_node ). ENDLOOP. ELSE. serialize_version( EXPORTING iv_version = c_default_version CHANGING ci_node = li_versions_node ). ENDIF. ci_document->append_child( li_versions_node ). ENDMETHOD. METHOD zif_abapgit_object~changed_by. DATA: ls_last_changed TYPE ty_last_changed, ls_currently_changed TYPE ty_last_changed, lt_version_info TYPE etversinfo_tabtype, lx_error TYPE REF TO cx_static_check, lv_text TYPE string, lv_object_type TYPE etobj_type. FIELD-SYMBOLS: LIKE LINE OF lt_version_info. TRY. lv_object_type = get_object_type( ). cl_apl_ecatt_object=>get_version_info_object( EXPORTING im_name = mv_object_name im_obj_type = lv_object_type IMPORTING ex_version_info = lt_version_info ). LOOP AT lt_version_info ASSIGNING . ls_currently_changed = get_change_information( ). IF is_change_more_recent_than( is_currently_changed = ls_currently_changed is_last_changed = ls_last_changed ) = abap_true. ls_last_changed = ls_currently_changed. ENDIF. ENDLOOP. CATCH cx_static_check INTO lx_error. lv_text = lx_error->get_text( ). MESSAGE lv_text TYPE 'S' DISPLAY LIKE 'E'. ENDTRY. IF ls_last_changed-luser IS NOT INITIAL. rv_user = ls_last_changed-luser. ELSE. rv_user = c_user_unknown. ENDIF. ENDMETHOD. METHOD zif_abapgit_object~delete. DATA: lx_error TYPE REF TO cx_ecatt_apl, lv_text TYPE string, lv_object_type TYPE etobj_type. lv_object_type = get_object_type( ). TRY. cl_apl_ecatt_object=>delete_object( im_obj_type = lv_object_type im_name = mv_object_name " we have to supply a version, so let's use the default version " and delete them all im_version = c_default_version im_delete_all_versions = abap_true ). CATCH cx_ecatt_apl INTO lx_error. lv_text = lx_error->get_text( ). zcx_abapgit_exception=>raise( lv_text ). ENDTRY. ENDMETHOD. METHOD zif_abapgit_object~deserialize. DATA: li_document TYPE REF TO if_ixml_document, li_versions TYPE REF TO if_ixml_node_collection, li_version_iterator TYPE REF TO if_ixml_node_iterator, li_version_node TYPE REF TO if_ixml_node. li_document = io_xml->get_raw( ). li_versions = li_document->get_elements_by_tag_name( depth = 0 name = c_name-version ). li_version_iterator = li_versions->create_iterator( ). DO. li_version_node = li_version_iterator->get_next( ). IF li_version_node IS NOT BOUND. EXIT. ENDIF. deserialize_version( ii_version_node = li_version_node iv_package = iv_package ). ENDDO. ENDMETHOD. METHOD zif_abapgit_object~exists. DATA: lv_object_type TYPE etobj_type. lv_object_type = get_object_type( ). TRY. rv_bool = cl_apl_ecatt_object=>existence_check_object( im_name = mv_object_name im_version = c_default_version im_obj_type = lv_object_type im_exists_any_version = abap_true ). CATCH cx_ecatt. RETURN. ENDTRY. ENDMETHOD. METHOD zif_abapgit_object~get_comparator. RETURN. ENDMETHOD. METHOD zif_abapgit_object~get_deserialize_order. RETURN. ENDMETHOD. METHOD zif_abapgit_object~get_deserialize_steps. APPEND zif_abapgit_object=>gc_step_id-abap TO rt_steps. ENDMETHOD. METHOD zif_abapgit_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD zif_abapgit_object~is_active. rv_active = is_active( ). ENDMETHOD. METHOD zif_abapgit_object~is_locked. DATA: lv_object TYPE seqg3-garg. lv_object = ms_item-obj_name. OVERLAY lv_object WITH ' '. lv_object = lv_object && '*'. rv_is_locked = exists_a_lock_entry_for( iv_lock_object = get_lock_object( ) iv_argument = lv_object ). ENDMETHOD. METHOD zif_abapgit_object~jump. " Covered by ZCL_ABAPGIT_OBJECTS=>JUMP ENDMETHOD. METHOD zif_abapgit_object~map_filename_to_object. RETURN. ENDMETHOD. METHOD zif_abapgit_object~map_object_to_filename. RETURN. ENDMETHOD. METHOD zif_abapgit_object~serialize. DATA: lt_version_info TYPE etversinfo_tabtype, li_document TYPE REF TO if_ixml_document, lx_error TYPE REF TO cx_ecatt, lv_text TYPE string, lv_object_type TYPE etobj_type. lv_object_type = get_object_type( ). TRY. cl_apl_ecatt_object=>get_version_info_object( EXPORTING im_name = mv_object_name im_obj_type = lv_object_type IMPORTING ex_version_info = lt_version_info ). SORT lt_version_info BY version. li_document = cl_ixml=>create( )->create_document( ). serialize_versions( EXPORTING it_version_info = lt_version_info CHANGING ci_document = li_document ). io_xml->set_raw( li_document->get_root_element( ) ). CATCH cx_ecatt INTO lx_error. lv_text = lx_error->get_text( ). MESSAGE lv_text TYPE 'S' DISPLAY LIKE 'E'. ENDTRY. ENDMETHOD. ENDCLASS.