abapGit/src/objects/zcl_abapgit_object_ecatt_super.clas.abap
2023-12-18 17:16:00 -05:00

654 lines
17 KiB
ABAP

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: <ls_version_info> 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 <ls_version_info>.
serialize_version(
EXPORTING
iv_version = <ls_version_info>-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: <ls_version_info> 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_version_info>.
ls_currently_changed = get_change_information( <ls_version_info> ).
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.