CLASS zcl_abapgit_gui_page_commit DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_gui_page
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES: zif_abapgit_gui_page_hotkey.

    CONSTANTS:
      BEGIN OF c_action,
        commit_post   TYPE string VALUE 'commit_post',
        commit_cancel TYPE string VALUE 'commit_cancel',
      END OF c_action .

    METHODS constructor
      IMPORTING
        io_repo  TYPE REF TO zcl_abapgit_repo_online
        io_stage TYPE REF TO zcl_abapgit_stage
      RAISING
        zcx_abapgit_exception.

    METHODS zif_abapgit_gui_event_handler~on_event
        REDEFINITION .
  PROTECTED SECTION.

    CLASS-METHODS parse_commit_request
      IMPORTING
        !it_postdata TYPE cnht_post_data_tab
      EXPORTING
        !eg_fields   TYPE any .

    METHODS render_content
        REDEFINITION .
    METHODS scripts
        REDEFINITION .
  PRIVATE SECTION.
    DATA: mo_repo  TYPE REF TO zcl_abapgit_repo_online,
          mo_stage TYPE REF TO zcl_abapgit_stage.

    METHODS:
      render_menu
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
      render_stage
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
        RAISING   zcx_abapgit_exception,
      render_form
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
        RAISING   zcx_abapgit_exception,
      render_text_input
        IMPORTING iv_name        TYPE string
                  iv_label       TYPE string
                  iv_value       TYPE string OPTIONAL
                  iv_max_length  TYPE string OPTIONAL
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.

ENDCLASS.

CLASS ZCL_ABAPGIT_GUI_PAGE_COMMIT IMPLEMENTATION.

  METHOD constructor.
    super->constructor( ).

    mo_repo   = io_repo.
    mo_stage  = io_stage.

    ms_control-page_title = 'COMMIT'.
  ENDMETHOD.

  METHOD parse_commit_request.

    CONSTANTS: lc_replace TYPE string VALUE '<<new>>'.

    DATA: lv_string TYPE string,
          lt_fields TYPE tihttpnvp.

    FIELD-SYMBOLS <lv_body> TYPE string.

    CLEAR eg_fields.

    CONCATENATE LINES OF it_postdata INTO lv_string.
    REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_crlf    IN lv_string WITH lc_replace.
    REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_newline IN lv_string WITH lc_replace.
    lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( lv_string ).

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'COMMITTER_NAME'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'COMMITTER_EMAIL'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'AUTHOR_NAME'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'AUTHOR_EMAIL'
        it_field = lt_fields
      CHANGING
      cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'COMMENT'
        it_field = lt_fields
      CHANGING
      cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'BODY'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).

    ASSIGN COMPONENT 'BODY' OF STRUCTURE eg_fields TO <lv_body>.
    ASSERT <lv_body> IS ASSIGNED.
    REPLACE ALL OCCURRENCES OF lc_replace IN <lv_body> WITH zif_abapgit_definitions=>c_newline.

  ENDMETHOD.

  METHOD render_content.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).
    ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top(
      io_repo         = mo_repo
      iv_show_package = abap_false
      iv_branch       = mo_repo->get_branch_name( ) ) ).

    ro_html->add( render_menu( ) ).
    ro_html->add( render_form( ) ).
    ro_html->add( render_stage( ) ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_form.

    CONSTANTS: lc_body_col_max TYPE i VALUE 150.

    DATA: li_user      TYPE REF TO zif_abapgit_persist_user.
    DATA: lv_user      TYPE string.
    DATA: lv_email     TYPE string.
    DATA: lv_s_param   TYPE string.
    DATA: lo_settings  TYPE REF TO zcl_abapgit_settings.
    DATA: lv_body_size TYPE i.

* see https://git-scm.com/book/ch5-2.html
* commit messages should be max 50 characters
* body should wrap at 72 characters

    li_user = zcl_abapgit_persistence_user=>get_instance( ).

    lv_user  = li_user->get_repo_git_user_name( mo_repo->get_url( ) ).
    IF lv_user IS INITIAL.
      lv_user  = li_user->get_default_git_user_name( ).
    ENDIF.
    IF lv_user IS INITIAL.
      " get default from user master record
      lv_user = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_name( ).
    ENDIF.

    lv_email = li_user->get_repo_git_user_email( mo_repo->get_url( ) ).
    IF lv_email IS INITIAL.
      lv_email = li_user->get_default_git_user_email( ).
    ENDIF.
    IF lv_email IS INITIAL.
      " get default from user master record
      lv_email = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_email( ).
    ENDIF.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).
    ro_html->add( '<form id="commit_form" class="aligned-form"'
               && ' method="post" action="sapevent:commit_post">' ).

    ro_html->add( render_text_input( iv_name  = 'committer_name'
                                     iv_label = 'committer name'
                                     iv_value = lv_user ) ).

    ro_html->add( render_text_input( iv_name  = 'committer_email'
                                     iv_label = 'committer e-mail'
                                     iv_value = lv_email ) ).

    lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).

    lv_s_param = lo_settings->get_commitmsg_comment_length( ).

    ro_html->add( render_text_input( iv_name       = 'comment'
                                     iv_label      = 'comment'
                                     iv_max_length = lv_s_param ) ).

    ro_html->add( '
' ).
    ro_html->add( 'body' ).

    lv_body_size = lo_settings->get_commitmsg_body_size( ).
    IF lv_body_size > lc_body_col_max.
      lv_body_size = lc_body_col_max.
    ENDIF.
    ro_html->add( |<textarea id="c-body" name="body" rows="10" cols="| &&
                  |{ lv_body_size }"></textarea>| ).

    ro_html->add( '<input type="submit" class="hidden-submit">' ).
    ro_html->add( '
' ).

    ro_html->add( '
' ).
    ro_html->add( '' ).
    ro_html->add( 'Optionally,'
               && ' specify author (same as committer by default)' ).
    ro_html->add( '
' ).

    ro_html->add( render_text_input( iv_name  = 'author_name'
                                     iv_label = 'author name' ) ).

    ro_html->add( render_text_input( iv_name  = 'author_email'
                                     iv_label = 'author e-mail' ) ).

    ro_html->add( '</form>' ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_menu.

    DATA lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar.

    CREATE OBJECT ro_html.
    CREATE OBJECT lo_toolbar.

    lo_toolbar->add( iv_act = 'submitFormById(''commit_form'');'
                     iv_txt = 'Commit'
                     iv_typ = zif_abapgit_html=>c_action_type-onclick
                     iv_opt = zif_abapgit_html=>c_html_opt-strong ) ##NO_TEXT.

    lo_toolbar->add( iv_act = c_action-commit_cancel
                     iv_txt = 'Cancel'
                     iv_opt = zif_abapgit_html=>c_html_opt-cancel ) ##NO_TEXT.

    ro_html->add( '
' ).
    ro_html->add( lo_toolbar->render( ) ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_stage.

    DATA: lt_stage TYPE zcl_abapgit_stage=>ty_stage_tt.

    FIELD-SYMBOLS: <ls_stage> LIKE LINE OF lt_stage.

    CREATE OBJECT ro_html.

    lt_stage = mo_stage->get_all( ).

    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( 'Staged files	' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).

    ro_html->add( '
' ).
    LOOP AT lt_stage ASSIGNING <ls_stage>.
      ro_html->add( '
' ).
      ro_html->add( '' ).
      ro_html->add( zcl_abapgit_stage=>method_description( <ls_stage>-method ) ).
      ro_html->add( '	' ).
      ro_html->add( '' ).
      ro_html->add( <ls_stage>-file-path && <ls_stage>-file-filename ).
      ro_html->add( '	' ).
      ro_html->add( '
' ).
    ENDLOOP.
    ro_html->add( '
' ).

    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_text_input.

    DATA lv_attrs TYPE string.

    CREATE OBJECT ro_html.

    IF iv_value IS NOT INITIAL.
      lv_attrs = | value="{ iv_value }"|.
    ENDIF.

    IF iv_max_length IS NOT INITIAL.
      lv_attrs = | maxlength="{ iv_max_length }"|.
    ENDIF.

    ro_html->add( '
' ).
    ro_html->add( |{ iv_label }| ).
    ro_html->add( |<input id="{ iv_name }" name="{ iv_name }" type="text"{ lv_attrs }>| ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD scripts.

    ro_html = super->scripts( ).

    ro_html->add( 'setInitialFocus("comment");' ).

  ENDMETHOD.

  METHOD zif_abapgit_gui_event_handler~on_event.

    DATA: ls_commit TYPE zcl_abapgit_services_git=>ty_commit_fields.

    CASE iv_action.
      WHEN c_action-commit_post.

        parse_commit_request(
          EXPORTING it_postdata = it_postdata
          IMPORTING eg_fields   = ls_commit ).

        ls_commit-repo_key = mo_repo->get_key( ).

        zcl_abapgit_services_git=>commit(
          is_commit = ls_commit
          io_repo   = mo_repo
          io_stage  = mo_stage ).

        ev_state = zcl_abapgit_gui=>c_event_state-go_back_to_bookmark.

      WHEN c_action-commit_cancel.
        ev_state = zcl_abapgit_gui=>c_event_state-go_back.

      WHEN OTHERS.
        super->zif_abapgit_gui_event_handler~on_event(
          EXPORTING
            iv_action    = iv_action
            iv_prev_page = iv_prev_page
            iv_getdata   = iv_getdata
            it_postdata  = it_postdata
          IMPORTING
            ei_page      = ei_page
            ev_state     = ev_state ).
    ENDCASE.

  ENDMETHOD.

  METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_gui_page_commit DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_gui_page
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES: zif_abapgit_gui_page_hotkey.

    CONSTANTS:
      BEGIN OF c_action,
        commit_post   TYPE string VALUE 'commit_post',
        commit_cancel TYPE string VALUE 'commit_cancel',
      END OF c_action .

    METHODS constructor
      IMPORTING
        io_repo  TYPE REF TO zcl_abapgit_repo_online
        io_stage TYPE REF TO zcl_abapgit_stage
      RAISING
        zcx_abapgit_exception.

    METHODS zif_abapgit_gui_event_handler~on_event
        REDEFINITION .
  PROTECTED SECTION.

    CLASS-METHODS parse_commit_request
      IMPORTING
        !it_postdata TYPE cnht_post_data_tab
      EXPORTING
        !eg_fields   TYPE any .

    METHODS render_content
        REDEFINITION .
    METHODS scripts
        REDEFINITION .
  PRIVATE SECTION.
    DATA: mo_repo  TYPE REF TO zcl_abapgit_repo_online,
          mo_stage TYPE REF TO zcl_abapgit_stage.

    METHODS:
      render_menu
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
      render_stage
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
        RAISING   zcx_abapgit_exception,
      render_form
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
        RAISING   zcx_abapgit_exception,
      render_text_input
        IMPORTING iv_name        TYPE string
                  iv_label       TYPE string
                  iv_value       TYPE string OPTIONAL
                  iv_max_length  TYPE string OPTIONAL
        RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.

ENDCLASS.

CLASS ZCL_ABAPGIT_GUI_PAGE_COMMIT IMPLEMENTATION.

  METHOD constructor.
    super->constructor( ).

    mo_repo   = io_repo.
    mo_stage  = io_stage.

    ms_control-page_title = 'COMMIT'.
  ENDMETHOD.

  METHOD parse_commit_request.

    CONSTANTS: lc_replace TYPE string VALUE '<<new>>'.

    DATA: lv_string TYPE string,
          lt_fields TYPE tihttpnvp.

    FIELD-SYMBOLS <lv_body> TYPE string.

    CLEAR eg_fields.

    CONCATENATE LINES OF it_postdata INTO lv_string.
    REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_crlf    IN lv_string WITH lc_replace.
    REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_newline IN lv_string WITH lc_replace.
    lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( lv_string ).

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'COMMITTER_NAME'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'COMMITTER_EMAIL'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'AUTHOR_NAME'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'AUTHOR_EMAIL'
        it_field = lt_fields
      CHANGING
      cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'COMMENT'
        it_field = lt_fields
      CHANGING
      cg_field = eg_fields ).
    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        iv_name = 'BODY'
        it_field = lt_fields
      CHANGING
        cg_field = eg_fields ).

    ASSIGN COMPONENT 'BODY' OF STRUCTURE eg_fields TO <lv_body>.
    ASSERT <lv_body> IS ASSIGNED.
    REPLACE ALL OCCURRENCES OF lc_replace IN <lv_body> WITH zif_abapgit_definitions=>c_newline.

  ENDMETHOD.

  METHOD render_content.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).
    ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top(
      io_repo         = mo_repo
      iv_show_package = abap_false
      iv_branch       = mo_repo->get_branch_name( ) ) ).

    ro_html->add( render_menu( ) ).
    ro_html->add( render_form( ) ).
    ro_html->add( render_stage( ) ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_form.

    CONSTANTS: lc_body_col_max TYPE i VALUE 150.

    DATA: li_user      TYPE REF TO zif_abapgit_persist_user.
    DATA: lv_user      TYPE string.
    DATA: lv_email     TYPE string.
    DATA: lv_s_param   TYPE string.
    DATA: lo_settings  TYPE REF TO zcl_abapgit_settings.
    DATA: lv_body_size TYPE i.

* see https://git-scm.com/book/ch5-2.html
* commit messages should be max 50 characters
* body should wrap at 72 characters

    li_user = zcl_abapgit_persistence_user=>get_instance( ).

    lv_user  = li_user->get_repo_git_user_name( mo_repo->get_url( ) ).
    IF lv_user IS INITIAL.
      lv_user  = li_user->get_default_git_user_name( ).
    ENDIF.
    IF lv_user IS INITIAL.
      " get default from user master record
      lv_user = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_name( ).
    ENDIF.

    lv_email = li_user->get_repo_git_user_email( mo_repo->get_url( ) ).
    IF lv_email IS INITIAL.
      lv_email = li_user->get_default_git_user_email( ).
    ENDIF.
    IF lv_email IS INITIAL.
      " get default from user master record
      lv_email = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_email( ).
    ENDIF.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).
    ro_html->add( '<form id="commit_form" class="aligned-form"'
               && ' method="post" action="sapevent:commit_post">' ).

    ro_html->add( render_text_input( iv_name  = 'committer_name'
                                     iv_label = 'committer name'
                                     iv_value = lv_user ) ).

    ro_html->add( render_text_input( iv_name  = 'committer_email'
                                     iv_label = 'committer e-mail'
                                     iv_value = lv_email ) ).

    lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).

    lv_s_param = lo_settings->get_commitmsg_comment_length( ).

    ro_html->add( render_text_input( iv_name       = 'comment'
                                     iv_label      = 'comment'
                                     iv_max_length = lv_s_param ) ).

    ro_html->add( '
' ).
    ro_html->add( 'body' ).

    lv_body_size = lo_settings->get_commitmsg_body_size( ).
    IF lv_body_size > lc_body_col_max.
      lv_body_size = lc_body_col_max.
    ENDIF.
    ro_html->add( |<textarea id="c-body" name="body" rows="10" cols="| &&
                  |{ lv_body_size }"></textarea>| ).

    ro_html->add( '<input type="submit" class="hidden-submit">' ).
    ro_html->add( '
' ).

    ro_html->add( '
' ).
    ro_html->add( '' ).
    ro_html->add( 'Optionally,'
               && ' specify author (same as committer by default)' ).
    ro_html->add( '
' ).

    ro_html->add( render_text_input( iv_name  = 'author_name'
                                     iv_label = 'author name' ) ).

    ro_html->add( render_text_input( iv_name  = 'author_email'
                                     iv_label = 'author e-mail' ) ).

    ro_html->add( '</form>' ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_menu.

    DATA lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar.

    CREATE OBJECT ro_html.
    CREATE OBJECT lo_toolbar.

    lo_toolbar->add( iv_act = 'submitFormById(''commit_form'');'
                     iv_txt = 'Commit'
                     iv_typ = zif_abapgit_html=>c_action_type-onclick
                     iv_opt = zif_abapgit_html=>c_html_opt-strong ) ##NO_TEXT.

    lo_toolbar->add( iv_act = c_action-commit_cancel
                     iv_txt = 'Cancel'
                     iv_opt = zif_abapgit_html=>c_html_opt-cancel ) ##NO_TEXT.

    ro_html->add( '
' ).
    ro_html->add( lo_toolbar->render( ) ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_stage.

    DATA: lt_stage TYPE zcl_abapgit_stage=>ty_stage_tt.

    FIELD-SYMBOLS: <ls_stage> LIKE LINE OF lt_stage.

    CREATE OBJECT ro_html.

    lt_stage = mo_stage->get_all( ).

    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( 'Staged files	' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).

    ro_html->add( '
' ).
    LOOP AT lt_stage ASSIGNING <ls_stage>.
      ro_html->add( '
' ).
      ro_html->add( '' ).
      ro_html->add( zcl_abapgit_stage=>method_description( <ls_stage>-method ) ).
      ro_html->add( '	' ).
      ro_html->add( '' ).
      ro_html->add( <ls_stage>-file-path && <ls_stage>-file-filename ).
      ro_html->add( '	' ).
      ro_html->add( '
' ).
    ENDLOOP.
    ro_html->add( '
' ).

    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_text_input.

    DATA lv_attrs TYPE string.

    CREATE OBJECT ro_html.

    IF iv_value IS NOT INITIAL.
      lv_attrs = | value="{ iv_value }"|.
    ENDIF.

    IF iv_max_length IS NOT INITIAL.
      lv_attrs = | maxlength="{ iv_max_length }"|.
    ENDIF.

    ro_html->add( '
' ).
    ro_html->add( |{ iv_label }| ).
    ro_html->add( |<input id="{ iv_name }" name="{ iv_name }" type="text"{ lv_attrs }>| ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD scripts.

    ro_html = super->scripts( ).

    ro_html->add( 'setInitialFocus("comment");' ).

  ENDMETHOD.

  METHOD zif_abapgit_gui_event_handler~on_event.

    DATA: ls_commit TYPE zcl_abapgit_services_git=>ty_commit_fields.

    CASE iv_action.
      WHEN c_action-commit_post.

        parse_commit_request(
          EXPORTING it_postdata = it_postdata
          IMPORTING eg_fields   = ls_commit ).

        ls_commit-repo_key = mo_repo->get_key( ).

        zcl_abapgit_services_git=>commit(
          is_commit = ls_commit
          io_repo   = mo_repo
          io_stage  = mo_stage ).

        MESSAGE 'Commit was successful' TYPE 'S' ##NO_TEXT.

        ev_state = zcl_abapgit_gui=>c_event_state-go_back_to_bookmark.

      WHEN c_action-commit_cancel.
        ev_state = zcl_abapgit_gui=>c_event_state-go_back.

      WHEN OTHERS.
        super->zif_abapgit_gui_event_handler~on_event(
          EXPORTING
            iv_action    = iv_action
            iv_prev_page = iv_prev_page
            iv_getdata   = iv_getdata
            it_postdata  = it_postdata
          IMPORTING
            ei_page      = ei_page
            ev_state     = ev_state ).
    ENDCASE.

  ENDMETHOD.

  METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.

  ENDMETHOD.
ENDCLASS.

Add commit success message (#2979)

Add commit success message (#2979)

* New version of #2973

* Update zcl_abapgit_gui_page_commit.clas.abap


"! Progress reporter logger
"!

"! This logger shows all log entries in the SAP GUI progress indicator (status bar), using
"! CL_PROGRESS_INDICATOR internally (which itself is a wrapper class for function module
"! SAPGUI_PROGRESS_INDICATOR.
"!

"!

"! Keep in mind that sending status messages using the progress indicator to the front end may cause
"! severe performance problems. If that is a concern supply IV_OUTPUT_IMMEDIATELY in the
"! constructor with ABAP_FALSE.
"!

CLASS zcl_alog_progress_rep_logger DEFINITION
  PUBLIC
  INHERITING FROM zcl_alog_msg_logger_base
  CREATE PUBLIC .

  PUBLIC SECTION.

    "! @parameter iv_output_immediately | Output log entries immediately / always
    METHODS constructor
      IMPORTING
        !iv_output_immediately TYPE abap_bool DEFAULT abap_true .
    METHODS set_total_entries
      IMPORTING
        !iv_total_entries TYPE int4 .
    METHODS set_actual_entries
      IMPORTING
        !iv_actual_entries TYPE int4 .
  PROTECTED SECTION.

    METHODS entry_internal
         REDEFINITION .
    METHODS entry_msg_internal
         REDEFINITION .
  PRIVATE SECTION.

    DATA mv_output_immediately TYPE abap_bool .
    DATA mv_total_entries TYPE int4 .
    DATA mv_actual_entries TYPE int4 .
ENDCLASS.

CLASS ZCL_ALOG_PROGRESS_REP_LOGGER IMPLEMENTATION.

  METHOD constructor.
    super->constructor( ).
    mv_output_immediately = iv_output_immediately.
* EP Set actual and default maxinum counter
    set_actual_entries( 1 ).
    set_total_entries( 100 ).

  ENDMETHOD.

  METHOD entry_internal.
    cl_progress_indicator=>progress_indicate( i_text               = iv_text
                                              i_output_immediately = mv_output_immediately
                                              i_processed          = mv_actual_entries
                                              i_total              = mv_total_entries ).
  ENDMETHOD.

  METHOD entry_msg_internal.
    cl_progress_indicator=>progress_indicate( i_msgid              = iv_msgid
                                              i_msgno              = iv_msgno
                                              i_msgv1              = iv_msgv1
                                              i_msgv2              = iv_msgv2
                                              i_msgv3              = iv_msgv3
                                              i_msgv4              = iv_msgv4
                                              i_output_immediately = mv_output_immediately
                                              i_processed          = 1
                                              i_total              = 100 ).
  ENDMETHOD.

  METHOD set_actual_entries.
    mv_actual_entries = iv_actual_entries.
  ENDMETHOD.

  METHOD set_total_entries.
    mv_total_entries = iv_total_entries.
  ENDMETHOD.
ENDCLASS.

"! Progress reporter logger
"!

"! This logger shows all log entries in the SAP GUI progress indicator (status bar), using
"! CL_PROGRESS_INDICATOR internally (which itself is a wrapper class for function module
"! SAPGUI_PROGRESS_INDICATOR.
"!

"!

"! Keep in mind that sending status messages using the progress indicator to the front end may cause
"! severe performance problems. If that is a concern supply IV_OUTPUT_IMMEDIATELY in the
"! constructor with ABAP_FALSE.
"!

CLASS zcl_alog_progress_rep_logger DEFINITION
  PUBLIC
  INHERITING FROM zcl_alog_msg_logger_base
  CREATE PUBLIC .

  PUBLIC SECTION.

    "! @parameter iv_output_immediately | Output log entries immediately / always
    METHODS constructor
      IMPORTING
        !iv_output_immediately TYPE abap_bool DEFAULT abap_true .
    METHODS set_total_entries
      IMPORTING
        !iv_total_entries TYPE int4 .
    METHODS set_actual_entries
      IMPORTING
        !iv_actual_entries TYPE int4 .
  PROTECTED SECTION.

    METHODS entry_internal
         REDEFINITION .
    METHODS entry_msg_internal
         REDEFINITION .
  PRIVATE SECTION.

    DATA mv_output_immediately TYPE abap_bool .
    DATA mv_total_entries TYPE int4 .
    DATA mv_actual_entries TYPE int4 .
ENDCLASS.

CLASS ZCL_ALOG_PROGRESS_REP_LOGGER IMPLEMENTATION.

  METHOD constructor.
    super->constructor( ).
    mv_output_immediately = iv_output_immediately.
* Set default actual and total counter
    set_actual_entries( 1 ).
    set_total_entries( 100 ).

  ENDMETHOD.

  METHOD entry_internal.
    cl_progress_indicator=>progress_indicate( i_text               = iv_text
                                              i_output_immediately = mv_output_immediately
                                              i_processed          = mv_actual_entries
                                              i_total              = mv_total_entries ).
  ENDMETHOD.

  METHOD entry_msg_internal.
    cl_progress_indicator=>progress_indicate( i_msgid              = iv_msgid
                                              i_msgno              = iv_msgno
                                              i_msgv1              = iv_msgv1
                                              i_msgv2              = iv_msgv2
                                              i_msgv3              = iv_msgv3
                                              i_msgv4              = iv_msgv4
                                              i_output_immediately = mv_output_immediately
                                              i_processed          = mv_actual_entries
                                              i_total              = mv_total_entries ).
  ENDMETHOD.

  METHOD set_actual_entries.
    mv_actual_entries = iv_actual_entries.
  ENDMETHOD.

  METHOD set_total_entries.
    mv_total_entries = iv_total_entries.
  ENDMETHOD.
ENDCLASS.

add dinamic counter

add dinamic counter


CLASS zcl_abapgit_object_ddlx DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES zif_abapgit_object.
    ALIASES mo_files FOR zif_abapgit_object~mo_files.
  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA mi_persistence TYPE REF TO if_wb_object_persist .
    METHODS get_persistence
      RETURNING
        VALUE(ri_persistence) TYPE REF TO if_wb_object_persist
      RAISING
        zcx_abapgit_exception .
    METHODS clear_fields
      CHANGING
        !cg_data TYPE any .
    METHODS clear_field
      IMPORTING
        !iv_fieldname TYPE csequence
      CHANGING
        !cg_metadata  TYPE any .
ENDCLASS.

CLASS zcl_abapgit_object_ddlx IMPLEMENTATION.

  METHOD clear_field.

    FIELD-SYMBOLS: <lg_field> TYPE data.

    ASSIGN COMPONENT iv_fieldname
           OF STRUCTURE cg_metadata
           TO <lg_field>.
    ASSERT sy-subrc = 0.

    CLEAR: <lg_field>.

  ENDMETHOD.

  METHOD clear_fields.

    FIELD-SYMBOLS: <lg_metadata> TYPE any.

    ASSIGN COMPONENT 'METADATA'
           OF STRUCTURE cg_data
           TO <lg_metadata>.
    ASSERT sy-subrc = 0.

    clear_field( EXPORTING iv_fieldname = 'CHANGED_AT'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CHANGED_BY'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CREATED_AT'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CREATED_BY'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'RESPONSIBLE'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'PACKAGE_REF-NAME'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CONTAINER_REF-PACKAGE_NAME'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'VERSION'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'RESPONSIBLE'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'MASTER_SYSTEM'
                 CHANGING  cg_metadata  = <lg_metadata> ).

  ENDMETHOD.

  METHOD get_persistence.

    DATA: lx_error TYPE REF TO cx_root.

    TRY.
        IF mi_persistence IS NOT BOUND.

          CREATE OBJECT mi_persistence
                 TYPE ('CL_DDLX_ADT_OBJECT_PERSIST').

        ENDIF.

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

    ri_persistence = mi_persistence.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.
    rv_user = c_user_unknown.
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lv_object_key TYPE seu_objkey,
          lx_error      TYPE REF TO cx_root.

    lv_object_key = ms_item-obj_name.

    TRY.

        get_persistence( )->delete( p_object_key = lv_object_key
                                    p_version    = swbm_version_active ).

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: li_data_model TYPE REF TO if_wb_object_data_model,
          lr_data       TYPE REF TO data,
          lx_error      TYPE REF TO cx_root.

    FIELD-SYMBOLS: <lg_data>    TYPE any,
                   <lg_source>  TYPE data,
                   <lg_version> TYPE data,
                   <lg_package> TYPE data.

    TRY.
        CREATE DATA lr_data
          TYPE ('CL_DDLX_WB_OBJECT_DATA=>TY_OBJECT_DATA').
        ASSIGN lr_data->* TO <lg_data>.

        io_xml->read(
          EXPORTING
            iv_name = 'DDLX'
          CHANGING
            cg_data = <lg_data> ).

        ASSIGN COMPONENT 'CONTENT-SOURCE' OF STRUCTURE <lg_data> TO <lg_source>.
        ASSERT sy-subrc = 0.

        TRY.
            " If the file doesn't exist that's ok, because previously
            " the source code was stored in the xml. We are downward compatible.
            <lg_source> = mo_files->read_string( 'asddlxs' ).
          CATCH zcx_abapgit_exception ##NO_HANDLER.
        ENDTRY.

        CREATE OBJECT li_data_model
          TYPE ('CL_DDLX_WB_OBJECT_DATA').

        ASSIGN COMPONENT 'METADATA-VERSION' OF STRUCTURE <lg_data> TO <lg_version>.
        ASSERT sy-subrc = 0.

        " We have to always save as inactive. Standard activation below activates then
        " and also creates transport request entry if necessary
        <lg_version> = 'inactive'.

        "package needed to be able to determine ABAP language version
        ASSIGN COMPONENT 'METADATA-PACKAGE_REF-NAME' OF STRUCTURE <lg_data> TO <lg_package>.
        IF <lg_package> IS ASSIGNED.
          <lg_package> = iv_package.
        ENDIF.

        li_data_model->set_data( <lg_data> ).

        get_persistence( )->save( li_data_model ).

        tadir_insert( iv_package ).

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

    zcl_abapgit_objects_activation=>add_item( ms_item ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: lv_object_key TYPE seu_objkey.

    lv_object_key = ms_item-obj_name.

    rv_bool = abap_true.

    TRY.
        get_persistence( )->get( p_object_key           = lv_object_key
                                 p_version              = swbm_version_active
                                 p_existence_check_only = abap_true ).

      CATCH cx_swb_exception.
        rv_bool = abap_false.
    ENDTRY.

  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    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( ).
    rs_metadata-delete_tadir = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~is_active.
    rv_active = is_active( ).
  ENDMETHOD.

  METHOD zif_abapgit_object~is_locked.

    rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESWB_EO'
                                            iv_argument    = |{ ms_item-obj_type }{ ms_item-obj_name }| ).

  ENDMETHOD.

  METHOD zif_abapgit_object~jump.
    " Covered by ZCL_ABAPGIT_ADT_LINK=>JUMP
  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: lv_object_key  TYPE seu_objkey,
          li_data_model  TYPE REF TO if_wb_object_data_model,
          li_persistence TYPE REF TO if_wb_object_persist,
          lr_data        TYPE REF TO data,
          lx_error       TYPE REF TO cx_root.

    FIELD-SYMBOLS: <lg_data>  TYPE any,
                   <lg_field> TYPE data.

    lv_object_key = ms_item-obj_name.

    TRY.
        CREATE DATA lr_data
          TYPE ('CL_DDLX_WB_OBJECT_DATA=>TY_OBJECT_DATA').
        ASSIGN lr_data->* TO <lg_data>.

        CREATE OBJECT li_data_model
          TYPE ('CL_DDLX_WB_OBJECT_DATA').

        li_persistence = get_persistence( ).

        IF zcl_abapgit_factory=>get_environment( )->compare_with_inactive( ) = abap_true.
          "Retrieve inactive version
          li_persistence->get(
            EXPORTING
              p_object_key  = lv_object_key
              p_version     = swbm_version_inactive
            CHANGING
              p_object_data = li_data_model ).
          IF li_data_model->get_object_name( ) IS INITIAL.
            "Fallback: retrieve active version
            li_persistence->get(
              EXPORTING
                p_object_key  = lv_object_key
                p_version     = swbm_version_active
              CHANGING
                p_object_data = li_data_model ).
          ENDIF.
        ELSE.
          "Retrieve active version
          li_persistence->get(
            EXPORTING
              p_object_key  = lv_object_key
              p_version     = swbm_version_active
            CHANGING
              p_object_data = li_data_model ).
        ENDIF.

        li_data_model->get_data( IMPORTING p_data = <lg_data> ).

        clear_fields( CHANGING cg_data = <lg_data> ).

        ASSIGN COMPONENT 'CONTENT-SOURCE' OF STRUCTURE <lg_data> TO <lg_field>.
        ASSERT sy-subrc = 0.

        mo_files->add_string( iv_ext    = 'asddlxs'
                              iv_string = <lg_field> ).

        CLEAR <lg_field>.

        io_xml->add( iv_name = 'DDLX'
                     ig_data = <lg_data> ).

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_object_ddlx DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES zif_abapgit_object.
    ALIASES mo_files FOR zif_abapgit_object~mo_files.
  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA mi_persistence TYPE REF TO if_wb_object_persist .
    METHODS get_persistence
      RETURNING
        VALUE(ri_persistence) TYPE REF TO if_wb_object_persist
      RAISING
        zcx_abapgit_exception .
    METHODS clear_fields
      CHANGING
        !cg_data TYPE any .
    METHODS clear_field
      IMPORTING
        !iv_fieldname TYPE csequence
      CHANGING
        !cg_metadata  TYPE any .
ENDCLASS.

CLASS zcl_abapgit_object_ddlx IMPLEMENTATION.

  METHOD clear_field.

    FIELD-SYMBOLS: <lg_field> TYPE data.

    ASSIGN COMPONENT iv_fieldname
           OF STRUCTURE cg_metadata
           TO <lg_field>.
    IF sy-subrc = 0.
      CLEAR: <lg_field>.
    ENDIF.

  ENDMETHOD.

  METHOD clear_fields.

    FIELD-SYMBOLS: <lg_metadata> TYPE any.

    ASSIGN COMPONENT 'METADATA'
           OF STRUCTURE cg_data
           TO <lg_metadata>.
    ASSERT sy-subrc = 0.

    clear_field( EXPORTING iv_fieldname = 'CHANGED_AT'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CHANGED_BY'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CREATED_AT'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CREATED_BY'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'RESPONSIBLE'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'PACKAGE_REF-NAME'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'CONTAINER_REF-PACKAGE_NAME'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'VERSION'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'RESPONSIBLE'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'MASTER_SYSTEM'
                 CHANGING  cg_metadata  = <lg_metadata> ).

    clear_field( EXPORTING iv_fieldname = 'ABAP_LANGUAGE_VERSION'
                 CHANGING  cg_metadata  = <lg_metadata> ).
    clear_field( EXPORTING iv_fieldname = 'ABAP_LANGU_VERSION'
                 CHANGING  cg_metadata  = <lg_metadata> ).

  ENDMETHOD.

  METHOD get_persistence.

    DATA: lx_error TYPE REF TO cx_root.

    TRY.
        IF mi_persistence IS NOT BOUND.

          CREATE OBJECT mi_persistence
                 TYPE ('CL_DDLX_ADT_OBJECT_PERSIST').

        ENDIF.

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

    ri_persistence = mi_persistence.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.
    rv_user = c_user_unknown.
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lv_object_key TYPE seu_objkey,
          lx_error      TYPE REF TO cx_root.

    lv_object_key = ms_item-obj_name.

    TRY.

        get_persistence( )->delete( p_object_key = lv_object_key
                                    p_version    = swbm_version_active ).

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: li_data_model TYPE REF TO if_wb_object_data_model,
          lr_data       TYPE REF TO data,
          lx_error      TYPE REF TO cx_root.

    FIELD-SYMBOLS: <lg_data>    TYPE any,
                   <lg_source>  TYPE data,
                   <lg_version> TYPE data,
                   <lg_package> TYPE data.

    TRY.
        CREATE DATA lr_data
          TYPE ('CL_DDLX_WB_OBJECT_DATA=>TY_OBJECT_DATA').
        ASSIGN lr_data->* TO <lg_data>.

        io_xml->read(
          EXPORTING
            iv_name = 'DDLX'
          CHANGING
            cg_data = <lg_data> ).

        ASSIGN COMPONENT 'CONTENT-SOURCE' OF STRUCTURE <lg_data> TO <lg_source>.
        ASSERT sy-subrc = 0.

        TRY.
            " If the file doesn't exist that's ok, because previously
            " the source code was stored in the xml. We are downward compatible.
            <lg_source> = mo_files->read_string( 'asddlxs' ).
          CATCH zcx_abapgit_exception ##NO_HANDLER.
        ENDTRY.

        CREATE OBJECT li_data_model
          TYPE ('CL_DDLX_WB_OBJECT_DATA').

        ASSIGN COMPONENT 'METADATA-VERSION' OF STRUCTURE <lg_data> TO <lg_version>.
        ASSERT sy-subrc = 0.

        " We have to always save as inactive. Standard activation below activates then
        " and also creates transport request entry if necessary
        <lg_version> = 'inactive'.

        "package needed to be able to determine ABAP language version
        ASSIGN COMPONENT 'METADATA-PACKAGE_REF-NAME' OF STRUCTURE <lg_data> TO <lg_package>.
        IF <lg_package> IS ASSIGNED.
          <lg_package> = iv_package.
        ENDIF.

        li_data_model->set_data( <lg_data> ).

        get_persistence( )->save( li_data_model ).

        tadir_insert( iv_package ).

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

    zcl_abapgit_objects_activation=>add_item( ms_item ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: lv_object_key TYPE seu_objkey.

    lv_object_key = ms_item-obj_name.

    rv_bool = abap_true.

    TRY.
        get_persistence( )->get( p_object_key           = lv_object_key
                                 p_version              = swbm_version_active
                                 p_existence_check_only = abap_true ).

      CATCH cx_swb_exception.
        rv_bool = abap_false.
    ENDTRY.

  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    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( ).
    rs_metadata-delete_tadir = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~is_active.
    rv_active = is_active( ).
  ENDMETHOD.

  METHOD zif_abapgit_object~is_locked.

    rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESWB_EO'
                                            iv_argument    = |{ ms_item-obj_type }{ ms_item-obj_name }| ).

  ENDMETHOD.

  METHOD zif_abapgit_object~jump.
    " Covered by ZCL_ABAPGIT_ADT_LINK=>JUMP
  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: lv_object_key  TYPE seu_objkey,
          li_data_model  TYPE REF TO if_wb_object_data_model,
          li_persistence TYPE REF TO if_wb_object_persist,
          lr_data        TYPE REF TO data,
          lx_error       TYPE REF TO cx_root.

    FIELD-SYMBOLS: <lg_data>  TYPE any,
                   <lg_field> TYPE data.

    lv_object_key = ms_item-obj_name.

    TRY.
        CREATE DATA lr_data
          TYPE ('CL_DDLX_WB_OBJECT_DATA=>TY_OBJECT_DATA').
        ASSIGN lr_data->* TO <lg_data>.

        CREATE OBJECT li_data_model
          TYPE ('CL_DDLX_WB_OBJECT_DATA').

        li_persistence = get_persistence( ).

        IF zcl_abapgit_factory=>get_environment( )->compare_with_inactive( ) = abap_true.
          "Retrieve inactive version
          li_persistence->get(
            EXPORTING
              p_object_key  = lv_object_key
              p_version     = swbm_version_inactive
            CHANGING
              p_object_data = li_data_model ).
          IF li_data_model->get_object_name( ) IS INITIAL.
            "Fallback: retrieve active version
            li_persistence->get(
              EXPORTING
                p_object_key  = lv_object_key
                p_version     = swbm_version_active
              CHANGING
                p_object_data = li_data_model ).
          ENDIF.
        ELSE.
          "Retrieve active version
          li_persistence->get(
            EXPORTING
              p_object_key  = lv_object_key
              p_version     = swbm_version_active
            CHANGING
              p_object_data = li_data_model ).
        ENDIF.

        li_data_model->get_data( IMPORTING p_data = <lg_data> ).

        clear_fields( CHANGING cg_data = <lg_data> ).

        ASSIGN COMPONENT 'CONTENT-SOURCE' OF STRUCTURE <lg_data> TO <lg_field>.
        ASSERT sy-subrc = 0.

        mo_files->add_string( iv_ext    = 'asddlxs'
                              iv_string = <lg_field> ).

        CLEAR <lg_field>.

        io_xml->add( iv_name = 'DDLX'
                     ig_data = <lg_data> ).

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise_with_text( lx_error ).
    ENDTRY.

  ENDMETHOD.
ENDCLASS.

clear ABAP_LANGU_VERSION

DDLX: clear ABAP_LANGU_VERSION


CLASS ltcl_filter_files_to_deser DEFINITION DEFERRED.
CLASS ltcl_prio_deserialization DEFINITION DEFERRED.

CLASS zcl_abapgit_file_deserialize DEFINITION LOCAL FRIENDS ltcl_filter_files_to_deser.
CLASS zcl_abapgit_file_deserialize DEFINITION LOCAL FRIENDS ltcl_prio_deserialization.

CLASS ltcl_filter_files_to_deser DEFINITION FINAL FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PRIVATE SECTION.
    DATA:
      mo_objects TYPE REF TO zcl_abapgit_file_deserialize,
      mt_result  TYPE zif_abapgit_definitions=>ty_results_tt.

    METHODS:
      setup,
      filter_duplicates FOR TESTING RAISING cx_static_check,
      filter_duplicates_rstate FOR TESTING RAISING cx_static_check,
      filter_duplicates_lstate FOR TESTING RAISING cx_static_check,
      filter_duplicates_match FOR TESTING RAISING cx_static_check,
      filter_duplicates_init_objtype FOR TESTING RAISING cx_static_check,
      filter_duplicates_changes_01 FOR TESTING RAISING cx_static_check,
      filter_duplicates_changes_02 FOR TESTING RAISING cx_static_check,
      filter_duplicates_deleted FOR TESTING RAISING cx_static_check,

      given_result
        IMPORTING
          iv_result_line TYPE string,

      when_filter_is_applied.

ENDCLASS.

CLASS ltcl_filter_files_to_deser IMPLEMENTATION.

  METHOD setup.

    CREATE OBJECT mo_objects.

  ENDMETHOD.

  METHOD filter_duplicates.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_rstate.

    DATA: ls_exp LIKE LINE OF mt_result,
          ls_act LIKE LINE OF mt_result.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;A| ).

    READ TABLE mt_result INDEX 2 INTO ls_exp.

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

    READ TABLE mt_result INDEX 1 INTO ls_act.

    cl_abap_unit_assert=>assert_equals(
      exp = ls_exp
      act = ls_act ).

  ENDMETHOD.

  METHOD filter_duplicates_lstate.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;A;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;A;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_match.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;X;;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;X;;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_init_objtype.

    given_result( |;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;;| ).
    given_result( |;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_changes_01.

    DATA: ls_exp LIKE LINE OF mt_result,
          ls_act LIKE LINE OF mt_result.

    " test different order since SORT object,obj_name is non-deterministic
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.abap;;;M;M| ).
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.testclasses.abap;;;;M| ).

    READ TABLE mt_result INDEX 1 INTO ls_exp.

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

    READ TABLE mt_result INDEX 1 INTO ls_act.

    " expect M,M
    cl_abap_unit_assert=>assert_equals(
      exp = ls_exp
      act = ls_act ).

  ENDMETHOD.

  METHOD filter_duplicates_changes_02.

    DATA: ls_exp LIKE LINE OF mt_result,
          ls_act LIKE LINE OF mt_result.

    " test different order since SORT object,obj_name is non-deterministic
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.abap;;;;M| ).
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.testclasses.abap;;;M;M| ).

    READ TABLE mt_result INDEX 2 INTO ls_exp.

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

    READ TABLE mt_result INDEX 1 INTO ls_act.

    " expect M,M
    cl_abap_unit_assert=>assert_equals(
      exp = ls_exp
      act = ls_act ).

  ENDMETHOD.

  METHOD filter_duplicates_deleted.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;D| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD given_result.

    DATA: ls_result LIKE LINE OF mt_result.

    SPLIT iv_result_line
      AT ';'
      INTO ls_result-obj_type
           ls_result-obj_name
           ls_result-inactive
           ls_result-path
           ls_result-filename
           ls_result-package
           ls_result-match
           ls_result-lstate
           ls_result-rstate.

    INSERT ls_result INTO TABLE mt_result.

  ENDMETHOD.

  METHOD when_filter_is_applied.

    mt_result = mo_objects->filter_files_to_deserialize( mt_result ).

  ENDMETHOD.

ENDCLASS.

CLASS ltcl_prio_deserialization DEFINITION FINAL FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PRIVATE SECTION.
    METHODS:
      setup,
      ddls_before_dcls FOR TESTING RAISING cx_static_check,
      webi_before_sprx FOR TESTING RAISING cx_static_check,
      iasp_before_isrp FOR TESTING RAISING cx_static_check,
      iobj_before_odso FOR TESTING RAISING cx_static_check,
      tobj_before_scp1 FOR TESTING RAISING cx_static_check,
      otgr_before_char FOR TESTING RAISING cx_static_check,
      sprx_before_clas FOR TESTING RAISING cx_static_check,
      sprx_before_intf FOR TESTING RAISING cx_static_check,
      sprx_before_tabl FOR TESTING RAISING cx_static_check,
      pinf_before_devc FOR TESTING RAISING cx_static_check,
      clas_before_pinf FOR TESTING RAISING cx_static_check,
      enhs_before_ensc FOR TESTING RAISING cx_static_check,
      ensc_before_enho FOR TESTING RAISING cx_static_check,
      enho_before_enhc FOR TESTING RAISING cx_static_check,
      xslt_before_clas_and_prog FOR TESTING RAISING cx_static_check,

      given
        IMPORTING
          iv_object_type TYPE string,
      when_deser_is_priorized,
      then
        IMPORTING
          iv_exp_object_type TYPE string.

    DATA:
      mo_objects          TYPE REF TO zcl_abapgit_file_deserialize,
      mt_input            TYPE zif_abapgit_definitions=>ty_results_tt,
      mt_output           TYPE zif_abapgit_definitions=>ty_results_tt,
      mv_counter          TYPE i,
      mv_exp_output_tabix TYPE i.

ENDCLASS.

CLASS ltcl_prio_deserialization IMPLEMENTATION.

  METHOD setup.
    CREATE OBJECT mo_objects.
    mv_exp_output_tabix = 0.
  ENDMETHOD.

  METHOD enhs_before_ensc.
    given( 'ENSC' ).
    given( 'ENHS' ).
    when_deser_is_priorized( ).
    then( 'ENHS' ).
    then( 'ENSC' ).
  ENDMETHOD.

  METHOD ensc_before_enho.
    given( 'ENHO' ).
    given( 'ENSC' ).
    when_deser_is_priorized( ).
    then( 'ENSC' ).
    then( 'ENHO' ).
  ENDMETHOD.

  METHOD enho_before_enhc.
    given( 'ENHC' ).
    given( 'ENHO' ).
    when_deser_is_priorized( ).
    then( 'ENHO' ).
    then( 'ENHC' ).
  ENDMETHOD.

  METHOD sprx_before_clas.
    given( 'CLAS' ).
    given( 'SPRX' ).
    when_deser_is_priorized( ).
    then( 'SPRX' ).
    then( 'CLAS' ).
  ENDMETHOD.

  METHOD sprx_before_intf.
    given( 'INTF' ).
    given( 'SPRX' ).
    when_deser_is_priorized( ).
    then( 'SPRX' ).
    then( 'INTF' ).
  ENDMETHOD.

  METHOD sprx_before_tabl.
    given( 'TABL' ).
    given( 'SPRX' ).
    when_deser_is_priorized( ).
    then( 'SPRX' ).
    then( 'TABL' ).
  ENDMETHOD.

  METHOD otgr_before_char.
    given( 'CHAR' ).
    given( 'OTGR' ).
    when_deser_is_priorized( ).
    then( 'OTGR' ).
    then( 'CHAR' ).
  ENDMETHOD.

  METHOD pinf_before_devc.
    given( 'DEVC' ).
    given( 'PINF' ).
    when_deser_is_priorized( ).
    then( 'PINF' ).
    then( 'DEVC' ).
  ENDMETHOD.

  METHOD tobj_before_scp1.
    given( 'SCP1' ).
    given( 'TOBJ' ).
    when_deser_is_priorized( ).
    then( 'TOBJ' ).
    then( 'SCP1' ).
  ENDMETHOD.

  METHOD iobj_before_odso.
    given( 'ODSO' ).
    given( 'IOBJ' ).
    when_deser_is_priorized( ).
    then( 'IOBJ' ).
    then( 'ODSO' ).
  ENDMETHOD.

  METHOD iasp_before_isrp.
    given( 'ISRP' ).
    given( 'IASP' ).
    when_deser_is_priorized( ).
    then( 'IASP' ).
    then( 'ISRP' ).
  ENDMETHOD.

  METHOD webi_before_sprx.
    given( 'SPRX' ).
    given( 'WEBI' ).
    when_deser_is_priorized( ).
    then( 'WEBI' ).
    then( 'SPRX' ).
  ENDMETHOD.

  METHOD clas_before_pinf.
    given( 'PINF' ).
    given( 'CLAS' ).
    when_deser_is_priorized( ).
    then( 'CLAS' ).
    then( 'PINF' ).
  ENDMETHOD.

  METHOD xslt_before_clas_and_prog.
    given( 'XSLT' ).
    given( 'INTF' ).
    given( 'CLAS' ).
    when_deser_is_priorized( ).
    then( 'XSLT' ).
    then( 'INTF' ).
    then( 'CLAS' ).
  ENDMETHOD.

  METHOD ddls_before_dcls.
    given( 'DCLS' ).
    given( 'DDLS' ).
    given( 'DCLS' ).
    given( 'DDLS' ).
    when_deser_is_priorized( ).
    then( 'DDLS' ).
    then( 'DDLS' ).
    then( 'DCLS' ).
    then( 'DCLS' ).
  ENDMETHOD.

  METHOD given.

    DATA ls_input LIKE LINE OF mt_input.
    ls_input-obj_type = iv_object_type.
    ls_input-obj_name = mv_counter.
    INSERT ls_input INTO TABLE mt_input.
    mv_counter = mv_counter + 1.

  ENDMETHOD.

  METHOD when_deser_is_priorized.

    DATA lo_log TYPE REF TO zcl_abapgit_log.

    CREATE OBJECT lo_log.

    mt_output = mo_objects->prioritize_deser(
      ii_log     = lo_log
      it_results = mt_input ).

  ENDMETHOD.

  METHOD then.

    DATA: ls_output LIKE LINE OF mt_output.

    mv_exp_output_tabix = mv_exp_output_tabix + 1.

    READ TABLE mt_output INTO ls_output INDEX mv_exp_output_tabix.

    cl_abap_unit_assert=>assert_equals(
      exp = iv_exp_object_type
      act = ls_output-obj_type ).

  ENDMETHOD.

ENDCLASS.

CLASS ltcl_filter_files_to_deser DEFINITION DEFERRED.
CLASS ltcl_prio_deserialization DEFINITION DEFERRED.

CLASS zcl_abapgit_file_deserialize DEFINITION LOCAL FRIENDS ltcl_filter_files_to_deser.
CLASS zcl_abapgit_file_deserialize DEFINITION LOCAL FRIENDS ltcl_prio_deserialization.

CLASS ltcl_filter_files_to_deser DEFINITION FINAL FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PRIVATE SECTION.
    DATA:
      mo_objects TYPE REF TO zcl_abapgit_file_deserialize,
      mt_result  TYPE zif_abapgit_definitions=>ty_results_tt.

    METHODS:
      setup,
      filter_duplicates FOR TESTING RAISING cx_static_check,
      filter_duplicates_rstate FOR TESTING RAISING cx_static_check,
      filter_duplicates_lstate FOR TESTING RAISING cx_static_check,
      filter_duplicates_match FOR TESTING RAISING cx_static_check,
      filter_duplicates_init_objtype FOR TESTING RAISING cx_static_check,
      filter_duplicates_changes_01 FOR TESTING RAISING cx_static_check,
      filter_duplicates_changes_02 FOR TESTING RAISING cx_static_check,
      filter_duplicates_deleted FOR TESTING RAISING cx_static_check,

      given_result
        IMPORTING
          iv_result_line TYPE string,

      when_filter_is_applied.

ENDCLASS.

CLASS ltcl_filter_files_to_deser IMPLEMENTATION.

  METHOD setup.

    CREATE OBJECT mo_objects.

  ENDMETHOD.

  METHOD filter_duplicates.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_rstate.

    DATA: ls_exp LIKE LINE OF mt_result,
          ls_act LIKE LINE OF mt_result.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;A| ).

    READ TABLE mt_result INDEX 2 INTO ls_exp.

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

    READ TABLE mt_result INDEX 1 INTO ls_act.

    cl_abap_unit_assert=>assert_equals(
      exp = ls_exp
      act = ls_act ).

  ENDMETHOD.

  METHOD filter_duplicates_lstate.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;A;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;A;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_match.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;X;;| ).
    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;X;;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_init_objtype.

    given_result( |;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.abap;;;;| ).
    given_result( |;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD filter_duplicates_changes_01.

    DATA: ls_exp LIKE LINE OF mt_result,
          ls_act LIKE LINE OF mt_result.

    " test different order since SORT object,obj_name is non-deterministic
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.abap;;;M;M| ).
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.testclasses.abap;;;;M| ).

    READ TABLE mt_result INDEX 1 INTO ls_exp.

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

    READ TABLE mt_result INDEX 1 INTO ls_act.

    " expect M,M
    cl_abap_unit_assert=>assert_equals(
      exp = ls_exp
      act = ls_act ).

  ENDMETHOD.

  METHOD filter_duplicates_changes_02.

    DATA: ls_exp LIKE LINE OF mt_result,
          ls_act LIKE LINE OF mt_result.

    " test different order since SORT object,obj_name is non-deterministic
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.abap;;;;M| ).
    given_result( |CLAS;ZAG_UNIT_TEST;;/src/;zag_unit_test.clas.testclasses.abap;;;M;M| ).

    READ TABLE mt_result INDEX 2 INTO ls_exp.

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 1
      act = lines( mt_result ) ).

    READ TABLE mt_result INDEX 1 INTO ls_act.

    " expect M,M
    cl_abap_unit_assert=>assert_equals(
      exp = ls_exp
      act = ls_act ).

  ENDMETHOD.

  METHOD filter_duplicates_deleted.

    given_result( |PROG;ZAG_UNIT_TEST;;/src/;zag_unit_test.prog.xml;;;;D| ).

    when_filter_is_applied( ).

    cl_abap_unit_assert=>assert_equals(
      exp = 0
      act = lines( mt_result ) ).

  ENDMETHOD.

  METHOD given_result.

    DATA: ls_result LIKE LINE OF mt_result.

    SPLIT iv_result_line
      AT ';'
      INTO ls_result-obj_type
           ls_result-obj_name
           ls_result-inactive
           ls_result-path
           ls_result-filename
           ls_result-package
           ls_result-match
           ls_result-lstate
           ls_result-rstate.

    INSERT ls_result INTO TABLE mt_result.

  ENDMETHOD.

  METHOD when_filter_is_applied.

    mt_result = mo_objects->filter_files_to_deserialize( mt_result ).

  ENDMETHOD.

ENDCLASS.

CLASS ltcl_prio_deserialization DEFINITION FINAL FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PRIVATE SECTION.
    METHODS:
      setup,
      ddls_before_dcls FOR TESTING RAISING cx_static_check,
      webi_before_sprx FOR TESTING RAISING cx_static_check,
      iasp_before_isrp FOR TESTING RAISING cx_static_check,
      iobj_before_odso FOR TESTING RAISING cx_static_check,
      tobj_before_scp1 FOR TESTING RAISING cx_static_check,
      otgr_before_char FOR TESTING RAISING cx_static_check,
      sprx_before_clas FOR TESTING RAISING cx_static_check,
      sprx_before_intf FOR TESTING RAISING cx_static_check,
      sprx_before_tabl FOR TESTING RAISING cx_static_check,
      pinf_before_devc FOR TESTING RAISING cx_static_check,
      clas_before_pinf FOR TESTING RAISING cx_static_check,
      enhs_before_ensc FOR TESTING RAISING cx_static_check,
      ensc_before_enho FOR TESTING RAISING cx_static_check,
      enho_before_enhc FOR TESTING RAISING cx_static_check,
      xslt_before_clas FOR TESTING RAISING cx_static_check,
      xslt_before_prog FOR TESTING RAISING cx_static_check,

      given
        IMPORTING
          iv_object_type TYPE string,
      when_deser_is_priorized,
      then
        IMPORTING
          iv_exp_object_type TYPE string.

    DATA:
      mo_objects          TYPE REF TO zcl_abapgit_file_deserialize,
      mt_input            TYPE zif_abapgit_definitions=>ty_results_tt,
      mt_output           TYPE zif_abapgit_definitions=>ty_results_tt,
      mv_counter          TYPE i,
      mv_exp_output_tabix TYPE i.

ENDCLASS.

CLASS ltcl_prio_deserialization IMPLEMENTATION.

  METHOD setup.
    CREATE OBJECT mo_objects.
    mv_exp_output_tabix = 0.
  ENDMETHOD.

  METHOD enhs_before_ensc.
    given( 'ENSC' ).
    given( 'ENHS' ).
    when_deser_is_priorized( ).
    then( 'ENHS' ).
    then( 'ENSC' ).
  ENDMETHOD.

  METHOD ensc_before_enho.
    given( 'ENHO' ).
    given( 'ENSC' ).
    when_deser_is_priorized( ).
    then( 'ENSC' ).
    then( 'ENHO' ).
  ENDMETHOD.

  METHOD enho_before_enhc.
    given( 'ENHC' ).
    given( 'ENHO' ).
    when_deser_is_priorized( ).
    then( 'ENHO' ).
    then( 'ENHC' ).
  ENDMETHOD.

  METHOD sprx_before_clas.
    given( 'CLAS' ).
    given( 'SPRX' ).
    when_deser_is_priorized( ).
    then( 'SPRX' ).
    then( 'CLAS' ).
  ENDMETHOD.

  METHOD sprx_before_intf.
    given( 'INTF' ).
    given( 'SPRX' ).
    when_deser_is_priorized( ).
    then( 'SPRX' ).
    then( 'INTF' ).
  ENDMETHOD.

  METHOD sprx_before_tabl.
    given( 'TABL' ).
    given( 'SPRX' ).
    when_deser_is_priorized( ).
    then( 'SPRX' ).
    then( 'TABL' ).
  ENDMETHOD.

  METHOD otgr_before_char.
    given( 'CHAR' ).
    given( 'OTGR' ).
    when_deser_is_priorized( ).
    then( 'OTGR' ).
    then( 'CHAR' ).
  ENDMETHOD.

  METHOD pinf_before_devc.
    given( 'DEVC' ).
    given( 'PINF' ).
    when_deser_is_priorized( ).
    then( 'PINF' ).
    then( 'DEVC' ).
  ENDMETHOD.

  METHOD tobj_before_scp1.
    given( 'SCP1' ).
    given( 'TOBJ' ).
    when_deser_is_priorized( ).
    then( 'TOBJ' ).
    then( 'SCP1' ).
  ENDMETHOD.

  METHOD iobj_before_odso.
    given( 'ODSO' ).
    given( 'IOBJ' ).
    when_deser_is_priorized( ).
    then( 'IOBJ' ).
    then( 'ODSO' ).
  ENDMETHOD.

  METHOD iasp_before_isrp.
    given( 'ISRP' ).
    given( 'IASP' ).
    when_deser_is_priorized( ).
    then( 'IASP' ).
    then( 'ISRP' ).
  ENDMETHOD.

  METHOD webi_before_sprx.
    given( 'SPRX' ).
    given( 'WEBI' ).
    when_deser_is_priorized( ).
    then( 'WEBI' ).
    then( 'SPRX' ).
  ENDMETHOD.

  METHOD clas_before_pinf.
    given( 'PINF' ).
    given( 'CLAS' ).
    when_deser_is_priorized( ).
    then( 'CLAS' ).
    then( 'PINF' ).
  ENDMETHOD.

  METHOD xslt_before_clas.
    given( 'XSLT' ).
    given( 'INTF' ).
    given( 'CLAS' ).
    when_deser_is_priorized( ).
    then( 'XSLT' ).
    then( 'INTF' ).
    then( 'CLAS' ).
  ENDMETHOD.

  METHOD xslt_before_prog.
    given( 'PROG' ).
    given( 'XSLT' ).
    when_deser_is_priorized( ).
    then( 'XSLT' ).
    then( 'PROG' ).
  ENDMETHOD.

  METHOD ddls_before_dcls.
    given( 'DCLS' ).
    given( 'DDLS' ).
    given( 'DCLS' ).
    given( 'DDLS' ).
    when_deser_is_priorized( ).
    then( 'DDLS' ).
    then( 'DDLS' ).
    then( 'DCLS' ).
    then( 'DCLS' ).
  ENDMETHOD.

  METHOD given.

    DATA ls_input LIKE LINE OF mt_input.
    ls_input-obj_type = iv_object_type.
    ls_input-obj_name = mv_counter.
    INSERT ls_input INTO TABLE mt_input.
    mv_counter = mv_counter + 1.

  ENDMETHOD.

  METHOD when_deser_is_priorized.

    DATA lo_log TYPE REF TO zcl_abapgit_log.

    CREATE OBJECT lo_log.

    mt_output = mo_objects->prioritize_deser(
      ii_log     = lo_log
      it_results = mt_input ).

  ENDMETHOD.

  METHOD then.

    DATA: ls_output LIKE LINE OF mt_output.

    mv_exp_output_tabix = mv_exp_output_tabix + 1.

    READ TABLE mt_output INTO ls_output INDEX mv_exp_output_tabix.

    cl_abap_unit_assert=>assert_equals(
      exp = iv_exp_object_type
      act = ls_output-obj_type ).

  ENDMETHOD.

ENDCLASS.

add unit test xslt_before_prog (#5268)

add unit test xslt_before_prog (#5268)

ref #5262


CLASS zcl_abapgit_default_task DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    CLASS-METHODS:
      get_instance
        RETURNING
          VALUE(ro_instance) TYPE REF TO zcl_abapgit_default_task
        RAISING
          zcx_abapgit_exception.

    METHODS:
      constructor
        RAISING
          zcx_abapgit_exception,

      set
        IMPORTING
          iv_package TYPE devclass
        RAISING
          zcx_abapgit_exception,

      reset
        RAISING
          zcx_abapgit_exception.

  PRIVATE SECTION.
    CLASS-DATA: mo_instance TYPE REF TO zcl_abapgit_default_task.

    DATA: mv_task_is_set_by_abapgit TYPE abap_bool,
          ms_save_default_task      TYPE e070use.

    METHODS restore_old_default_task
              RAISING
                zcx_abapgit_exception.

ENDCLASS.

CLASS zcl_abapgit_default_task IMPLEMENTATION.

  METHOD constructor.

    DATA: lt_e070use TYPE STANDARD TABLE OF e070use.

    " Save the current default task to restore it later...
    CALL FUNCTION 'TR_TASK_GET'
      TABLES
        tt_e070use       = lt_e070use     " Table of current settings
      EXCEPTIONS
        invalid_username = 1
        invalid_category = 2
        invalid_client   = 3
        OTHERS           = 4.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_GET { sy-subrc }| ).
    ENDIF.

    IF lines( lt_e070use ) = 0.
      RETURN.
    ENDIF.

    READ TABLE lt_e070use INTO ms_save_default_task
                          INDEX 1.

  ENDMETHOD.

  METHOD get_instance.

    IF mo_instance IS NOT BOUND.

      CREATE OBJECT mo_instance.

    ENDIF.

    ro_instance = mo_instance.

  ENDMETHOD.

  METHOD reset.

    DATA: lt_e070use TYPE STANDARD TABLE OF e070use.

    CHECK mv_task_is_set_by_abapgit = abap_true.

    CALL FUNCTION 'TR_TASK_GET'
      TABLES
        tt_e070use       = lt_e070use    " Table of current settings
      EXCEPTIONS
        invalid_username = 1
        invalid_category = 2
        invalid_client   = 3
        OTHERS           = 4.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_GET { sy-subrc }| ).
    ENDIF.

    READ TABLE lt_e070use ASSIGNING FIELD-SYMBOL(<ls_e070use>)
                          INDEX 1.
    ASSERT sy-subrc = 0.

    CALL FUNCTION 'TR_TASK_RESET'
      EXPORTING
        iv_username      = <ls_e070use>-username
        iv_order         = <ls_e070use>-ordernum
        iv_task          = <ls_e070use>-tasknum
        iv_dialog        = abap_false
      EXCEPTIONS
        invalid_username = 1
        invalid_order    = 2
        invalid_task     = 3
        OTHERS           = 4.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_RESET { sy-subrc }| ).
    ENDIF.

    restore_old_default_task( ).

  ENDMETHOD.

  METHOD set.

    DATA: li_package TYPE REF TO if_package,
          lt_e071    TYPE STANDARD TABLE OF e071,
          lt_e071k   TYPE STANDARD TABLE OF e071k,
          lv_order   TYPE trkorr,
          lv_task    TYPE trkorr.

    CHECK mv_task_is_set_by_abapgit = abap_false.

    " checks whether object changes of the package are rerorded in transport
    " requests. If true then we set the default task, so that no annoying
    " transport request popups are shown while deserializing.

    cl_package_factory=>load_package(
      EXPORTING
        i_package_name             = iv_package
      IMPORTING
        e_package                  = li_package
      EXCEPTIONS
        object_not_existing        = 1
        unexpected_error           = 2
        intern_err                 = 3
        no_access                  = 4
        object_locked_and_modified = 5
        OTHERS                     = 6 ).

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from CL_PACKAGE_FACTORY=>LOAD_PACKAGE { sy-subrc }| ).
    ENDIF.

    IF li_package->wbo_korr_flag = abap_false.
      " Objects of package are not recorded in transport request,
      " no need to proceed.
      RETURN.
    ENDIF.

    CALL FUNCTION 'TRINT_ORDER_CHOICE'
      IMPORTING
        we_order               = lv_order     " Selected request
        we_task                = lv_task    " Selected task
      TABLES
        wt_e071                = lt_e071    " Object table to be edited (for mass editing)
        wt_e071k               = lt_e071k    " Key table to be edited (for mass editing)
      EXCEPTIONS
        no_correction_selected = 1
        display_mode           = 2
        object_append_error    = 3
        recursive_call         = 4
        wrong_order_type       = 5
        OTHERS                 = 6.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TRINT_ORDER_CHOICE { sy-subrc }| ).
    ENDIF.

    CALL FUNCTION 'TR_TASK_SET'
      EXPORTING
        iv_order          = lv_order    " Request to be s et
        iv_task           = lv_task    " Task to be set
      EXCEPTIONS
        invalid_username  = 1
        invalid_category  = 2
        invalid_client    = 3
        invalid_validdays = 4
        invalid_order     = 5
        invalid_task      = 6
        OTHERS            = 7.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_SET { sy-subrc }| ).
    ENDIF.

    mv_task_is_set_by_abapgit = abap_true.

  ENDMETHOD.

  METHOD restore_old_default_task.

    CHECK ms_save_default_task IS NOT INITIAL.

    CALL FUNCTION 'TR_TASK_SET'
      EXPORTING
        iv_order          = ms_save_default_task-ordernum    " Request to be s et
        iv_task           = ms_save_default_task-tasknum    " Task to be set
      EXCEPTIONS
        invalid_username  = 1
        invalid_category  = 2
        invalid_client    = 3
        invalid_validdays = 4
        invalid_order     = 5
        invalid_task      = 6
        OTHERS            = 7.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_SET { sy-subrc }| ).
    ENDIF.

  ENDMETHOD.

ENDCLASS.

CLASS zcl_abapgit_default_task DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    CLASS-METHODS:
      get_instance
        RETURNING
          VALUE(ro_instance) TYPE REF TO zcl_abapgit_default_task
        RAISING
          zcx_abapgit_exception.

    METHODS:
      constructor
        RAISING
          zcx_abapgit_exception,

      set
        IMPORTING
          iv_package TYPE devclass
        RAISING
          zcx_abapgit_exception,

      reset
        RAISING
          zcx_abapgit_exception.

  PRIVATE SECTION.
    CLASS-DATA: mo_instance TYPE REF TO zcl_abapgit_default_task.

    DATA: mv_task_is_set_by_abapgit TYPE abap_bool,
          ms_save_default_task      TYPE e070use.

    METHODS restore_old_default_task
      RAISING
        zcx_abapgit_exception.

ENDCLASS.

CLASS zcl_abapgit_default_task IMPLEMENTATION.

  METHOD constructor.

    DATA: lt_e070use TYPE STANDARD TABLE OF e070use.

    " Save the current default task to restore it later...
    CALL FUNCTION 'TR_TASK_GET'
      TABLES
        tt_e070use       = lt_e070use     " Table of current settings
      EXCEPTIONS
        invalid_username = 1
        invalid_category = 2
        invalid_client   = 3
        OTHERS           = 4.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_GET { sy-subrc }| ).
    ENDIF.

    IF lines( lt_e070use ) = 0.
      RETURN.
    ENDIF.

    READ TABLE lt_e070use INTO ms_save_default_task
                          INDEX 1.

  ENDMETHOD.

  METHOD get_instance.

    IF mo_instance IS NOT BOUND.

      CREATE OBJECT mo_instance.

    ENDIF.

    ro_instance = mo_instance.

  ENDMETHOD.

  METHOD reset.

    DATA: lt_e070use TYPE STANDARD TABLE OF e070use.

    IF mv_task_is_set_by_abapgit = abap_false.
      " if the default transport request task isn't set
      " by us there is nothing to do.
      RETURN.
    ENDIF.

    CALL FUNCTION 'TR_TASK_GET'
      TABLES
        tt_e070use       = lt_e070use    " Table of current settings
      EXCEPTIONS
        invalid_username = 1
        invalid_category = 2
        invalid_client   = 3
        OTHERS           = 4.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_GET { sy-subrc }| ).
    ENDIF.

    READ TABLE lt_e070use ASSIGNING FIELD-SYMBOL(<ls_e070use>)
                          INDEX 1.
    ASSERT sy-subrc = 0.

    CALL FUNCTION 'TR_TASK_RESET'
      EXPORTING
        iv_username      = <ls_e070use>-username
        iv_order         = <ls_e070use>-ordernum
        iv_task          = <ls_e070use>-tasknum
        iv_dialog        = abap_false
      EXCEPTIONS
        invalid_username = 1
        invalid_order    = 2
        invalid_task     = 3
        OTHERS           = 4.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_RESET { sy-subrc }| ).
    ENDIF.

    restore_old_default_task( ).

  ENDMETHOD.

  METHOD set.

    " checks whether object changes of the package are rerorded in transport
    " requests. If true then we set the default task, so that no annoying
    " transport request popups are shown while deserializing.

    DATA: li_package TYPE REF TO if_package,
          lt_e071    TYPE STANDARD TABLE OF e071,
          lt_e071k   TYPE STANDARD TABLE OF e071k,
          lv_order   TYPE trkorr,
          lv_task    TYPE trkorr.

    IF mv_task_is_set_by_abapgit = abap_true.
      " the default transport request task is already set by us
      " -> no reason to do it again.
      RETURN.
    ENDIF.

    cl_package_factory=>load_package(
      EXPORTING
        i_package_name             = iv_package
      IMPORTING
        e_package                  = li_package
      EXCEPTIONS
        object_not_existing        = 1
        unexpected_error           = 2
        intern_err                 = 3
        no_access                  = 4
        object_locked_and_modified = 5
        OTHERS                     = 6 ).

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from CL_PACKAGE_FACTORY=>LOAD_PACKAGE { sy-subrc }| ).
    ENDIF.

    IF li_package->wbo_korr_flag = abap_false.
      " Objects of package are not recorded in transport request,
      " no need to proceed.
      RETURN.
    ENDIF.

    CALL FUNCTION 'TRINT_ORDER_CHOICE'
      IMPORTING
        we_order               = lv_order     " Selected request
        we_task                = lv_task    " Selected task
      TABLES
        wt_e071                = lt_e071    " Object table to be edited (for mass editing)
        wt_e071k               = lt_e071k    " Key table to be edited (for mass editing)
      EXCEPTIONS
        no_correction_selected = 1
        display_mode           = 2
        object_append_error    = 3
        recursive_call         = 4
        wrong_order_type       = 5
        OTHERS                 = 6.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TRINT_ORDER_CHOICE { sy-subrc }| ).
    ENDIF.

    CALL FUNCTION 'TR_TASK_SET'
      EXPORTING
        iv_order          = lv_order    " Request to be s et
        iv_task           = lv_task    " Task to be set
      EXCEPTIONS
        invalid_username  = 1
        invalid_category  = 2
        invalid_client    = 3
        invalid_validdays = 4
        invalid_order     = 5
        invalid_task      = 6
        OTHERS            = 7.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_SET { sy-subrc }| ).
    ENDIF.

    mv_task_is_set_by_abapgit = abap_true.

  ENDMETHOD.

  METHOD restore_old_default_task.

    IF ms_save_default_task IS INITIAL.
      " There wasn't a default transport request before
      " so we needn't restore anything.
      RETURN.
    ENDIF.

    CALL FUNCTION 'TR_TASK_SET'
      EXPORTING
        iv_order          = ms_save_default_task-ordernum    " Request to be s et
        iv_task           = ms_save_default_task-tasknum    " Task to be set
      EXCEPTIONS
        invalid_username  = 1
        invalid_category  = 2
        invalid_client    = 3
        invalid_validdays = 4
        invalid_order     = 5
        invalid_task      = 6
        OTHERS            = 7.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from TR_TASK_SET { sy-subrc }| ).
    ENDIF.

  ENDMETHOD.

ENDCLASS.

Fix linter errors

Fix linter errors


CLASS zcl_abapgit_object_wdca DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_objects_super
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES zif_abapgit_object .
  PROTECTED SECTION.
  PRIVATE SECTION.

    METHODS read
      EXPORTING
        !es_outline TYPE wdy_cfg_outline_data
        !et_data    TYPE wdy_cfg_persist_data_appl_tab
      RAISING
        zcx_abapgit_exception .
    METHODS save
      IMPORTING
        !is_outline TYPE wdy_cfg_outline_data
        !it_data    TYPE wdy_cfg_persist_data_appl_tab
        !iv_package TYPE devclass
      RAISING
        zcx_abapgit_exception .
    METHODS delete
      IMPORTING
        !iv_package TYPE devclass
      RAISING
        zcx_abapgit_exception .
    METHODS check
      IMPORTING
        !it_messages TYPE cts_messages
      RAISING
        zcx_abapgit_exception .
ENDCLASS.

CLASS ZCL_ABAPGIT_OBJECT_WDCA IMPLEMENTATION.

  METHOD check.

    FIELD-SYMBOLS: <ls_message> TYPE LINE OF cts_messages.

    LOOP AT it_messages ASSIGNING <ls_message> WHERE severity = 'E'.
      zcx_abapgit_exception=>raise( <ls_message>-text ).
    ENDLOOP.

  ENDMETHOD.

  METHOD delete.

    DATA:
      lo_cfg       TYPE REF TO cl_wdr_cfg_persistence_appl,
      lx_err       TYPE REF TO cx_wd_configuration,
      lt_messages  TYPE cts_messages,
      ls_key       TYPE wdy_config_key,
      ls_outline   TYPE wdy_cfg_outline_data,
      lv_operation TYPE i,
      lv_name      TYPE wdy_md_object_name,
      lv_exists    TYPE wdy_boolean,
      lv_transport TYPE trkorr.

    ls_key = ms_item-obj_name.

    TRY.
        CREATE OBJECT lo_cfg
          EXPORTING
            config_key  = ls_key
            object_name = lv_name.

        MOVE-CORRESPONDING ls_key TO ls_outline.

        lo_cfg->check_config_existent(
          EXPORTING
            i_outline_data       = ls_outline
            i_only_current_layer = abap_false
            i_is_original        = abap_true
          IMPORTING
            e_is_existent        = lv_exists ).

        IF lv_exists = abap_false.
          RETURN.
        ENDIF.

        lv_transport = zcl_abapgit_default_transport=>get_instance( )->get( )-ordernum.
        lo_cfg->set_transport( trkorr   = lv_transport
                               devclass = iv_package ).

        lv_operation = if_wdr_cfg_constants=>c_cts_operation-e_delete.
        " First call, check, second call, delete
        DO 2 TIMES.
          lo_cfg->do_next_step(
            IMPORTING
              e_messages = lt_messages
            CHANGING
              c_operation = lv_operation ).
          check( lt_messages ).
        ENDDO.

      CATCH cx_wd_configuration INTO lx_err.
        IF lx_err->textid = cx_wd_configuration=>conf_config_not_exist.
          RETURN.
        ELSE.
          zcx_abapgit_exception=>raise( 'WDCA, delete error:' && lx_err->get_text( ) ).
        ENDIF.
    ENDTRY.

  ENDMETHOD.

  METHOD read.

    DATA:
      lo_cfg    TYPE REF TO cl_wdr_cfg_persistence_appl,
      ls_key    TYPE wdy_config_key,
      lv_exists TYPE abap_bool,
      lx_err    TYPE REF TO cx_wd_configuration,
      lv_name   TYPE wdy_md_object_name.

    FIELD-SYMBOLS:
      <ls_data>        LIKE LINE OF et_data,
      <ls_appl_params> LIKE LINE OF <ls_data>-appl_params.

    CLEAR: es_outline, et_data.

    ls_key = ms_item-obj_name.

    TRY.
        CREATE OBJECT lo_cfg
          EXPORTING
            config_key  = ls_key
            object_name = lv_name.

        MOVE-CORRESPONDING ls_key TO es_outline.

        lo_cfg->check_config_existent(
          EXPORTING
            i_outline_data       = es_outline
            i_only_current_layer = abap_false
            i_is_original        = abap_true
          IMPORTING
            e_is_existent        = lv_exists ).

        IF lv_exists = abap_false.
          RETURN.
        ENDIF.

        es_outline = lo_cfg->read_outline_data( ).

        CLEAR: es_outline-devclass,
               es_outline-author,
               es_outline-createdon,
               es_outline-changedby,
               es_outline-changedon.

        et_data = lo_cfg->read_data( ).

        " Clear descriptions since they are release and language-specific
        LOOP AT et_data ASSIGNING <ls_data>.
          LOOP AT <ls_data>-appl_params ASSIGNING <ls_appl_params>.
            CLEAR <ls_appl_params>-description.
          ENDLOOP.
        ENDLOOP.

      CATCH cx_wd_configuration INTO lx_err.
        zcx_abapgit_exception=>raise( 'WDCA, read error:' && lx_err->get_text( ) ).
    ENDTRY.

  ENDMETHOD.

  METHOD save.

    DATA:
      lo_cfg       TYPE REF TO cl_wdr_cfg_persistence_appl,
      lx_err       TYPE REF TO cx_wd_configuration,
      lt_messages  TYPE cts_messages,
      ls_key       TYPE wdy_config_key,
      ls_data      LIKE LINE OF it_data,
      lv_operation TYPE i,
      lv_name      TYPE wdy_md_object_name,
      lv_exists    TYPE wdy_boolean,
      lv_transport TYPE trkorr.

    MOVE-CORRESPONDING is_outline TO ls_key.

    TRY.
        CREATE OBJECT lo_cfg
          EXPORTING
            config_key  = ls_key
            object_name = lv_name.

        READ TABLE it_data INDEX 1 INTO ls_data.
        ASSERT sy-subrc = 0.

        lo_cfg->check_config_existent(
          EXPORTING
            i_outline_data       = is_outline
            i_only_current_layer = abap_false
            i_is_original        = abap_true
          IMPORTING
            e_is_existent        = lv_exists ).

      CATCH cx_wd_configuration ##NO_HANDLER.
        " Ignore
    ENDTRY.

    TRY.
        lv_transport = zcl_abapgit_default_transport=>get_instance( )->get( )-ordernum.
        lo_cfg->set_transport( trkorr   = lv_transport
                               devclass = iv_package ).
        lo_cfg->set_save_data( ls_data ).
        lo_cfg->set_config_description( is_outline ).

        IF lv_exists = abap_false.
          lv_operation = if_wdr_cfg_constants=>c_cts_operation-e_create.
        ELSE.
          lv_operation = if_wdr_cfg_constants=>c_cts_operation-e_save.
        ENDIF.

        " First call, check, second call, create/save
        DO 2 TIMES.
          lo_cfg->do_next_step(
            IMPORTING
              e_messages  = lt_messages
            CHANGING
              c_operation = lv_operation ).
          check( lt_messages ).
        ENDDO.

      CATCH cx_wd_configuration INTO lx_err.
        zcx_abapgit_exception=>raise( 'WDCA, save error:' && lx_err->get_text( ) ).
    ENDTRY.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    DATA ls_key TYPE wdy_config_key.

    ls_key = ms_item-obj_name.

    SELECT SINGLE changedby FROM wdy_config_appl INTO rv_user
      WHERE config_id = ls_key-config_id AND config_type = ls_key-config_type AND config_var = ls_key-config_var.
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    delete( iv_package = iv_package ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: ls_outline TYPE wdy_cfg_outline_data,
          lt_data    TYPE wdy_cfg_persist_data_appl_tab.

    io_xml->read( EXPORTING iv_name = 'OUTLINE'
                  CHANGING  cg_data = ls_outline ).
    io_xml->read( EXPORTING iv_name = 'DATA'
                  CHANGING  cg_data = lt_data ).

    save( is_outline = ls_outline
          it_data    = lt_data
          iv_package = iv_package ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.
    DATA: ls_wdy_config_appl TYPE wdy_config_appl.
    DATA: ls_wdy_config_key TYPE wdy_config_key.

    ls_wdy_config_key = ms_item-obj_name.
    SELECT SINGLE * FROM wdy_config_appl
      INTO ls_wdy_config_appl
      WHERE config_id = ls_wdy_config_key-config_id
        AND config_type = ls_wdy_config_key-config_type
        AND config_var = ls_wdy_config_key-config_var.  "#EC CI_GENBUFF
    rv_bool = boolc( sy-subrc = 0 ).
  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    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.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    CALL FUNCTION 'RS_TOOL_ACCESS'
      EXPORTING
        operation     = 'SHOW'
        object_name   = ms_item-obj_name
        object_type   = ms_item-obj_type
        in_new_window = abap_true.

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: ls_outline TYPE wdy_cfg_outline_data,
          lt_data    TYPE wdy_cfg_persist_data_appl_tab.

    read( IMPORTING es_outline = ls_outline
                    et_data    = lt_data ).

    IF ls_outline IS INITIAL.
      RETURN.
    ENDIF.

    io_xml->add( iv_name = 'OUTLINE'
                 ig_data = ls_outline ).
    io_xml->add( iv_name = 'DATA'
                 ig_data = lt_data ).

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_object_wdca DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_objects_super
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES zif_abapgit_object .
    ALIASES mo_files
      FOR zif_abapgit_object~mo_files .
  PROTECTED SECTION.
  PRIVATE SECTION.

    METHODS read
      EXPORTING
        !es_outline TYPE wdy_cfg_outline_data
        !et_data    TYPE wdy_cfg_persist_data_appl_tab
      RAISING
        zcx_abapgit_exception .
    METHODS save
      IMPORTING
        !is_outline TYPE wdy_cfg_outline_data
        !it_data    TYPE wdy_cfg_persist_data_appl_tab
        !iv_package TYPE devclass
      RAISING
        zcx_abapgit_exception .
    METHODS delete
      IMPORTING
        !iv_package TYPE devclass
      RAISING
        zcx_abapgit_exception .
    METHODS check
      IMPORTING
        !it_messages TYPE cts_messages
      RAISING
        zcx_abapgit_exception .
ENDCLASS.

CLASS ZCL_ABAPGIT_OBJECT_WDCA IMPLEMENTATION.

  METHOD check.

    FIELD-SYMBOLS: <ls_message> TYPE LINE OF cts_messages.

    LOOP AT it_messages ASSIGNING <ls_message> WHERE severity = 'E'.
      zcx_abapgit_exception=>raise( <ls_message>-text ).
    ENDLOOP.

  ENDMETHOD.

  METHOD delete.

    DATA:
      lo_cfg       TYPE REF TO cl_wdr_cfg_persistence_appl,
      lx_err       TYPE REF TO cx_wd_configuration,
      lt_messages  TYPE cts_messages,
      ls_key       TYPE wdy_config_key,
      ls_outline   TYPE wdy_cfg_outline_data,
      lv_operation TYPE i,
      lv_name      TYPE wdy_md_object_name,
      lv_exists    TYPE wdy_boolean,
      lv_transport TYPE trkorr.

    ls_key = ms_item-obj_name.

    TRY.
        CREATE OBJECT lo_cfg
          EXPORTING
            config_key  = ls_key
            object_name = lv_name.

        MOVE-CORRESPONDING ls_key TO ls_outline.

        lo_cfg->check_config_existent(
          EXPORTING
            i_outline_data       = ls_outline
            i_only_current_layer = abap_false
            i_is_original        = abap_true
          IMPORTING
            e_is_existent        = lv_exists ).

        IF lv_exists = abap_false.
          RETURN.
        ENDIF.

        lv_transport = zcl_abapgit_default_transport=>get_instance( )->get( )-ordernum.
        lo_cfg->set_transport( trkorr   = lv_transport
                               devclass = iv_package ).

        lv_operation = if_wdr_cfg_constants=>c_cts_operation-e_delete.
        " First call, check, second call, delete
        DO 2 TIMES.
          lo_cfg->do_next_step(
            IMPORTING
              e_messages = lt_messages
            CHANGING
              c_operation = lv_operation ).
          check( lt_messages ).
        ENDDO.

      CATCH cx_wd_configuration INTO lx_err.
        IF lx_err->textid = cx_wd_configuration=>conf_config_not_exist.
          RETURN.
        ELSE.
          zcx_abapgit_exception=>raise( 'WDCA, delete error:' && lx_err->get_text( ) ).
        ENDIF.
    ENDTRY.

  ENDMETHOD.

  METHOD read.

    DATA:
      lo_cfg    TYPE REF TO cl_wdr_cfg_persistence_appl,
      ls_key    TYPE wdy_config_key,
      lv_exists TYPE abap_bool,
      lx_err    TYPE REF TO cx_wd_configuration,
      lv_name   TYPE wdy_md_object_name.

    FIELD-SYMBOLS:
      <ls_data>        LIKE LINE OF et_data,
      <ls_appl_params> LIKE LINE OF <ls_data>-appl_params.

    CLEAR: es_outline, et_data.

    ls_key = ms_item-obj_name.

    TRY.
        CREATE OBJECT lo_cfg
          EXPORTING
            config_key  = ls_key
            object_name = lv_name.

        MOVE-CORRESPONDING ls_key TO es_outline.

        lo_cfg->check_config_existent(
          EXPORTING
            i_outline_data       = es_outline
            i_only_current_layer = abap_false
            i_is_original        = abap_true
          IMPORTING
            e_is_existent        = lv_exists ).

        IF lv_exists = abap_false.
          RETURN.
        ENDIF.

        es_outline = lo_cfg->read_outline_data( ).

        CLEAR: es_outline-devclass,
               es_outline-author,
               es_outline-createdon,
               es_outline-changedby,
               es_outline-changedon.

        et_data = lo_cfg->read_data( ).

        " Clear descriptions since they are release and language-specific
        LOOP AT et_data ASSIGNING <ls_data>.
          LOOP AT <ls_data>-appl_params ASSIGNING <ls_appl_params>.
            CLEAR <ls_appl_params>-description.
          ENDLOOP.
        ENDLOOP.

      CATCH cx_wd_configuration INTO lx_err.
        zcx_abapgit_exception=>raise( 'WDCA, read error:' && lx_err->get_text( ) ).
    ENDTRY.

  ENDMETHOD.

  METHOD save.

    DATA:
      lo_cfg       TYPE REF TO cl_wdr_cfg_persistence_appl,
      lx_err       TYPE REF TO cx_wd_configuration,
      lt_messages  TYPE cts_messages,
      ls_key       TYPE wdy_config_key,
      ls_data      LIKE LINE OF it_data,
      lv_operation TYPE i,
      lv_name      TYPE wdy_md_object_name,
      lv_exists    TYPE wdy_boolean,
      lv_transport TYPE trkorr.

    MOVE-CORRESPONDING is_outline TO ls_key.

    TRY.
        CREATE OBJECT lo_cfg
          EXPORTING
            config_key  = ls_key
            object_name = lv_name.

        READ TABLE it_data INDEX 1 INTO ls_data.
        ASSERT sy-subrc = 0.

        lo_cfg->check_config_existent(
          EXPORTING
            i_outline_data       = is_outline
            i_only_current_layer = abap_false
            i_is_original        = abap_true
          IMPORTING
            e_is_existent        = lv_exists ).

      CATCH cx_wd_configuration ##NO_HANDLER.
        " Ignore
    ENDTRY.

    TRY.
        lv_transport = zcl_abapgit_default_transport=>get_instance( )->get( )-ordernum.
        lo_cfg->set_transport( trkorr   = lv_transport
                               devclass = iv_package ).
        lo_cfg->set_save_data( ls_data ).
        lo_cfg->set_config_description( is_outline ).

        IF lv_exists = abap_false.
          lv_operation = if_wdr_cfg_constants=>c_cts_operation-e_create.
        ELSE.
          lv_operation = if_wdr_cfg_constants=>c_cts_operation-e_save.
        ENDIF.

        " First call, check, second call, create/save
        DO 2 TIMES.
          lo_cfg->do_next_step(
            IMPORTING
              e_messages  = lt_messages
            CHANGING
              c_operation = lv_operation ).
          check( lt_messages ).
        ENDDO.

      CATCH cx_wd_configuration INTO lx_err.
        zcx_abapgit_exception=>raise( 'WDCA, save error:' && lx_err->get_text( ) ).
    ENDTRY.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    DATA ls_key TYPE wdy_config_key.

    ls_key = ms_item-obj_name.

    SELECT SINGLE changedby FROM wdy_config_appl INTO rv_user
      WHERE config_id = ls_key-config_id AND config_type = ls_key-config_type AND config_var = ls_key-config_var.
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    delete( iv_package = iv_package ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: ls_outline     TYPE wdy_cfg_outline_data,
          lt_data        TYPE wdy_cfg_persist_data_appl_tab,
          lt_config_appt TYPE TABLE OF wdy_config_appt,
          lv_xml_string  TYPE string,
          lv_xml_xstring TYPE xstring.

    io_xml->read( EXPORTING iv_name = 'OUTLINE'
                  CHANGING  cg_data = ls_outline ).
    io_xml->read( EXPORTING iv_name = 'DATA'
                  CHANGING  cg_data = lt_data ).

    save( is_outline = ls_outline
          it_data    = lt_data
          iv_package = iv_package ).

    TRY.
        lv_xml_string = mo_files->read_string( iv_extra = 'appl_config'
                                               iv_ext   = 'xml' ).
        TRY.
            lv_xml_string = zcl_abapgit_xml_pretty=>print( iv_xml           = lv_xml_string
                                                           iv_ignore_errors = abap_false
                                                           iv_unpretty      = abap_true ).
          CATCH zcx_abapgit_exception.
            zcx_abapgit_exception=>raise( 'Error Un-Pretty Printing WDCA XML Content: ' && ms_item-obj_name ).
        ENDTRY.

        REPLACE FIRST OCCURRENCE
          OF REGEX '<\?xml version="1\.0" encoding="[\w-]+"\?>'
          IN lv_xml_string
          WITH '<?xml version="1.0"?>'.
        ASSERT sy-subrc = 0.

        lv_xml_xstring = zcl_abapgit_convert=>string_to_xstring( iv_str = lv_xml_string ).
        UPDATE wdy_config_appl
          SET xcontent = lv_xml_xstring
          WHERE config_id   = ls_outline-config_id
            AND config_type = ls_outline-config_type
            AND config_var  = ls_outline-config_var.
      CATCH zcx_abapgit_exception.
        " File not found
    ENDTRY.

    io_xml->read( EXPORTING iv_name = 'DESCR_LANG'
                  CHANGING  cg_data = lt_config_appt ).

    IF lt_config_appt IS NOT INITIAL.
      DELETE FROM wdy_config_appt
        WHERE config_id   = ls_outline-config_id
          AND config_type = ls_outline-config_type
          AND config_var  = ls_outline-config_var.
      MODIFY wdy_config_appt FROM TABLE lt_config_appt.
      IF sy-subrc <> 0.
        zcx_abapgit_exception=>raise( 'Error Updating WDY_CONFIG_APPT for Component Config ' && ms_item-obj_name ).
      ENDIF.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.
    DATA: ls_wdy_config_appl TYPE wdy_config_appl.
    DATA: ls_wdy_config_key TYPE wdy_config_key.

    ls_wdy_config_key = ms_item-obj_name.
    SELECT SINGLE * FROM wdy_config_appl
      INTO ls_wdy_config_appl
      WHERE config_id = ls_wdy_config_key-config_id
        AND config_type = ls_wdy_config_key-config_type
        AND config_var = ls_wdy_config_key-config_var.  "#EC CI_GENBUFF
    rv_bool = boolc( sy-subrc = 0 ).
  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    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.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    CALL FUNCTION 'RS_TOOL_ACCESS'
      EXPORTING
        operation     = 'SHOW'
        object_name   = ms_item-obj_name
        object_type   = ms_item-obj_type
        in_new_window = abap_true.

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: ls_outline     TYPE wdy_cfg_outline_data,
          lt_data        TYPE wdy_cfg_persist_data_appl_tab,
          lt_cc_text     TYPE TABLE OF wdy_config_appt,
          lv_xml_xstring TYPE xstring,
          lv_xml_string  TYPE string.

    read( IMPORTING es_outline = ls_outline
                    et_data    = lt_data ).

    IF ls_outline IS INITIAL.
      RETURN.
    ENDIF.

    io_xml->add( iv_name = 'OUTLINE'
                 ig_data = ls_outline ).
    io_xml->add( iv_name = 'DATA'
                 ig_data = lt_data ).

    SELECT SINGLE xcontent
      INTO lv_xml_xstring
      FROM wdy_config_appl
      WHERE config_id = ls_outline-config_id
        AND config_type = ls_outline-config_type
        AND config_var = ls_outline-config_var.
    lv_xml_string = zcl_abapgit_convert=>xstring_to_string_utf8( iv_data = lv_xml_xstring ).
    IF lv_xml_string IS NOT INITIAL.
      TRY.
          lv_xml_string = zcl_abapgit_xml_pretty=>print(
            iv_xml           = lv_xml_string
            iv_ignore_errors = abap_false ).
        CATCH zcx_abapgit_exception.
          zcx_abapgit_exception=>raise( 'Error Pretty Printing WDCA XML Content: ' && ms_item-obj_name ).
      ENDTRY.

      REPLACE FIRST OCCURRENCE
        OF REGEX '<\?xml version="1\.0" encoding="[\w-]+"\?>'
        IN lv_xml_string
        WITH '<?xml version="1.0" encoding="utf-8"?>'.
      ASSERT sy-subrc = 0.
    ENDIF.

    mo_files->add_string( iv_extra  = 'appl_config'
                          iv_ext    = 'xml'
                          iv_string = lv_xml_string ).

    SELECT * FROM wdy_config_appt INTO TABLE lt_cc_text
      WHERE config_id   = ls_outline-config_id
      AND config_type = ls_outline-config_type
      AND config_var  = ls_outline-config_var
      ORDER BY PRIMARY KEY.
    IF lt_cc_text IS NOT INITIAL.
      io_xml->add( iv_name = 'DESCR_LANG'
                   ig_data = lt_cc_text ).
    ENDIF.

  ENDMETHOD.
ENDCLASS.

WDCA: Add support for appl. config content (#5030)

* object WDCA

object WDCA
+ wdy_config_appl-xcontent
+ wdy_config_appt

* Update zcl_abapgit_object_wdca.clas.abap

* Update src/objects/zcl_abapgit_object_wdca.clas.abap

Co-authored-by: abaplint[bot] <589dee37d0e82f3cabf9dea701e9ec2fd481eb1e@users.noreply.github.com>

* Update src/objects/zcl_abapgit_object_wdca.clas.abap

Co-authored-by: abaplint[bot] <589dee37d0e82f3cabf9dea701e9ec2fd481eb1e@users.noreply.github.com>

* Update zcl_abapgit_object_wdca.clas.abap

Co-authored-by: abaplint[bot] <589dee37d0e82f3cabf9dea701e9ec2fd481eb1e@users.noreply.github.com>
Co-authored-by: Lars Hvam <721d1b171982cd84b755f6b25130d2b88cd1f696@hotmail.com>