CLASS zcl_ags_repo DEFINITION
  PUBLIC
  CREATE PUBLIC .

  PUBLIC SECTION.

    TYPES:
      ty_branches_tt TYPE STANDARD TABLE OF REF TO zcl_ags_branch WITH DEFAULT KEY .

    CLASS-METHODS create
      IMPORTING
        !iv_name        TYPE zags_repos-name
        !iv_description TYPE zags_repos-description
      RETURNING
        VALUE(ro_repo)  TYPE REF TO zcl_ags_repo
      RAISING
        zcx_ags_error .
    CLASS-METHODS get_instance
      IMPORTING
        !iv_name       TYPE zags_repos-name
      RETURNING
        VALUE(ro_repo) TYPE REF TO zcl_ags_repo
      RAISING
        zcx_ags_error .
    CLASS-METHODS list
      RETURNING
        VALUE(rt_list) TYPE zags_repos_tt .
    METHODS constructor
      IMPORTING
        !iv_name TYPE zags_repos-name
      RAISING
        zcx_ags_error .
    METHODS create_branch
      IMPORTING
        !iv_name         TYPE zags_branches-name
        !iv_commit       TYPE zags_sha1
      RETURNING
        VALUE(ro_branch) TYPE REF TO zcl_ags_branch
      RAISING
        zcx_ags_error .
    METHODS delete
      RAISING
        zcx_ags_error .
    METHODS get_branch
      IMPORTING
        !iv_branch_name  TYPE zags_branch_name
      RETURNING
        VALUE(ro_branch) TYPE REF TO zcl_ags_branch
      RAISING
        zcx_ags_error .
    METHODS get_data
      RETURNING
        VALUE(rs_data) TYPE zags_repos .
    METHODS get_default_branch
      RETURNING
        VALUE(ro_branch) TYPE REF TO zcl_ags_branch
      RAISING
        zcx_ags_error .
    METHODS list_branches
      RETURNING
        VALUE(rt_list) TYPE ty_branches_tt
      RAISING
        zcx_ags_error .
    METHODS set_description
      IMPORTING
        !iv_description TYPE zags_repos-description
      RAISING
        zcx_ags_error .
  PROTECTED SECTION.
private section.

  data MS_DATA type ZAGS_REPOS .

  class-methods INITIAL_COMMIT
    importing
      !IV_REPO type ZAGS_REPOS-REPO
      !IV_NAME type CLIKE
    returning
      value(RV_COMMIT) type ZAGS_SHA1
    raising
      ZCX_AGS_ERROR .
ENDCLASS.

CLASS ZCL_AGS_REPO IMPLEMENTATION.

  METHOD constructor.

    ms_data = zcl_ags_db=>get_repos( )->single( iv_name ).

  ENDMETHOD.

  METHOD create.

    DATA: ls_repo TYPE zags_repos.

    ASSERT NOT iv_name CA '/\'.
    ASSERT NOT iv_name IS INITIAL.

    TRY.
        zcl_ags_db=>get_repos( )->single( iv_name ).
        RAISE EXCEPTION TYPE zcx_ags_error
          EXPORTING
            textid = zcx_ags_error=>m001.
      CATCH zcx_ags_error ##NO_HANDLER.
    ENDTRY.

    ls_repo-repo        = zcl_ags_util=>uuid( ).
    ls_repo-name        = iv_name.
    ls_repo-description = iv_description.
    ls_repo-head        = 'master' ##no_text.

    zcl_ags_db=>get_repos( )->insert( ls_repo ).

    ro_repo = get_instance( iv_name ).

    ro_repo->create_branch(
      iv_name   = ls_repo-head
      iv_commit = initial_commit(
        iv_repo = ls_repo-repo
        iv_name = iv_name ) ).

  ENDMETHOD.

  METHOD create_branch.

    DATA: ls_branch TYPE zags_branches.

* validate that iv_commit exists?
    zcl_ags_obj_commit=>get_instance(
      iv_repo = ms_data-repo
      iv_sha1 = iv_commit ).

    ls_branch-repo   = ms_data-repo.
    ls_branch-branch = zcl_ags_util=>uuid( ).
    ls_branch-name   = iv_name.
    ls_branch-sha1   = iv_commit.

    zcl_ags_db=>get_branches( )->insert( ls_branch ).

    ro_branch = get_branch( iv_name ).

  ENDMETHOD.

  METHOD delete.

    DATA: lt_branches TYPE ty_branches_tt.

    FIELD-SYMBOLS: <lo_branch> LIKE LINE OF lt_branches.

    lt_branches = list_branches( ).
    LOOP AT lt_branches ASSIGNING <lo_branch>.
      <lo_branch>->delete( ).
    ENDLOOP.

    zcl_ags_db=>get_repos( )->delete( ms_data-name ).

  ENDMETHOD.

  METHOD get_branch.

    DATA: lt_branches TYPE ty_branches_tt.

    lt_branches = list_branches( ).
    LOOP AT lt_branches INTO ro_branch.
      IF ro_branch->get_data( )-name = iv_branch_name.
        RETURN.
      ENDIF.
    ENDLOOP.

    ASSERT 0 = 1.

  ENDMETHOD.

  METHOD get_data.

    rs_data = ms_data.

  ENDMETHOD.

  METHOD get_default_branch.

    ro_branch = get_branch( ms_data-head ).

  ENDMETHOD.

  METHOD get_instance.

    CREATE OBJECT ro_repo
      EXPORTING
        iv_name = iv_name.

  ENDMETHOD.

  METHOD initial_commit.

    DATA: lo_blob   TYPE REF TO zcl_ags_obj_blob,
          lo_commit TYPE REF TO zcl_ags_obj_commit,
          lo_tree   TYPE REF TO zcl_ags_obj_tree,
          lv_str    TYPE string,
          lv_user   TYPE string.

    CREATE OBJECT lo_blob
      EXPORTING
        iv_repo = iv_repo.
    lv_str = iv_name.
    lo_blob->set_data( zcl_ags_util=>string_to_xstring_utf8( lv_str ) ).
    lo_blob->save( ).

    CREATE OBJECT lo_tree
      EXPORTING
        iv_repo = iv_repo.
    lo_tree->add_file( iv_chmod = zcl_ags_obj_tree=>c_chmod-file
                       iv_name  = 'README.md'
                       iv_sha1  = lo_blob->sha1( ) ) ##no_text.
    lo_tree->save( ).

    lv_user = |initial <foo@bar.com> { zcl_ags_util=>get_time( ) }|.

    CREATE OBJECT lo_commit
      EXPORTING
        iv_repo = iv_repo.
    lo_commit->set_tree( lo_tree->sha1( ) ).
    lo_commit->set_author( lv_user ).
    lo_commit->set_committer( lv_user ).
    lo_commit->set_body( 'initial' ) ##no_text.
    lo_commit->save( ).

    rv_commit = lo_commit->sha1( ).

  ENDMETHOD.

  METHOD list.

    rt_list = zcl_ags_db=>get_repos( )->list( ).

  ENDMETHOD.

  METHOD list_branches.

    DATA: lt_list   TYPE zags_branches_tt,
          lo_branch TYPE REF TO zcl_ags_branch.

    FIELD-SYMBOLS: <ls_list> LIKE LINE OF lt_list.

    lt_list = zcl_ags_db=>get_branches( )->list( ms_data-repo ).

    LOOP AT lt_list ASSIGNING <ls_list>.
      CREATE OBJECT lo_branch
        EXPORTING
          io_repo = me
          iv_name = <ls_list>-name.

      APPEND lo_branch TO rt_list.
    ENDLOOP.

  ENDMETHOD.

  METHOD set_description.

    zcl_ags_db=>get_repos( )->update_description(
      iv_repo        = ms_data-repo
      iv_description = iv_description ).

    ms_data-description = iv_description.

  ENDMETHOD.
ENDCLASS.

CLASS zcl_ags_repo DEFINITION
  PUBLIC
  CREATE PUBLIC .

  PUBLIC SECTION.

    TYPES:
      ty_branches_tt TYPE STANDARD TABLE OF REF TO zcl_ags_branch WITH DEFAULT KEY .

    CLASS-METHODS create
      IMPORTING
        !iv_name        TYPE zags_repos-name
        !iv_description TYPE zags_repos-description
      RETURNING
        VALUE(ro_repo)  TYPE REF TO zcl_ags_repo
      RAISING
        zcx_ags_error .
    CLASS-METHODS get_instance
      IMPORTING
        !iv_name       TYPE zags_repos-name
      RETURNING
        VALUE(ro_repo) TYPE REF TO zcl_ags_repo
      RAISING
        zcx_ags_error .
    CLASS-METHODS list
      RETURNING
        VALUE(rt_list) TYPE zags_repos_tt .
    METHODS constructor
      IMPORTING
        !iv_name TYPE zags_repos-name
      RAISING
        zcx_ags_error .
    METHODS create_branch
      IMPORTING
        !iv_name         TYPE zags_branches-name
        !iv_commit       TYPE zags_sha1
      RETURNING
        VALUE(ro_branch) TYPE REF TO zcl_ags_branch
      RAISING
        zcx_ags_error .
    METHODS delete
      RAISING
        zcx_ags_error .
    METHODS get_branch
      IMPORTING
        !iv_branch_name  TYPE zags_branch_name
      RETURNING
        VALUE(ro_branch) TYPE REF TO zcl_ags_branch
      RAISING
        zcx_ags_error .
    METHODS get_data
      RETURNING
        VALUE(rs_data) TYPE zags_repos .
    METHODS get_default_branch
      RETURNING
        VALUE(ro_branch) TYPE REF TO zcl_ags_branch
      RAISING
        zcx_ags_error .
    METHODS list_branches
      RETURNING
        VALUE(rt_list) TYPE ty_branches_tt
      RAISING
        zcx_ags_error .
    METHODS set_description
      IMPORTING
        !iv_description TYPE zags_repos-description
      RAISING
        zcx_ags_error .
  PROTECTED SECTION.
  PRIVATE SECTION.

    DATA ms_data TYPE zags_repos .

    CLASS-METHODS initial_commit
      IMPORTING
        !iv_repo         TYPE zags_repos-repo
        !iv_name         TYPE clike
      RETURNING
        VALUE(rv_commit) TYPE zags_sha1
      RAISING
        zcx_ags_error .
ENDCLASS.

CLASS ZCL_AGS_REPO IMPLEMENTATION.

  METHOD constructor.

    ms_data = zcl_ags_db=>get_repos( )->single( iv_name ).

  ENDMETHOD.

  METHOD create.

    DATA: ls_repo TYPE zags_repos.

    ASSERT NOT iv_name CA '/\'.
    ASSERT NOT iv_name IS INITIAL.

    TRY.
        zcl_ags_db=>get_repos( )->single( iv_name ).
        RAISE EXCEPTION TYPE zcx_ags_error
          EXPORTING
            textid = zcx_ags_error=>m001.
      CATCH zcx_ags_error ##NO_HANDLER.
    ENDTRY.

    ls_repo-repo        = zcl_ags_util=>uuid( ).
    ls_repo-name        = iv_name.
    ls_repo-description = iv_description.
    ls_repo-head        = 'master' ##no_text.

    zcl_ags_db=>get_repos( )->insert( ls_repo ).

    ro_repo = get_instance( iv_name ).

    ro_repo->create_branch(
      iv_name   = ls_repo-head
      iv_commit = initial_commit(
        iv_repo = ls_repo-repo
        iv_name = iv_name ) ).

  ENDMETHOD.

  METHOD create_branch.

    DATA: ls_branch TYPE zags_branches.

* validate that iv_commit exists?
    zcl_ags_obj_commit=>get_instance(
      iv_repo = ms_data-repo
      iv_sha1 = iv_commit ).

    ls_branch-repo   = ms_data-repo.
    ls_branch-branch = zcl_ags_util=>uuid( ).
    ls_branch-name   = iv_name.
    ls_branch-sha1   = iv_commit.

    zcl_ags_db=>get_branches( )->insert( ls_branch ).

    ro_branch = get_branch( iv_name ).

  ENDMETHOD.

  METHOD delete.

    DATA: lt_branches TYPE ty_branches_tt.

    FIELD-SYMBOLS: <lo_branch> LIKE LINE OF lt_branches.

    lt_branches = list_branches( ).
    LOOP AT lt_branches ASSIGNING <lo_branch>.
      <lo_branch>->delete( ).
    ENDLOOP.

    zcl_ags_db=>get_repos( )->delete( ms_data-name ).

  ENDMETHOD.

  METHOD get_branch.

    DATA: lt_branches TYPE ty_branches_tt.

    lt_branches = list_branches( ).
    LOOP AT lt_branches INTO ro_branch.
      IF ro_branch->get_data( )-name = iv_branch_name.
        RETURN.
      ENDIF.
    ENDLOOP.

    ASSERT 0 = 1.

  ENDMETHOD.

  METHOD get_data.

    rs_data = ms_data.

  ENDMETHOD.

  METHOD get_default_branch.

    ro_branch = get_branch( ms_data-head ).

  ENDMETHOD.

  METHOD get_instance.

    CREATE OBJECT ro_repo
      EXPORTING
        iv_name = iv_name.

  ENDMETHOD.

  METHOD initial_commit.

    DATA: lo_blob   TYPE REF TO zcl_ags_obj_blob,
          lo_commit TYPE REF TO zcl_ags_obj_commit,
          lo_tree   TYPE REF TO zcl_ags_obj_tree,
          lv_str    TYPE string,
          lv_user   TYPE string.

    CREATE OBJECT lo_blob
      EXPORTING
        iv_repo = iv_repo.
    lv_str = iv_name.
    lo_blob->set_data( zcl_ags_util=>string_to_xstring_utf8( lv_str ) ).
    lo_blob->save( ).

    CREATE OBJECT lo_tree
      EXPORTING
        iv_repo = iv_repo.
    lo_tree->add_file( iv_chmod = zcl_ags_obj_tree=>c_chmod-file
                       iv_name  = 'README.md'
                       iv_sha1  = lo_blob->sha1( ) ) ##no_text.
    lo_tree->save( ).

    lv_user = |initial <foo@bar.com> { zcl_ags_util=>get_time( ) }|.

    CREATE OBJECT lo_commit
      EXPORTING
        iv_repo = iv_repo.
    lo_commit->set_tree( lo_tree->sha1( ) ).
    lo_commit->set_author( lv_user ).
    lo_commit->set_committer( lv_user ).
    lo_commit->set_body( 'initial' ) ##no_text.
    lo_commit->save( ).

    rv_commit = lo_commit->sha1( ).

  ENDMETHOD.

  METHOD list.

    rt_list = zcl_ags_db=>get_repos( )->list( ).

  ENDMETHOD.

  METHOD list_branches.

    DATA: lt_list   TYPE zags_branches_tt,
          lo_branch TYPE REF TO zcl_ags_branch.

    FIELD-SYMBOLS: <ls_list> LIKE LINE OF lt_list.

    lt_list = zcl_ags_db=>get_branches( )->list( ms_data-repo ).

    LOOP AT lt_list ASSIGNING <ls_list>.
      CREATE OBJECT lo_branch
        EXPORTING
          io_repo = me
          iv_name = <ls_list>-name.

      APPEND lo_branch TO rt_list.
    ENDLOOP.

  ENDMETHOD.

  METHOD set_description.

    zcl_ags_db=>get_repos( )->update_description(
      iv_repo        = ms_data-repo
      iv_description = iv_description ).

    ms_data-description = iv_description.

  ENDMETHOD.
ENDCLASS.

fix indentation #2

fix indentation #2


*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_FORMS
*&---------------------------------------------------------------------*

*&---------------------------------------------------------------------*
*&      Form  run
*&---------------------------------------------------------------------*
FORM run.

  DATA: lx_exception TYPE REF TO zcx_abapgit_exception,
        lv_ind       TYPE t000-ccnocliind.

  SELECT SINGLE ccnocliind FROM t000 INTO lv_ind
    WHERE mandt = sy-mandt.
  IF sy-subrc = 0
      AND lv_ind <> ' '
      AND lv_ind <> '1'. " check changes allowed
    WRITE: / 'Wrong client, changes to repository objects not allowed'. "#EC NOTEXT
    RETURN.
  ENDIF.

  TRY.
      zcl_abapgit_migrations=>run( ).
      PERFORM open_gui.
    CATCH zcx_abapgit_exception INTO lx_exception.
      MESSAGE lx_exception TYPE 'E'.
  ENDTRY.

ENDFORM.                    "run

FORM open_gui RAISING zcx_abapgit_exception.

  IF sy-batch = abap_true.
    zcl_abapgit_background=>run( ).
  ELSE.

    zcl_abapgit_services_abapgit=>prepare_gui_startup( ).
    zcl_abapgit_ui_factory=>get_gui( )->go_home( ).
    CALL SELECTION-SCREEN 1001. " trigger screen

  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  branch_popup
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->TT_FIELDS      text
*      -->PV_CODE        text
*      -->CS_ERROR       text
*      -->CV_SHOW_POPUP  text
*      -->RAISING        text
*      -->zcx_abapgit_exception  text
*      -->##CALLED       text
*      -->##NEEDED       text
*----------------------------------------------------------------------*
FORM branch_popup TABLES   tt_fields TYPE zif_abapgit_definitions=>ty_sval_tt
                  USING    pv_code TYPE clike
                  CHANGING cs_error TYPE svale
                           cv_show_popup TYPE c
                  RAISING zcx_abapgit_exception ##called ##needed.
* called dynamically from function module POPUP_GET_VALUES_USER_BUTTONS

  DATA: lx_error  TYPE REF TO zcx_abapgit_exception,
        li_popups TYPE REF TO zif_abapgit_popups.

  TRY.
      li_popups = zcl_abapgit_ui_factory=>get_popups( ).
      li_popups->branch_popup_callback(
        EXPORTING
          iv_code       = pv_code
        CHANGING
          ct_fields     = tt_fields[]
          cs_error      = cs_error
          cv_show_popup = cv_show_popup ).

    CATCH zcx_abapgit_exception INTO lx_error.
      MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
  ENDTRY.

ENDFORM.                    "branch_popup

FORM package_popup TABLES   tt_fields TYPE zif_abapgit_definitions=>ty_sval_tt
                   USING    pv_code TYPE clike
                   CHANGING cs_error TYPE svale
                            cv_show_popup TYPE c
                   RAISING  zcx_abapgit_exception ##called ##needed.
* called dynamically from function module POPUP_GET_VALUES_USER_BUTTONS

  DATA: lx_error  TYPE REF TO zcx_abapgit_exception,
        li_popups TYPE REF TO zif_abapgit_popups.

  TRY.
      li_popups = zcl_abapgit_ui_factory=>get_popups( ).
      li_popups->package_popup_callback(
        EXPORTING
          iv_code       = pv_code
        CHANGING
          ct_fields     = tt_fields[]
          cs_error      = cs_error
          cv_show_popup = cv_show_popup ).

    CATCH zcx_abapgit_exception INTO lx_error.
      MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
  ENDTRY.

ENDFORM.                    "package_popup

FORM output.
  DATA: lt_ucomm TYPE TABLE OF sy-ucomm.

  PERFORM set_pf_status IN PROGRAM rsdbrunt IF FOUND.

  APPEND 'CRET' TO lt_ucomm.  "Button Execute

  CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
    EXPORTING
      p_status  = sy-pfkey
    TABLES
      p_exclude = lt_ucomm.

ENDFORM.

FORM exit RAISING zcx_abapgit_exception.
  CASE sy-ucomm.
    WHEN 'CBAC'.  "Back
      IF zcl_abapgit_ui_factory=>get_gui( )->back( ) IS INITIAL.
        LEAVE TO SCREEN 1001.
      ENDIF.
  ENDCASE.
ENDFORM.

FORM password_popup
      USING
        iv_repo_url TYPE string
      CHANGING
        cv_user     TYPE string
        cv_pass     TYPE string.

  lcl_password_dialog=>popup(
    EXPORTING
      iv_repo_url     = iv_repo_url
    CHANGING
      cv_user         = cv_user
      cv_pass         = cv_pass ).

ENDFORM.

FORM remove_toolbar USING pv_dynnr TYPE char4.

  DATA: ls_header               TYPE rpy_dyhead,
        lt_containers           TYPE dycatt_tab,
        lt_fields_to_containers TYPE dyfatc_tab,
        lt_flow_logic           TYPE swydyflow.

  CALL FUNCTION 'RPY_DYNPRO_READ'
    EXPORTING
      progname             = sy-cprog
      dynnr                = pv_dynnr
    IMPORTING
      header               = ls_header
    TABLES
      containers           = lt_containers
      fields_to_containers = lt_fields_to_containers
      flow_logic           = lt_flow_logic
    EXCEPTIONS
      cancelled            = 1
      not_found            = 2
      permission_error     = 3
      OTHERS               = 4.
  IF sy-subrc IS NOT INITIAL.
    RETURN. " Ignore errors, just exit
  ENDIF.

  IF ls_header-no_toolbar = abap_true.
    RETURN. " No change required
  ENDIF.

  ls_header-no_toolbar = abap_true.

  CALL FUNCTION 'RPY_DYNPRO_INSERT'
    EXPORTING
      header                 = ls_header
      suppress_exist_checks  = abap_true
    TABLES
      containers           = lt_containers
      fields_to_containers = lt_fields_to_containers
      flow_logic           = lt_flow_logic
    EXCEPTIONS
      cancelled              = 1
      already_exists         = 2
      program_not_exists     = 3
      not_executed           = 4
      missing_required_field = 5
      illegal_field_value    = 6
      field_not_allowed      = 7
      not_generated          = 8
      illegal_field_position = 9
      OTHERS                 = 10.
  IF sy-subrc <> 2 AND sy-subrc <> 0.
    RETURN. " Ignore errors, just exit
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_FORMS
*&---------------------------------------------------------------------*

*&---------------------------------------------------------------------*
*&      Form  run
*&---------------------------------------------------------------------*
FORM run.

  DATA: lx_exception TYPE REF TO zcx_abapgit_exception,
        lv_ind       TYPE t000-ccnocliind.

  SELECT SINGLE ccnocliind FROM t000 INTO lv_ind
    WHERE mandt = sy-mandt.
  IF sy-subrc = 0
      AND lv_ind <> ' '
      AND lv_ind <> '1'. " check changes allowed
    WRITE: / 'Wrong client, changes to repository objects not allowed'. "#EC NOTEXT
    RETURN.
  ENDIF.

  TRY.
      zcl_abapgit_migrations=>run( ).
      PERFORM open_gui.
    CATCH zcx_abapgit_exception INTO lx_exception.
      MESSAGE lx_exception TYPE 'E'.
  ENDTRY.

ENDFORM.                    "run

FORM open_gui RAISING zcx_abapgit_exception.

  IF sy-batch = abap_true.
    zcl_abapgit_background=>run( ).
  ELSE.

    zcl_abapgit_services_abapgit=>prepare_gui_startup( ).
    zcl_abapgit_ui_factory=>get_gui( )->go_home( ).
    CALL SELECTION-SCREEN 1001. " trigger screen

  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  branch_popup
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->TT_FIELDS      text
*      -->PV_CODE        text
*      -->CS_ERROR       text
*      -->CV_SHOW_POPUP  text
*      -->RAISING        text
*      -->zcx_abapgit_exception  text
*      -->##CALLED       text
*      -->##NEEDED       text
*----------------------------------------------------------------------*
FORM branch_popup TABLES   tt_fields TYPE zif_abapgit_definitions=>ty_sval_tt
                  USING    pv_code TYPE clike
                  CHANGING cs_error TYPE svale
                           cv_show_popup TYPE c
                  RAISING zcx_abapgit_exception ##called ##needed.
* called dynamically from function module POPUP_GET_VALUES_USER_BUTTONS

  DATA: lx_error  TYPE REF TO zcx_abapgit_exception,
        li_popups TYPE REF TO zif_abapgit_popups.

  TRY.
      li_popups = zcl_abapgit_ui_factory=>get_popups( ).
      li_popups->branch_popup_callback(
        EXPORTING
          iv_code       = pv_code
        CHANGING
          ct_fields     = tt_fields[]
          cs_error      = cs_error
          cv_show_popup = cv_show_popup ).

    CATCH zcx_abapgit_exception INTO lx_error.
      MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
  ENDTRY.

ENDFORM.                    "branch_popup

FORM package_popup TABLES   tt_fields TYPE zif_abapgit_definitions=>ty_sval_tt
                   USING    pv_code TYPE clike
                   CHANGING cs_error TYPE svale
                            cv_show_popup TYPE c
                   RAISING  zcx_abapgit_exception ##called ##needed.
* called dynamically from function module POPUP_GET_VALUES_USER_BUTTONS

  DATA: lx_error  TYPE REF TO zcx_abapgit_exception,
        li_popups TYPE REF TO zif_abapgit_popups.

  TRY.
      li_popups = zcl_abapgit_ui_factory=>get_popups( ).
      li_popups->package_popup_callback(
        EXPORTING
          iv_code       = pv_code
        CHANGING
          ct_fields     = tt_fields[]
          cs_error      = cs_error
          cv_show_popup = cv_show_popup ).

    CATCH zcx_abapgit_exception INTO lx_error.
      MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
  ENDTRY.

ENDFORM.                    "package_popup

FORM output.
  DATA: lt_ucomm TYPE TABLE OF sy-ucomm.

  PERFORM set_pf_status IN PROGRAM rsdbrunt IF FOUND.

  APPEND 'CRET' TO lt_ucomm.  "Button Execute
  APPEND 'SPOS' TO lt_ucomm.  "Button Save

  CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
    EXPORTING
      p_status  = sy-pfkey
    TABLES
      p_exclude = lt_ucomm.

ENDFORM.

FORM exit RAISING zcx_abapgit_exception.
  CASE sy-ucomm.
    WHEN 'CBAC'.  "Back
      IF zcl_abapgit_ui_factory=>get_gui( )->back( ) IS INITIAL.
        LEAVE TO SCREEN 1001.
      ENDIF.
  ENDCASE.
ENDFORM.

FORM password_popup
      USING
        iv_repo_url TYPE string
      CHANGING
        cv_user     TYPE string
        cv_pass     TYPE string.

  lcl_password_dialog=>popup(
    EXPORTING
      iv_repo_url     = iv_repo_url
    CHANGING
      cv_user         = cv_user
      cv_pass         = cv_pass ).

ENDFORM.

FORM remove_toolbar USING pv_dynnr TYPE char4.

  DATA: ls_header               TYPE rpy_dyhead,
        lt_containers           TYPE dycatt_tab,
        lt_fields_to_containers TYPE dyfatc_tab,
        lt_flow_logic           TYPE swydyflow.

  CALL FUNCTION 'RPY_DYNPRO_READ'
    EXPORTING
      progname             = sy-cprog
      dynnr                = pv_dynnr
    IMPORTING
      header               = ls_header
    TABLES
      containers           = lt_containers
      fields_to_containers = lt_fields_to_containers
      flow_logic           = lt_flow_logic
    EXCEPTIONS
      cancelled            = 1
      not_found            = 2
      permission_error     = 3
      OTHERS               = 4.
  IF sy-subrc IS NOT INITIAL.
    RETURN. " Ignore errors, just exit
  ENDIF.

  IF ls_header-no_toolbar = abap_true.
    RETURN. " No change required
  ENDIF.

  ls_header-no_toolbar = abap_true.

  CALL FUNCTION 'RPY_DYNPRO_INSERT'
    EXPORTING
      header                 = ls_header
      suppress_exist_checks  = abap_true
    TABLES
      containers             = lt_containers
      fields_to_containers   = lt_fields_to_containers
      flow_logic             = lt_flow_logic
    EXCEPTIONS
      cancelled              = 1
      already_exists         = 2
      program_not_exists     = 3
      not_executed           = 4
      missing_required_field = 5
      illegal_field_value    = 6
      field_not_allowed      = 7
      not_generated          = 8
      illegal_field_position = 9
      OTHERS                 = 10.
  IF sy-subrc <> 2 AND sy-subrc <> 0.
    RETURN. " Ignore errors, just exit
  ENDIF.

ENDFORM.

disable save button

disable save button


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.

    DATA: mo_persistence TYPE REF TO if_wb_object_persist.

  PRIVATE SECTION.
    METHODS:
      get_persistence
        RETURNING
          VALUE(ri_persistence) TYPE REF TO if_wb_object_persist
        RAISING
          zcx_abapgit_exception,

      clear_fields
        CHANGING
          cs_data TYPE any,

      clear_field
        IMPORTING
          iv_fieldname TYPE csequence
        CHANGING
          cs_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 cs_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 cs_data
           TO <lg_metadata>.
    ASSERT sy-subrc = 0.

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

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

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

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

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

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

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

  ENDMETHOD.

  METHOD get_persistence.

    DATA: lx_error TYPE REF TO cx_root.

    TRY.
        IF mo_persistence IS NOT BOUND.

          CREATE OBJECT mo_persistence
                 TYPE ('CL_DDLX_ADT_OBJECT_PERSIST').

        ENDIF.

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = lx_error->get_text( )
                                      ix_previous = lx_error ).
    ENDTRY.

    ri_persistence = mo_persistence.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.
    rv_user = c_user_unknown.
  ENDMETHOD.

  METHOD zif_abapgit_object~compare_to_remote_version.
    CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

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

    lv_object_key = ms_item-obj_name.

    TRY.
        CREATE OBJECT li_data_model TYPE ('CL_DDLX_WB_OBJECT_DATA').

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

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = lx_error->get_text( )
                                      ix_previous = 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_field> 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_field>.
        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_field> = mo_files->read_string( 'asddlxs' ) ##no_text.
          CATCH zcx_abapgit_exception.
        ENDTRY.

        CREATE OBJECT li_data_model
          TYPE ('CL_DDLX_WB_OBJECT_DATA').

        li_data_model->set_data( <lg_data> ).

        get_persistence( )->save( li_data_model ).

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = lx_error->get_text( )
                                      ix_previous = lx_error ).
    ENDTRY.

  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_metadata.
    rs_metadata = get_metadata( ).
    rs_metadata-ddic = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~has_changed_since.
    rv_changed = 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 = 'ESDICT'
                                            iv_argument    = |{ ms_item-obj_type }{ ms_item-obj_name }| ).

  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    TRY.
        jump_adt( iv_obj_name = ms_item-obj_name
                  iv_obj_type = ms_item-obj_type ).

      CATCH zcx_abapgit_exception.
        zcx_abapgit_exception=>raise( 'DDLX Jump Error' ).
    ENDTRY.

  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( ).
        li_persistence->get(
          EXPORTING
            p_object_key  = lv_object_key
            p_version     = swbm_version_active
          CHANGING
            p_object_data = li_data_model ).

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

        clear_fields( CHANGING cs_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( iv_text     = lx_error->get_text( )
                                      ix_previous = 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.

    DATA: mo_persistence TYPE REF TO if_wb_object_persist.

  PRIVATE SECTION.
    METHODS:
      get_persistence
        RETURNING
          VALUE(ri_persistence) TYPE REF TO if_wb_object_persist
        RAISING
          zcx_abapgit_exception,

      clear_fields
        CHANGING
          cs_data TYPE any,

      clear_field
        IMPORTING
          iv_fieldname TYPE csequence
        CHANGING
          cs_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 cs_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 cs_data
           TO <lg_metadata>.
    ASSERT sy-subrc = 0.

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

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

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

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

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

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

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

  ENDMETHOD.

  METHOD get_persistence.

    DATA: lx_error TYPE REF TO cx_root.

    TRY.
        IF mo_persistence IS NOT BOUND.

          CREATE OBJECT mo_persistence
                 TYPE ('CL_DDLX_ADT_OBJECT_PERSIST').

        ENDIF.

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = lx_error->get_text( )
                                      ix_previous = lx_error ).
    ENDTRY.

    ri_persistence = mo_persistence.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.
    rv_user = c_user_unknown.
  ENDMETHOD.

  METHOD zif_abapgit_object~compare_to_remote_version.
    CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

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

    lv_object_key = ms_item-obj_name.

    TRY.
        CREATE OBJECT li_data_model TYPE ('CL_DDLX_WB_OBJECT_DATA').

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

      CATCH cx_root INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = lx_error->get_text( )
                                      ix_previous = 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_field> 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_field>.
        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_field> = mo_files->read_string( 'asddlxs' ) ##no_text.
          CATCH zcx_abapgit_exception.
        ENDTRY.

        CREATE OBJECT li_data_model
          TYPE ('CL_DDLX_WB_OBJECT_DATA').

        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( iv_text     = lx_error->get_text( )
                                      ix_previous = lx_error ).
    ENDTRY.

  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_metadata.
    rs_metadata = get_metadata( ).
    rs_metadata-ddic = abap_true.
    rs_metadata-delete_tadir = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~has_changed_since.
    rv_changed = 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 = 'ESDICT'
                                            iv_argument    = |{ ms_item-obj_type }{ ms_item-obj_name }| ).

  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    TRY.
        jump_adt( iv_obj_name = ms_item-obj_name
                  iv_obj_type = ms_item-obj_type ).

      CATCH zcx_abapgit_exception.
        zcx_abapgit_exception=>raise( 'DDLX Jump Error' ).
    ENDTRY.

  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( ).
        li_persistence->get(
          EXPORTING
            p_object_key  = lv_object_key
            p_version     = swbm_version_active
          CHANGING
            p_object_data = li_data_model ).

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

        clear_fields( CHANGING cs_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( iv_text     = lx_error->get_text( )
                                      ix_previous = lx_error ).
    ENDTRY.

  ENDMETHOD.
ENDCLASS.

add tadir handling

DDLX: add tadir handling


CLASS zcl_abapgit_object_enqu DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES zif_abapgit_object.
    ALIASES mo_files FOR zif_abapgit_object~mo_files.

ENDCLASS.

CLASS ZCL_ABAPGIT_OBJECT_ENQU IMPLEMENTATION.

  METHOD zif_abapgit_object~changed_by.

    SELECT SINGLE as4user FROM dd25l
      INTO rv_user
      WHERE viewname = ms_item-obj_name
      AND as4local = 'A'
      AND as4vers  = '0000'.
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~compare_to_remote_version.
    CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lv_objname TYPE rsedd0-ddobjname.

    lv_objname = ms_item-obj_name.

    CALL FUNCTION 'RS_DD_DELETE_OBJ'
      EXPORTING
        no_ask               = abap_true
        objname              = lv_objname
        objtype              = 'L'
      EXCEPTIONS
        not_executed         = 1
        object_not_found     = 2
        object_not_specified = 3
        permission_failure   = 4.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, ENQU' ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: lv_name  TYPE ddobjname,
          ls_dd25v TYPE dd25v,
          lt_dd26e TYPE TABLE OF dd26e,
          lt_dd27p TYPE TABLE OF dd27p.

    io_xml->read( EXPORTING iv_name = 'DD25V'
                  CHANGING cg_data = ls_dd25v ).
    io_xml->read( EXPORTING iv_name = 'DD26E_TABLE'
                  CHANGING cg_data = lt_dd26e ).
    io_xml->read( EXPORTING iv_name = 'DD27P_TABLE'
                  CHANGING cg_data = lt_dd27p ).

    corr_insert( iv_package ).

    lv_name = ms_item-obj_name.

    CALL FUNCTION 'DDIF_ENQU_PUT'
      EXPORTING
        name              = lv_name
        dd25v_wa          = ls_dd25v
      TABLES
        dd26e_tab         = lt_dd26e
        dd27p_tab         = lt_dd27p
      EXCEPTIONS
        enqu_not_found    = 1
        name_inconsistent = 2
        enqu_inconsistent = 3
        put_failure       = 4
        put_refused       = 5
        OTHERS            = 6.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from DDIF_ENQU_PUT' ).
    ENDIF.

    zcl_abapgit_objects_activation=>add_item( ms_item ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: lv_viewname TYPE dd25l-viewname.

    SELECT SINGLE viewname FROM dd25l INTO lv_viewname
      WHERE viewname = ms_item-obj_name
      AND as4local = 'A'
      AND as4vers = '0000'.
    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.

  METHOD zif_abapgit_object~get_metadata.
    rs_metadata = get_metadata( ).
    rs_metadata-ddic = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~has_changed_since.

    DATA: lv_date TYPE dats,
          lv_time TYPE tims.

    SELECT SINGLE as4date as4time FROM dd25l
      INTO (lv_date, lv_time)
      WHERE viewname = ms_item-obj_name
      AND as4local = 'A'
      AND as4vers  = '0000'.

    rv_changed = check_timestamp(
      iv_timestamp = iv_timestamp
      iv_date      = lv_date
      iv_time      = lv_time ).

  ENDMETHOD.

  METHOD zif_abapgit_object~is_locked.

    rv_is_locked = abap_false.

  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    jump_se11( iv_radio = 'RSRD1-ENQU'
               iv_field = 'RSRD1-ENQU_VAL' ).

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: lv_name  TYPE ddobjname,
          ls_dd25v TYPE dd25v,
          lt_dd26e TYPE TABLE OF dd26e,
          lt_dd27p TYPE TABLE OF dd27p.

    FIELD-SYMBOLS: <ls_dd27p> LIKE LINE OF lt_dd27p.

    lv_name = ms_item-obj_name.

    CALL FUNCTION 'DDIF_ENQU_GET'
      EXPORTING
        name          = lv_name
        state         = 'A'
        langu         = mv_language
      IMPORTING
        dd25v_wa      = ls_dd25v
      TABLES
        dd26e_tab     = lt_dd26e
        dd27p_tab     = lt_dd27p
      EXCEPTIONS
        illegal_input = 1
        OTHERS        = 2.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from DDIF_ENQU_GET' ).
    ENDIF.
    IF ls_dd25v IS INITIAL.
      RETURN. " does not exist in system
    ENDIF.

    CLEAR: ls_dd25v-as4user,
           ls_dd25v-as4date,
           ls_dd25v-as4time.

    LOOP AT lt_dd27p ASSIGNING <ls_dd27p>.
      "taken from table
      CLEAR <ls_dd27p>-headlen.
      CLEAR <ls_dd27p>-scrlen1.
      CLEAR <ls_dd27p>-scrlen2.
      CLEAR <ls_dd27p>-scrlen3.
      CLEAR <ls_dd27p>-intlen.
      CLEAR <ls_dd27p>-outputlen.
      CLEAR <ls_dd27p>-flength.
      CLEAR <ls_dd27p>-ddtext.
      CLEAR <ls_dd27p>-reptext.
      CLEAR <ls_dd27p>-scrtext_s.
      CLEAR <ls_dd27p>-scrtext_m.
      CLEAR <ls_dd27p>-scrtext_l.
    ENDLOOP.

    io_xml->add( iv_name = 'DD25V'
                 ig_data = ls_dd25v ).
    io_xml->add( ig_data = lt_dd26e
                 iv_name = 'DD26E_TABLE' ).
    io_xml->add( ig_data = lt_dd27p
                 iv_name = 'DD27P_TABLE' ).

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_object_enqu DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES zif_abapgit_object.
    ALIASES mo_files FOR zif_abapgit_object~mo_files.
  PRIVATE SECTION.
    TYPES: tyt_dd27p TYPE STANDARD TABLE OF dd27p WITH DEFAULT KEY.
    METHODS _clear_dd27p_fields CHANGING ct_dd27p TYPE tyt_dd27p.

ENDCLASS.

CLASS ZCL_ABAPGIT_OBJECT_ENQU IMPLEMENTATION.

  METHOD zif_abapgit_object~changed_by.

    SELECT SINGLE as4user FROM dd25l
      INTO rv_user
      WHERE viewname = ms_item-obj_name
      AND as4local = 'A'
      AND as4vers  = '0000'.
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~compare_to_remote_version.
    CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lv_objname TYPE rsedd0-ddobjname.

    lv_objname = ms_item-obj_name.

    CALL FUNCTION 'RS_DD_DELETE_OBJ'
      EXPORTING
        no_ask               = abap_true
        objname              = lv_objname
        objtype              = 'L'
      EXCEPTIONS
        not_executed         = 1
        object_not_found     = 2
        object_not_specified = 3
        permission_failure   = 4.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, ENQU' ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: lv_name  TYPE ddobjname,
          ls_dd25v TYPE dd25v,
          lt_dd26e TYPE TABLE OF dd26e,
          lt_dd27p TYPE tyt_dd27p.

    io_xml->read( EXPORTING iv_name = 'DD25V'
                  CHANGING cg_data = ls_dd25v ).
    io_xml->read( EXPORTING iv_name = 'DD26E_TABLE'
                  CHANGING cg_data = lt_dd26e ).
    io_xml->read( EXPORTING iv_name = 'DD27P_TABLE'
                  CHANGING cg_data = lt_dd27p ).

    corr_insert( iv_package ).

    lv_name = ms_item-obj_name.

    CALL FUNCTION 'DDIF_ENQU_PUT'
      EXPORTING
        name              = lv_name
        dd25v_wa          = ls_dd25v
      TABLES
        dd26e_tab         = lt_dd26e
        dd27p_tab         = lt_dd27p
      EXCEPTIONS
        enqu_not_found    = 1
        name_inconsistent = 2
        enqu_inconsistent = 3
        put_failure       = 4
        put_refused       = 5
        OTHERS            = 6.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from DDIF_ENQU_PUT' ).
    ENDIF.

    zcl_abapgit_objects_activation=>add_item( ms_item ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: lv_viewname TYPE dd25l-viewname.

    SELECT SINGLE viewname FROM dd25l INTO lv_viewname
      WHERE viewname = ms_item-obj_name
      AND as4local = 'A'
      AND as4vers = '0000'.
    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.

  METHOD zif_abapgit_object~get_metadata.
    rs_metadata = get_metadata( ).
    rs_metadata-ddic = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~has_changed_since.

    DATA: lv_date TYPE dats,
          lv_time TYPE tims.

    SELECT SINGLE as4date as4time FROM dd25l
      INTO (lv_date, lv_time)
      WHERE viewname = ms_item-obj_name
      AND as4local = 'A'
      AND as4vers  = '0000'.

    rv_changed = check_timestamp(
      iv_timestamp = iv_timestamp
      iv_date      = lv_date
      iv_time      = lv_time ).

  ENDMETHOD.

  METHOD zif_abapgit_object~is_locked.

    rv_is_locked = abap_false.

  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    jump_se11( iv_radio = 'RSRD1-ENQU'
               iv_field = 'RSRD1-ENQU_VAL' ).

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: lv_name  TYPE ddobjname,
          ls_dd25v TYPE dd25v,
          lt_dd26e TYPE TABLE OF dd26e,
          lt_dd27p TYPE tyt_dd27p.

    lv_name = ms_item-obj_name.

    CALL FUNCTION 'DDIF_ENQU_GET'
      EXPORTING
        name          = lv_name
        state         = 'A'
        langu         = mv_language
      IMPORTING
        dd25v_wa      = ls_dd25v
      TABLES
        dd26e_tab     = lt_dd26e
        dd27p_tab     = lt_dd27p
      EXCEPTIONS
        illegal_input = 1
        OTHERS        = 2.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from DDIF_ENQU_GET' ).
    ENDIF.
    IF ls_dd25v IS INITIAL.
      RETURN. " does not exist in system
    ENDIF.

    CLEAR: ls_dd25v-as4user,
           ls_dd25v-as4date,
           ls_dd25v-as4time.

    _clear_dd27p_fields( CHANGING ct_dd27p = lt_dd27p ).

    io_xml->add( iv_name = 'DD25V'
                 ig_data = ls_dd25v ).
    io_xml->add( ig_data = lt_dd26e
                 iv_name = 'DD26E_TABLE' ).
    io_xml->add( ig_data = lt_dd27p
                 iv_name = 'DD27P_TABLE' ).

  ENDMETHOD.

  METHOD _clear_dd27p_fields.

    FIELD-SYMBOLS <ls_dd27p> TYPE dd27p.

    LOOP AT ct_dd27p ASSIGNING <ls_dd27p>.
      "taken from table
      CLEAR <ls_dd27p>-headlen.
      CLEAR <ls_dd27p>-scrlen1.
      CLEAR <ls_dd27p>-scrlen2.
      CLEAR <ls_dd27p>-scrlen3.
      CLEAR <ls_dd27p>-intlen.
      CLEAR <ls_dd27p>-outputlen.
      CLEAR <ls_dd27p>-flength.
      CLEAR <ls_dd27p>-ddtext.
      CLEAR <ls_dd27p>-reptext.
      CLEAR <ls_dd27p>-scrtext_s.
      CLEAR <ls_dd27p>-scrtext_m.
      CLEAR <ls_dd27p>-scrtext_l.
      CLEAR <ls_dd27p>-rollname.
      CLEAR <ls_dd27p>-rollnamevi.
      CLEAR <ls_dd27p>-entitytab.
      CLEAR <ls_dd27p>-datatype.
      CLEAR <ls_dd27p>-inttype.
      CLEAR <ls_dd27p>-ddlanguage.
      CLEAR <ls_dd27p>-domname.
      CLEAR <ls_dd27p>-signflag.
    ENDLOOP.

  ENDMETHOD.
ENDCLASS.

clear some more fields #1110 (#1888)

ENQU: clear some more fields #1110 (#1888)

* ENQU: clear fields #1110

* ENQU: clear some more fields #1110


CLASS zcl_abapgit_object_xslt 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.
    METHODS:
      get
        RETURNING VALUE(ro_xslt) TYPE REF TO cl_o2_api_xsltdesc
        RAISING   zcx_abapgit_exception.

ENDCLASS.

CLASS zcl_abapgit_object_xslt IMPLEMENTATION.

  METHOD get.

    DATA: lv_name TYPE cxsltdesc.

    lv_name = ms_item-obj_name.

    cl_o2_api_xsltdesc=>load(
      EXPORTING
        p_xslt_desc        = lv_name
      IMPORTING
        p_obj              = ro_xslt
      EXCEPTIONS
        not_existing       = 1
        permission_failure = 2
        OTHERS             = 3 ).
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from cl_o2_api_xsltdesc=>load' ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    DATA: lo_xslt       TYPE REF TO cl_o2_api_xsltdesc,
          ls_attributes TYPE o2xsltattr.

    lo_xslt = get( ).
    lo_xslt->get_attributes(
      RECEIVING
        p_attributes     = ls_attributes
      EXCEPTIONS
        object_invalid   = 1
        xsltdesc_deleted = 2
        OTHERS           = 3 ).

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    rv_user = ls_attributes-changedby.

  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lo_xslt TYPE REF TO cl_o2_api_xsltdesc,
          lv_name TYPE cxsltdesc.

    lv_name = ms_item-obj_name.

    cl_o2_api_xsltdesc=>load(
      EXPORTING
        p_xslt_desc        = lv_name
      IMPORTING
        p_obj              = lo_xslt
      EXCEPTIONS
        error_occured      = 1
        not_existing       = 2
        permission_failure = 3
        version_not_found  = 4
        OTHERS             = 5 ).
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from cl_o2_api_xsltdesc=>load' ).
    ENDIF.

    lo_xslt->set_changeable( abap_true ).
    lo_xslt->delete( ).
    lo_xslt->save( ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: lv_source     TYPE string,
          lo_xslt       TYPE REF TO cl_o2_api_xsltdesc,
          lv_len        TYPE i,
          ls_attributes TYPE o2xsltattr.

    " Transformation might depend on other objects like a class
    " We attempt to activate it in late step
    IF iv_step = zif_abapgit_object=>gc_step_id-late.
      zcl_abapgit_objects_activation=>add_item( ms_item ).
      RETURN.
    ENDIF.

    IF zif_abapgit_object~exists( ) = abap_true.
      zif_abapgit_object~delete( iv_package ).
    ENDIF.

    io_xml->read( EXPORTING iv_name = 'ATTRIBUTES'
                  CHANGING cg_data = ls_attributes ).

    ls_attributes-devclass = iv_package.

    lv_source = mo_files->read_string( iv_extra = 'source'
                                       iv_ext   = 'xml' ).

* workaround: somewhere additional linefeeds are added
    lv_len = strlen( lv_source ) - 2.
    IF lv_source+lv_len(2) = cl_abap_char_utilities=>cr_lf.
      lv_source = lv_source(lv_len).
    ENDIF.

    cl_o2_api_xsltdesc=>create_new_from_string(
      EXPORTING
        p_source                = lv_source
        p_attr                  = ls_attributes
      IMPORTING
        p_obj                   = lo_xslt
      EXCEPTIONS
        action_cancelled        = 1
        error_occured           = 2
        not_authorized          = 3
        object_already_existing = 4
        undefined_name          = 5
        OTHERS                  = 6 ).
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from XSLT new, { sy-subrc }| ).
    ENDIF.

    lo_xslt->save(
      EXCEPTIONS
        action_cancelled      = 1
        error_occured         = 2
        object_invalid        = 3
        object_not_changeable = 4
        permission_failure    = 5
        OTHERS                = 6 ).
    IF sy-subrc <> 0.
      lo_xslt->set_changeable( abap_false ). " unlock
      zcx_abapgit_exception=>raise( |Error from XSLT save, { sy-subrc }| ).
    ENDIF.

    lo_xslt->activate(
      EXCEPTIONS
        generate_error    = 1
        storage_error     = 2
        syntax_errors     = 3
*        xtc_not_available = 4  downport/upport, does not exist in 751
        OTHERS            = 5 ).
    IF sy-subrc <> 0.
      lo_xslt->set_changeable( abap_false ). " unlock
      zcx_abapgit_exception=>raise( |Error from XSLT activate, { sy-subrc }| ).
    ENDIF.

    lo_xslt->set_changeable( abap_false ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: lv_name TYPE cxsltdesc.

    lv_name = ms_item-obj_name.

    rv_bool = cl_o2_api_xsltdesc=>exists( lv_name ).
    rv_bool = boolc( rv_bool = '1' ).

  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.
    APPEND zif_abapgit_object=>gc_step_id-late 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.

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: lo_xslt       TYPE REF TO cl_o2_api_xsltdesc,
          lv_source     TYPE string,
          ls_attributes TYPE o2xsltattr.

    lo_xslt = get( ).

    ls_attributes = lo_xslt->get_attributes( ).

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

    io_xml->add( iv_name = 'ATTRIBUTES'
                 ig_data = ls_attributes ).

    lv_source = lo_xslt->get_source_string( ).

    mo_files->add_string( iv_extra  = 'source'
                          iv_ext    = 'xml'
                          iv_string = lv_source ).

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_object_xslt 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.
    METHODS:
      get
        RETURNING VALUE(ro_xslt) TYPE REF TO cl_o2_api_xsltdesc
        RAISING   zcx_abapgit_exception.

ENDCLASS.

CLASS zcl_abapgit_object_xslt IMPLEMENTATION.

  METHOD get.

    DATA: lv_name TYPE cxsltdesc.

    lv_name = ms_item-obj_name.

    cl_o2_api_xsltdesc=>load(
      EXPORTING
        p_xslt_desc        = lv_name
      IMPORTING
        p_obj              = ro_xslt
      EXCEPTIONS
        not_existing       = 1
        permission_failure = 2
        OTHERS             = 3 ).
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from cl_o2_api_xsltdesc=>load' ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    DATA: lo_xslt       TYPE REF TO cl_o2_api_xsltdesc,
          ls_attributes TYPE o2xsltattr.

    lo_xslt = get( ).
    lo_xslt->get_attributes(
      RECEIVING
        p_attributes     = ls_attributes
      EXCEPTIONS
        object_invalid   = 1
        xsltdesc_deleted = 2
        OTHERS           = 3 ).

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    rv_user = ls_attributes-changedby.

  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lo_xslt TYPE REF TO cl_o2_api_xsltdesc,
          lv_name TYPE cxsltdesc.

    lv_name = ms_item-obj_name.

    cl_o2_api_xsltdesc=>load(
      EXPORTING
        p_xslt_desc        = lv_name
      IMPORTING
        p_obj              = lo_xslt
      EXCEPTIONS
        error_occured      = 1
        not_existing       = 2
        permission_failure = 3
        version_not_found  = 4
        OTHERS             = 5 ).
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( 'error from cl_o2_api_xsltdesc=>load' ).
    ENDIF.

    lo_xslt->set_changeable( abap_true ).
    lo_xslt->delete( ).
    lo_xslt->save( ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: lv_source     TYPE string,
          lo_xslt       TYPE REF TO cl_o2_api_xsltdesc,
          lv_len        TYPE i,
          ls_attributes TYPE o2xsltattr.

    " Transformation might depend on other objects like a class
    " We attempt to activate it in late step
    IF iv_step = zif_abapgit_object=>gc_step_id-late.
      zcl_abapgit_objects_activation=>add_item( ms_item ).
      RETURN.
    ENDIF.

    IF zif_abapgit_object~exists( ) = abap_true.
      zif_abapgit_object~delete( iv_package ).
    ENDIF.

    io_xml->read( EXPORTING iv_name = 'ATTRIBUTES'
                  CHANGING cg_data = ls_attributes ).

    ls_attributes-devclass = iv_package.

    lv_source = mo_files->read_string( iv_extra = 'source'
                                       iv_ext   = 'xml' ).

* workaround: somewhere additional linefeeds are added
    lv_len = strlen( lv_source ) - 2.
    IF lv_source+lv_len(2) = cl_abap_char_utilities=>cr_lf.
      lv_source = lv_source(lv_len).
    ENDIF.

    cl_o2_api_xsltdesc=>create_new_from_string(
      EXPORTING
        p_source                = lv_source
        p_attr                  = ls_attributes
      IMPORTING
        p_obj                   = lo_xslt
      EXCEPTIONS
        action_cancelled        = 1
        error_occured           = 2
        not_authorized          = 3
        object_already_existing = 4
        undefined_name          = 5
        OTHERS                  = 6 ).
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Error from XSLT new, { sy-subrc }| ).
    ENDIF.

    lo_xslt->save(
      EXCEPTIONS
        action_cancelled      = 1
        error_occured         = 2
        object_invalid        = 3
        object_not_changeable = 4
        permission_failure    = 5
        OTHERS                = 6 ).
    IF sy-subrc <> 0.
      lo_xslt->set_changeable( abap_false ). " unlock
      zcx_abapgit_exception=>raise( |Error from XSLT save, { sy-subrc }| ).
    ENDIF.

    lo_xslt->set_changeable( abap_false ).

    zcl_abapgit_objects_activation=>add_item( ms_item ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: lv_name TYPE cxsltdesc.

    lv_name = ms_item-obj_name.

    rv_bool = cl_o2_api_xsltdesc=>exists( lv_name ).
    rv_bool = boolc( rv_bool = '1' ).

  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.
    APPEND zif_abapgit_object=>gc_step_id-late 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.

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: lo_xslt       TYPE REF TO cl_o2_api_xsltdesc,
          lv_source     TYPE string,
          ls_attributes TYPE o2xsltattr.

    lo_xslt = get( ).

    ls_attributes = lo_xslt->get_attributes( ).

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

    io_xml->add( iv_name = 'ATTRIBUTES'
                 ig_data = ls_attributes ).

    lv_source = lo_xslt->get_source_string( ).

    mo_files->add_string( iv_extra  = 'source'
                          iv_ext    = 'xml'
                          iv_string = lv_source ).

  ENDMETHOD.
ENDCLASS.

Fix activation error (#5042)

XSLT: Fix activation error (#5042)

Remove activation from `deserialize` and use `zcl_abapgit_objects_activation` instead.


CLASS zcl_abapgit_objects_activation DEFINITION
  PUBLIC
  CREATE PUBLIC .

  PUBLIC SECTION.

    CLASS-METHODS add
      IMPORTING
        !iv_type   TYPE trobjtype
        !iv_name   TYPE clike
        !iv_delete TYPE abap_bool DEFAULT abap_false
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS add_item
      IMPORTING
        !is_item TYPE zif_abapgit_definitions=>ty_item
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS activate
      IMPORTING
        !iv_ddic TYPE abap_bool DEFAULT abap_false
        !ii_log  TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS clear .
    CLASS-METHODS is_ddic_type
      IMPORTING
        !iv_obj_type     TYPE trobjtype
      RETURNING
        VALUE(rv_result) TYPE abap_bool .
  PROTECTED SECTION.
  PRIVATE SECTION.

    TYPES:
      BEGIN OF ty_classes,
        object  TYPE trobjtype,
        clsname TYPE seoclsname,
      END OF ty_classes.

    CLASS-DATA:
      gt_classes TYPE STANDARD TABLE OF ty_classes WITH DEFAULT KEY .
    CLASS-DATA:
      gt_objects TYPE TABLE OF dwinactiv .

    CLASS-METHODS update_where_used
      IMPORTING
        !ii_log TYPE REF TO zif_abapgit_log.
    CLASS-METHODS use_new_activation_logic
      RETURNING
        VALUE(rv_use_new_activation_logic) TYPE abap_bool .
    CLASS-METHODS activate_new
      IMPORTING
        !iv_ddic TYPE abap_bool DEFAULT abap_false
        !ii_log  TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS activate_old
      IMPORTING
        !iv_ddic TYPE abap_bool DEFAULT abap_false
        !ii_log  TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS activate_ddic
      IMPORTING
        !ii_log TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS add_errors_and_warnings_to_log
      IMPORTING
        !iv_logname TYPE ddmass-logname
        !ii_log     TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
ENDCLASS.

CLASS zcl_abapgit_objects_activation IMPLEMENTATION.

  METHOD activate.

    " Make sure that all changes are committed since any activation error will lead to a rollback
    COMMIT WORK AND WAIT.

    IF use_new_activation_logic( ) = abap_true.
      activate_new(
        iv_ddic = iv_ddic
        ii_log  = ii_log ).
    ELSE.
      activate_old(
        iv_ddic = iv_ddic
        ii_log  = ii_log ).
    ENDIF.

    update_where_used( ii_log ).

  ENDMETHOD.

  METHOD activate_ddic.

    DATA: lt_gentab     TYPE STANDARD TABLE OF dcgentb,
          lv_rc         TYPE sy-subrc,
          ls_gentab     LIKE LINE OF lt_gentab,
          lt_deltab     TYPE STANDARD TABLE OF dcdeltb,
          lt_action_tab TYPE STANDARD TABLE OF dctablres,
          lv_logname    TYPE ddmass-logname.

    FIELD-SYMBOLS: <ls_object> LIKE LINE OF gt_objects.

    LOOP AT gt_objects ASSIGNING <ls_object>.
      " Filter types supported by mass activation
      IF is_ddic_type( <ls_object>-object ) = abap_false.
        CONTINUE.
      ENDIF.
      ls_gentab-tabix = sy-tabix.
      ls_gentab-type = <ls_object>-object.
      ls_gentab-name = <ls_object>-obj_name.
      IF ls_gentab-type = 'INDX' OR ls_gentab-type = 'XINX' OR ls_gentab-type = 'MCID'.
        CALL FUNCTION 'DD_E071_TO_DD'
          EXPORTING
            object   = <ls_object>-object
            obj_name = <ls_object>-obj_name
          IMPORTING
            name     = ls_gentab-name
            id       = ls_gentab-indx.
      ENDIF.
      INSERT ls_gentab INTO TABLE lt_gentab.
    ENDLOOP.

    IF lt_gentab IS NOT INITIAL.

      lv_logname = |ABAPGIT_{ sy-datum }_{ sy-uzeit }|.

      CALL FUNCTION 'DD_MASS_ACT_C3'
        EXPORTING
          ddmode         = 'O'         " activate changes in Original System
          frcact         = abap_true   " force Activation
          medium         = 'T'         " transport order
          device         = 'T'         " saves to table DDRPH?
          version        = 'M'         " activate newest version
          logname        = lv_logname
          write_log      = abap_true
          log_head_tail  = abap_true
          t_on           = space
          prid           = 1
        IMPORTING
          act_rc         = lv_rc
        TABLES
          gentab         = lt_gentab
          deltab         = lt_deltab
          cnvtab         = lt_action_tab
        EXCEPTIONS
          access_failure = 1
          no_objects     = 2
          locked         = 3
          internal_error = 4
          OTHERS         = 5.

      IF sy-subrc <> 0.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.

      IF lv_rc > 0.
        add_errors_and_warnings_to_log(
          iv_logname = lv_logname
          ii_log     = ii_log ).
      ENDIF.

      IF lv_rc > 4.
        zcx_abapgit_exception=>raise( 'Activation cancelled. Check the inactive objects.' ).
      ENDIF.

      " Remove objects from activation queue to avoid double activation in activate_old
      LOOP AT lt_gentab INTO ls_gentab.
        DELETE gt_objects WHERE object = ls_gentab-type AND obj_name = ls_gentab-name.
      ENDLOOP.
      DELETE gt_objects WHERE object = 'INDX' OR object = 'XINX' OR object = 'MCID'.

    ENDIF.

  ENDMETHOD.

  METHOD activate_new.

    IF gt_objects IS INITIAL.
      RETURN.
    ENDIF.

    IF iv_ddic = abap_true.

      activate_ddic( ii_log ).

    ELSE.

      activate_old( ii_log ).

    ENDIF.

  ENDMETHOD.

  METHOD activate_old.

    DATA: lv_popup TYPE abap_bool,
          lv_no_ui TYPE abap_bool.

    IF gt_objects IS NOT INITIAL.

      IF zcl_abapgit_ui_factory=>get_frontend_services( )->gui_is_available( ) = abap_true.
        IF zcl_abapgit_persist_factory=>get_settings( )->read( )->get_activate_wo_popup( ) = abap_true.
          lv_popup = abap_false.
        ELSE.
          lv_popup = abap_true.
        ENDIF.
      ELSE.
        lv_popup = abap_false.
      ENDIF.

      lv_no_ui = boolc( lv_popup = abap_false ).

      TRY.
          CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
            EXPORTING
              activate_ddic_objects  = iv_ddic
              with_popup             = lv_popup
              ui_decoupled           = lv_no_ui
            TABLES
              objects                = gt_objects
            EXCEPTIONS
              excecution_error       = 1
              cancelled              = 2
              insert_into_corr_error = 3
              OTHERS                 = 4 ##SUBRC_OK.
        CATCH cx_sy_dyn_call_param_not_found.
          CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
            EXPORTING
              activate_ddic_objects  = iv_ddic
              with_popup             = lv_popup
            TABLES
              objects                = gt_objects
            EXCEPTIONS
              excecution_error       = 1
              cancelled              = 2
              insert_into_corr_error = 3
              OTHERS                 = 4 ##SUBRC_OK.
      ENDTRY.
      CASE sy-subrc.
        WHEN 1 OR 3 OR 4.
          zcx_abapgit_exception=>raise_t100( ).
        WHEN 2.
          zcx_abapgit_exception=>raise( 'Activation cancelled. Check the inactive objects.' ).
      ENDCASE.

    ENDIF.

  ENDMETHOD.

  METHOD add.

* function group SEWORKINGAREA
* function module RS_INSERT_INTO_WORKING_AREA
* class CL_WB_ACTIVATION_WORK_AREA

    FIELD-SYMBOLS: <ls_object>  TYPE dwinactiv,
                   <ls_classes> LIKE LINE OF gt_classes.

    IF iv_type = 'CLAS' OR iv_type = 'INTF'.
      APPEND INITIAL LINE TO gt_classes ASSIGNING <ls_classes>.
      <ls_classes>-object  = iv_type.
      <ls_classes>-clsname = iv_name.
    ELSE.
      APPEND INITIAL LINE TO gt_objects ASSIGNING <ls_object>.
      <ls_object>-object     = iv_type.
      <ls_object>-obj_name   = iv_name.
      <ls_object>-delet_flag = iv_delete.
    ENDIF.

  ENDMETHOD.

  METHOD add_errors_and_warnings_to_log.

    DATA: lt_lines      TYPE STANDARD TABLE OF trlog,
          lv_logname_db TYPE ddprh-protname.

    FIELD-SYMBOLS: <ls_line> LIKE LINE OF lt_lines.

    lv_logname_db = iv_logname.

    CALL FUNCTION 'TR_READ_LOG'
      EXPORTING
        iv_log_type   = 'DB'
        iv_logname_db = lv_logname_db
      TABLES
        et_lines      = lt_lines
      EXCEPTIONS
        invalid_input = 1
        access_error  = 2
        OTHERS        = 3.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    " Only error messsages
    DELETE lt_lines WHERE severity <> 'E'
                      AND severity <> 'W'.
    " Remove "Return code..." message
    DELETE lt_lines WHERE class = 'D0' AND number = '319'.

    LOOP AT lt_lines ASSIGNING <ls_line>.
      ii_log->add( iv_msg  = <ls_line>-line
                   iv_type = <ls_line>-severity ).
    ENDLOOP.

  ENDMETHOD.

  METHOD add_item.
    add( iv_type = is_item-obj_type
         iv_name = is_item-obj_name ).
  ENDMETHOD.

  METHOD clear.
    CLEAR gt_objects.
    CLEAR gt_classes.
  ENDMETHOD.

  METHOD is_ddic_type.

    " Determine if object can be handled by mass activation (see RADMASUTC form ma_tab_check)

    CONSTANTS:
      lc_domain     TYPE c LENGTH 9  VALUE 'DOMA DOMD',
      lc_types      TYPE c LENGTH 50 VALUE 'DTEL DTED TABL TABD SQLT SQLD TTYP TTYD VIEW VIED',
      lc_technset   TYPE c LENGTH 24 VALUE 'TABT VIET SQTT INDX XINX',
      lc_f4_objects TYPE c LENGTH 35 VALUE 'SHLP SHLD MCOB MCOD MACO MACD MCID',
      lc_enqueue    TYPE c LENGTH 9  VALUE 'ENQU ENQD',
      lc_sqsc       TYPE c LENGTH 4  VALUE 'SQSC',
      lc_stob       TYPE c LENGTH 4  VALUE 'STOB',
      lc_ntab       TYPE c LENGTH 14 VALUE 'NTTT NTTB NTDT',
      lc_ddls       TYPE c LENGTH 14 VALUE 'DDLS DRUL DTDC',
      lc_switches   TYPE c LENGTH 24 VALUE 'SF01 SF02 SFSW SFBS SFBF',
      lc_para       TYPE c LENGTH 4  VALUE 'PARA', " can be referenced by DTEL
      lc_enhd       TYPE c LENGTH 4  VALUE 'ENHD'.

    rv_result = abap_true.
    IF lc_domain   NS iv_obj_type AND lc_types      NS iv_obj_type AND
       lc_technset NS iv_obj_type AND lc_f4_objects NS iv_obj_type AND
       lc_enqueue  NS iv_obj_type AND lc_sqsc       NS iv_obj_type AND
       lc_stob     NS iv_obj_type AND lc_ntab       NS iv_obj_type AND
       lc_ddls     NS iv_obj_type AND lc_para       NS iv_obj_type AND
       lc_switches NS iv_obj_type AND iv_obj_type <> lc_enhd.
      rv_result = abap_false.
    ENDIF.

  ENDMETHOD.

  METHOD update_where_used.

    DATA: ls_class    LIKE LINE OF gt_classes,
          lo_cross    TYPE REF TO cl_wb_crossreference,
          ls_item     TYPE zif_abapgit_definitions=>ty_item,
          lv_error    TYPE c LENGTH 1,
          lv_include  TYPE programm.

    LOOP AT gt_classes INTO ls_class.
      CASE ls_class-object.
        WHEN 'CLAS'.
          lv_include = cl_oo_classname_service=>get_classpool_name( ls_class-clsname ).
        WHEN 'INTF'.
          lv_include = cl_oo_classname_service=>get_interfacepool_name( ls_class-clsname ).
      ENDCASE.

      CREATE OBJECT lo_cross
        EXPORTING
          p_name    = lv_include
          p_include = lv_include.

      lo_cross->index_actualize( IMPORTING p_error = lv_error ).

      IF lv_error = abap_true.
        ls_item-obj_type = ls_class-object.
        ls_item-obj_name = ls_class-clsname.
        ii_log->add(
          iv_msg  = 'Error updating where-used list'
          is_item = ls_item ).
      ENDIF.
    ENDLOOP.

  ENDMETHOD.

  METHOD use_new_activation_logic.

    CALL FUNCTION 'FUNCTION_EXISTS'
      EXPORTING
        funcname           = 'DD_MASS_ACT_C3'
      EXCEPTIONS
        function_not_exist = 1
        OTHERS             = 2.
    IF sy-subrc = 0.
      rv_use_new_activation_logic = abap_true.
    ENDIF.

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_objects_activation DEFINITION
  PUBLIC
  CREATE PUBLIC .

  PUBLIC SECTION.

    CLASS-METHODS add
      IMPORTING
        !iv_type   TYPE trobjtype
        !iv_name   TYPE clike
        !iv_delete TYPE abap_bool DEFAULT abap_false
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS add_item
      IMPORTING
        !is_item TYPE zif_abapgit_definitions=>ty_item
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS activate
      IMPORTING
        !iv_ddic TYPE abap_bool DEFAULT abap_false
        !ii_log  TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS clear .
    CLASS-METHODS is_ddic_type
      IMPORTING
        !iv_obj_type     TYPE trobjtype
      RETURNING
        VALUE(rv_result) TYPE abap_bool .
  PROTECTED SECTION.
  PRIVATE SECTION.

    TYPES:
      BEGIN OF ty_classes,
        object  TYPE trobjtype,
        clsname TYPE seoclsname,
      END OF ty_classes.

    CLASS-DATA:
      gt_classes TYPE STANDARD TABLE OF ty_classes WITH DEFAULT KEY .
    CLASS-DATA:
      gt_objects TYPE TABLE OF dwinactiv .

    CLASS-METHODS update_where_used
      IMPORTING
        !ii_log TYPE REF TO zif_abapgit_log.
    CLASS-METHODS use_new_activation_logic
      RETURNING
        VALUE(rv_use_new_activation_logic) TYPE abap_bool .
    CLASS-METHODS activate_new
      IMPORTING
        !iv_ddic TYPE abap_bool DEFAULT abap_false
        !ii_log  TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS activate_old
      IMPORTING
        !iv_ddic TYPE abap_bool DEFAULT abap_false
        !ii_log  TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS activate_ddic
      IMPORTING
        !ii_log TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS add_errors_and_warnings_to_log
      IMPORTING
        !iv_logname TYPE ddmass-logname
        !ii_log     TYPE REF TO zif_abapgit_log
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS add_activation_errors_to_log
      IMPORTING
        !io_checklist       TYPE REF TO cl_wb_checklist
        !ii_log             TYPE REF TO zif_abapgit_log
      RETURNING
        VALUE(rv_try_again) TYPE abap_bool
      RAISING
        zcx_abapgit_exception .

ENDCLASS.

CLASS zcl_abapgit_objects_activation IMPLEMENTATION.

  METHOD activate.

    " Make sure that all changes are committed since any activation error will lead to a rollback
    COMMIT WORK AND WAIT.

    IF use_new_activation_logic( ) = abap_true.
      activate_new(
        iv_ddic = iv_ddic
        ii_log  = ii_log ).
    ELSE.
      activate_old(
        iv_ddic = iv_ddic
        ii_log  = ii_log ).
    ENDIF.

    update_where_used( ii_log ).

  ENDMETHOD.

  METHOD activate_ddic.

    DATA: lt_gentab     TYPE STANDARD TABLE OF dcgentb,
          lv_rc         TYPE sy-subrc,
          ls_gentab     LIKE LINE OF lt_gentab,
          lt_deltab     TYPE STANDARD TABLE OF dcdeltb,
          lt_action_tab TYPE STANDARD TABLE OF dctablres,
          lv_logname    TYPE ddmass-logname.

    FIELD-SYMBOLS: <ls_object> LIKE LINE OF gt_objects.

    LOOP AT gt_objects ASSIGNING <ls_object>.
      " Filter types supported by mass activation
      IF is_ddic_type( <ls_object>-object ) = abap_false.
        CONTINUE.
      ENDIF.
      ls_gentab-tabix = sy-tabix.
      ls_gentab-type = <ls_object>-object.
      ls_gentab-name = <ls_object>-obj_name.
      IF ls_gentab-type = 'INDX' OR ls_gentab-type = 'XINX' OR ls_gentab-type = 'MCID'.
        CALL FUNCTION 'DD_E071_TO_DD'
          EXPORTING
            object   = <ls_object>-object
            obj_name = <ls_object>-obj_name
          IMPORTING
            name     = ls_gentab-name
            id       = ls_gentab-indx.
      ENDIF.
      INSERT ls_gentab INTO TABLE lt_gentab.
    ENDLOOP.

    IF lt_gentab IS NOT INITIAL.

      lv_logname = |ABAPGIT_{ sy-datum }_{ sy-uzeit }|.

      CALL FUNCTION 'DD_MASS_ACT_C3'
        EXPORTING
          ddmode         = 'O'         " activate changes in Original System
          frcact         = abap_true   " force Activation
          medium         = 'T'         " transport order
          device         = 'T'         " saves to table DDRPH?
          version        = 'M'         " activate newest version
          logname        = lv_logname
          write_log      = abap_true
          log_head_tail  = abap_true
          t_on           = space
          prid           = 1
        IMPORTING
          act_rc         = lv_rc
        TABLES
          gentab         = lt_gentab
          deltab         = lt_deltab
          cnvtab         = lt_action_tab
        EXCEPTIONS
          access_failure = 1
          no_objects     = 2
          locked         = 3
          internal_error = 4
          OTHERS         = 5.

      IF sy-subrc <> 0.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.

      IF lv_rc > 0.
        add_errors_and_warnings_to_log(
          iv_logname = lv_logname
          ii_log     = ii_log ).
      ENDIF.

      IF lv_rc > 4.
        zcx_abapgit_exception=>raise( 'Activation cancelled. Check the inactive objects.' ).
      ENDIF.

      " Remove objects from activation queue to avoid double activation in activate_old
      LOOP AT lt_gentab INTO ls_gentab.
        DELETE gt_objects WHERE object = ls_gentab-type AND obj_name = ls_gentab-name.
      ENDLOOP.
      DELETE gt_objects WHERE object = 'INDX' OR object = 'XINX' OR object = 'MCID'.

    ENDIF.

  ENDMETHOD.

  METHOD activate_new.

    IF gt_objects IS INITIAL.
      RETURN.
    ENDIF.

    IF iv_ddic = abap_true.

      activate_ddic( ii_log ).

    ELSE.

      activate_old( ii_log ).

    ENDIF.

  ENDMETHOD.

  METHOD activate_old.

    DATA:
      lv_popup     TYPE abap_bool,
      lv_no_ui     TYPE abap_bool,
      lv_try_again TYPE abap_bool,
      lv_msg       TYPE string,
      lo_checklist TYPE REF TO cl_wb_checklist.

    IF gt_objects IS NOT INITIAL.

      IF zcl_abapgit_ui_factory=>get_frontend_services( )->gui_is_available( ) = abap_true.
        IF zcl_abapgit_persist_factory=>get_settings( )->read( )->get_activate_wo_popup( ) = abap_true.
          lv_popup = abap_false.
        ELSE.
          lv_popup = abap_true.
        ENDIF.
      ELSE.
        lv_popup = abap_false.
      ENDIF.

      lv_no_ui = boolc( lv_popup = abap_false ).

      TRY.
          CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
            EXPORTING
              activate_ddic_objects  = iv_ddic
              with_popup             = lv_popup
              ui_decoupled           = lv_no_ui
            IMPORTING
              p_checklist            = lo_checklist
            TABLES
              objects                = gt_objects
            EXCEPTIONS
              excecution_error       = 1
              cancelled              = 2
              insert_into_corr_error = 3
              OTHERS                 = 4 ##SUBRC_OK.
        CATCH cx_sy_dyn_call_param_not_found.
          CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
            EXPORTING
              activate_ddic_objects  = iv_ddic
              with_popup             = lv_popup
            IMPORTING
              p_checklist            = lo_checklist
            TABLES
              objects                = gt_objects
            EXCEPTIONS
              excecution_error       = 1
              cancelled              = 2
              insert_into_corr_error = 3
              OTHERS                 = 4 ##SUBRC_OK.
      ENDTRY.
      CASE sy-subrc.
        WHEN 1 OR 3 OR 4.
          zcx_abapgit_exception=>raise_t100( ).
        WHEN 2.
          lv_msg = 'Check the log and inactive objects.'.
          IF lv_popup = abap_false.
            lv_try_again = add_activation_errors_to_log(
              ii_log       = ii_log
              io_checklist = lo_checklist ).
            IF lv_try_again = abap_true.
              lv_msg = 'Turn on "Activation Popup" in "Personal Settings" and try again'.
            ENDIF.
          ENDIF.
          zcx_abapgit_exception=>raise( |Activation cancelled. { lv_msg }| ).
      ENDCASE.

    ENDIF.

  ENDMETHOD.

  METHOD add.

* function group SEWORKINGAREA
* function module RS_INSERT_INTO_WORKING_AREA
* class CL_WB_ACTIVATION_WORK_AREA

    FIELD-SYMBOLS: <ls_object>  TYPE dwinactiv,
                   <ls_classes> LIKE LINE OF gt_classes.

    IF iv_type = 'CLAS' OR iv_type = 'INTF'.
      APPEND INITIAL LINE TO gt_classes ASSIGNING <ls_classes>.
      <ls_classes>-object  = iv_type.
      <ls_classes>-clsname = iv_name.
    ELSE.
      APPEND INITIAL LINE TO gt_objects ASSIGNING <ls_object>.
      <ls_object>-object     = iv_type.
      <ls_object>-obj_name   = iv_name.
      <ls_object>-delet_flag = iv_delete.
    ENDIF.

  ENDMETHOD.

  METHOD add_activation_errors_to_log.

    DATA:
      ls_item    TYPE zif_abapgit_definitions=>ty_item,
      lt_message TYPE swbme_error_tab.

    FIELD-SYMBOLS:
      <lv_msg>     TYPE string,
      <ls_message> LIKE LINE OF lt_message.

    io_checklist->get_error_messages( IMPORTING p_error_tab = lt_message ).

    LOOP AT lt_message ASSIGNING <ls_message> WHERE mtype = 'E'.
      " When activting without popup, includes used in multiple main programs cause error
      " Run again WITH activation popup (see abapGit, Personal Settings)
      IF <ls_message>-message-msgid = 'EU' AND <ls_message>-message-msgno = '404'.
        rv_try_again = abap_true.
      ENDIF.
      CLEAR ls_item.
      IF strlen( <ls_message>-object_text ) > 5.
        ls_item-obj_type = <ls_message>-object_text(4).
        ls_item-obj_name = <ls_message>-object_text+5(*).
      ENDIF.
      LOOP AT <ls_message>-mtext ASSIGNING <lv_msg>.
        ii_log->add_error(
          iv_msg  = <lv_msg>
          is_item = ls_item ).
      ENDLOOP.
    ENDLOOP.

  ENDMETHOD.

  METHOD add_errors_and_warnings_to_log.

    DATA: lt_lines      TYPE STANDARD TABLE OF trlog,
          lv_logname_db TYPE ddprh-protname.

    FIELD-SYMBOLS: <ls_line> LIKE LINE OF lt_lines.

    lv_logname_db = iv_logname.

    CALL FUNCTION 'TR_READ_LOG'
      EXPORTING
        iv_log_type   = 'DB'
        iv_logname_db = lv_logname_db
      TABLES
        et_lines      = lt_lines
      EXCEPTIONS
        invalid_input = 1
        access_error  = 2
        OTHERS        = 3.

    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    " Only error messsages
    DELETE lt_lines WHERE severity <> 'E'
                      AND severity <> 'W'.
    " Remove "Return code..." message
    DELETE lt_lines WHERE class = 'D0' AND number = '319'.

    LOOP AT lt_lines ASSIGNING <ls_line>.
      ii_log->add( iv_msg  = <ls_line>-line
                   iv_type = <ls_line>-severity ).
    ENDLOOP.

  ENDMETHOD.

  METHOD add_item.
    add( iv_type = is_item-obj_type
         iv_name = is_item-obj_name ).
  ENDMETHOD.

  METHOD clear.
    CLEAR gt_objects.
    CLEAR gt_classes.
  ENDMETHOD.

  METHOD is_ddic_type.

    " Determine if object can be handled by mass activation (see RADMASUTC form ma_tab_check)

    CONSTANTS:
      lc_domain     TYPE c LENGTH 9  VALUE 'DOMA DOMD',
      lc_types      TYPE c LENGTH 50 VALUE 'DTEL DTED TABL TABD SQLT SQLD TTYP TTYD VIEW VIED',
      lc_technset   TYPE c LENGTH 24 VALUE 'TABT VIET SQTT INDX XINX',
      lc_f4_objects TYPE c LENGTH 35 VALUE 'SHLP SHLD MCOB MCOD MACO MACD MCID',
      lc_enqueue    TYPE c LENGTH 9  VALUE 'ENQU ENQD',
      lc_sqsc       TYPE c LENGTH 4  VALUE 'SQSC',
      lc_stob       TYPE c LENGTH 4  VALUE 'STOB',
      lc_ntab       TYPE c LENGTH 14 VALUE 'NTTT NTTB NTDT',
      lc_ddls       TYPE c LENGTH 14 VALUE 'DDLS DRUL DTDC',
      lc_switches   TYPE c LENGTH 24 VALUE 'SF01 SF02 SFSW SFBS SFBF',
      lc_para       TYPE c LENGTH 4  VALUE 'PARA', " can be referenced by DTEL
      lc_enhd       TYPE c LENGTH 4  VALUE 'ENHD'.

    rv_result = abap_true.
    IF lc_domain   NS iv_obj_type AND lc_types      NS iv_obj_type AND
       lc_technset NS iv_obj_type AND lc_f4_objects NS iv_obj_type AND
       lc_enqueue  NS iv_obj_type AND lc_sqsc       NS iv_obj_type AND
       lc_stob     NS iv_obj_type AND lc_ntab       NS iv_obj_type AND
       lc_ddls     NS iv_obj_type AND lc_para       NS iv_obj_type AND
       lc_switches NS iv_obj_type AND iv_obj_type <> lc_enhd.
      rv_result = abap_false.
    ENDIF.

  ENDMETHOD.

  METHOD update_where_used.

    DATA: ls_class   LIKE LINE OF gt_classes,
          lo_cross   TYPE REF TO cl_wb_crossreference,
          ls_item    TYPE zif_abapgit_definitions=>ty_item,
          lv_error   TYPE c LENGTH 1,
          lv_include TYPE programm.

    LOOP AT gt_classes INTO ls_class.
      CASE ls_class-object.
        WHEN 'CLAS'.
          lv_include = cl_oo_classname_service=>get_classpool_name( ls_class-clsname ).
        WHEN 'INTF'.
          lv_include = cl_oo_classname_service=>get_interfacepool_name( ls_class-clsname ).
      ENDCASE.

      CREATE OBJECT lo_cross
        EXPORTING
          p_name    = lv_include
          p_include = lv_include.

      lo_cross->index_actualize( IMPORTING p_error = lv_error ).

      IF lv_error = abap_true.
        ls_item-obj_type = ls_class-object.
        ls_item-obj_name = ls_class-clsname.
        ii_log->add(
          iv_msg  = 'Error updating where-used list'
          is_item = ls_item ).
      ENDIF.
    ENDLOOP.

  ENDMETHOD.

  METHOD use_new_activation_logic.

    CALL FUNCTION 'FUNCTION_EXISTS'
      EXPORTING
        funcname           = 'DD_MASS_ACT_C3'
      EXCEPTIONS
        function_not_exist = 1
        OTHERS             = 2.
    IF sy-subrc = 0.
      rv_use_new_activation_logic = abap_true.
    ENDIF.

  ENDMETHOD.
ENDCLASS.

Improve error handling during activation phase (#5506)

When the "Activation Popup" is turned off in "Personal Settings", any errors during activation will lead to "Activation cancelled. Check the inactive objects" which is not very helpful.

The change will add the errors to the abapGit log.

It will also handle the special case when activation of includes leads to error "Include is used in multiple main programs" (EU 404). In such case, you can turn on the activation popup and repeat the abapGit process successfully.

Co-authored-by: Lars Hvam <721d1b171982cd84b755f6b25130d2b88cd1f696@hotmail.com>


*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_TRANSPORT
*&---------------------------------------------------------------------*

CLASS lcl_transport DEFINITION FINAL.

  PUBLIC SECTION.
    CLASS-METHODS:
      zip RAISING lcx_exception.

  PRIVATE SECTION.
    CLASS-METHODS:
      popup
        RETURNING VALUE(rv_trkorr) TYPE e070-trkorr,
      read_requests
        IMPORTING iv_trkorr          TYPE e070-trkorr
        RETURNING VALUE(rt_requests) TYPE trwbo_requests
        RAISING   lcx_exception,
      find_top_package
        IMPORTING it_tadir          TYPE scts_tadir
        RETURNING VALUE(rv_package) TYPE devclass,
      resolve
        IMPORTING it_requests     TYPE trwbo_requests
        RETURNING VALUE(rt_tadir) TYPE scts_tadir
        RAISING   lcx_exception.

ENDCLASS.

CLASS lcl_transport IMPLEMENTATION.

  METHOD zip.

    DATA: lt_requests TYPE trwbo_requests,
          lt_tadir    TYPE scts_tadir,
          lv_package  TYPE devclass,
          ls_data     TYPE lcl_persistence_repo=>ty_repo,
          lo_repo     TYPE REF TO lcl_repo_offline,
          lv_trkorr   TYPE e070-trkorr.

    lv_trkorr = popup( ).
    IF lv_trkorr IS INITIAL.
      RETURN.
    ENDIF.

    lt_requests = read_requests( lv_trkorr ).
    lt_tadir = resolve( lt_requests ).
    IF lines( lt_tadir ) = 0.
      lcx_exception=>raise( 'empty transport' ).
    ENDIF.

    lv_package = find_top_package( lt_tadir ).
    IF lv_package IS INITIAL.
      lcx_exception=>raise( 'error finding super package' ).
    ENDIF.

    ls_data-key             = 'TZIP'.
    ls_data-package         = lv_package.
    ls_data-master_language = sy-langu.

    CREATE OBJECT lo_repo
      EXPORTING
        is_data = ls_data.

    lcl_zip=>export( io_repo = lo_repo
                     it_filter = lt_tadir ).

  ENDMETHOD.

  METHOD find_top_package.
* assumption: all objects in transport share a common super package

    DATA: lt_obj   TYPE lcl_sap_package=>ty_devclass_tt,
          lt_super TYPE lcl_sap_package=>ty_devclass_tt,
          lv_super LIKE LINE OF lt_super,
          lv_index TYPE i.

    FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF it_tadir.

    READ TABLE it_tadir INDEX 1 ASSIGNING <ls_tadir>.
    ASSERT sy-subrc = 0.
    lt_super = lcl_sap_package=>list_superpackages( <ls_tadir>-devclass ).

    LOOP AT it_tadir ASSIGNING <ls_tadir>.
      lt_obj = lcl_sap_package=>list_superpackages( <ls_tadir>-devclass ).

* filter out possibilities from lt_super
      LOOP AT lt_super INTO lv_super.
        lv_index = sy-tabix.
        READ TABLE lt_obj FROM lv_super TRANSPORTING NO FIELDS.
        IF sy-subrc <> 0.
          DELETE lt_super INDEX lv_index.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

    SORT lt_super.
    READ TABLE lt_super INDEX 1 INTO rv_package.

  ENDMETHOD.

  METHOD popup.

    CALL FUNCTION 'TR_F4_REQUESTS'
      EXPORTING
        iv_username         = sy-uname
        iv_trkorr_pattern   = rv_trkorr
        iv_trfunctions      = sctsc_types_all
        iv_trstatus         = sctsc_states_changeable
      IMPORTING
        ev_selected_request = rv_trkorr.

  ENDMETHOD.

  METHOD read_requests.

    CALL FUNCTION 'TR_READ_REQUEST_WITH_TASKS'
      EXPORTING
        iv_trkorr     = iv_trkorr
      IMPORTING
        et_requests   = rt_requests
      EXCEPTIONS
        invalid_input = 1
        OTHERS        = 2.
    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from TR_READ_REQUEST_WITH_TASKS' ).
    ENDIF.

  ENDMETHOD.

  METHOD resolve.

    DATA: lv_object     TYPE tadir-object,
          lv_obj_name   TYPE tadir-obj_name,
          lv_trobj_name TYPE trobj_name,
          ls_tadir      TYPE tadir.

    FIELD-SYMBOLS: <ls_request> LIKE LINE OF it_requests,
                   <ls_object>  LIKE LINE OF <ls_request>-objects.

    LOOP AT it_requests ASSIGNING <ls_request>.
      LOOP AT <ls_request>-objects ASSIGNING <ls_object>.
        IF <ls_object>-pgmid = 'LIMU'.
          CALL FUNCTION 'GET_R3TR_OBJECT_FROM_LIMU_OBJ'
            EXPORTING
              p_limu_objtype = <ls_object>-object
              p_limu_objname = <ls_object>-obj_name
            IMPORTING
              p_r3tr_objtype = lv_object
              p_r3tr_objname = lv_trobj_name
            EXCEPTIONS
              no_mapping     = 1
              OTHERS         = 2.
          IF sy-subrc <> 0.
            lcx_exception=>raise( 'error from GET_R3TR_OBJECT_FROM_LIMU_OBJ' ).
          ENDIF.
          lv_obj_name = lv_trobj_name.
        ELSE.
          lv_object   = <ls_object>-object.
          lv_obj_name = <ls_object>-obj_name.
        ENDIF.

        ls_tadir = lcl_tadir=>read_single(
          iv_object   = lv_object
          iv_obj_name = lv_obj_name ).

        APPEND ls_tadir TO rt_tadir.
      ENDLOOP.
    ENDLOOP.

    SORT rt_tadir BY object ASCENDING obj_name ASCENDING.
    DELETE ADJACENT DUPLICATES FROM rt_tadir COMPARING object obj_name.

  ENDMETHOD.

ENDCLASS.

*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_TRANSPORT
*&---------------------------------------------------------------------*

CLASS lcl_transport DEFINITION FINAL.

  PUBLIC SECTION.
    CLASS-METHODS:
      zip RAISING lcx_exception.

  PRIVATE SECTION.
    CLASS-METHODS:
      popup
        RETURNING VALUE(rv_trkorr) TYPE e070-trkorr,
      read_requests
        IMPORTING iv_trkorr          TYPE e070-trkorr
        RETURNING VALUE(rt_requests) TYPE trwbo_requests
        RAISING   lcx_exception,
      find_top_package
        IMPORTING it_tadir          TYPE scts_tadir
        RETURNING VALUE(rv_package) TYPE devclass,
      resolve
        IMPORTING it_requests     TYPE trwbo_requests
        RETURNING VALUE(rt_tadir) TYPE scts_tadir
        RAISING   lcx_exception.

ENDCLASS.

CLASS lcl_transport IMPLEMENTATION.

  METHOD zip.

    DATA: lt_requests TYPE trwbo_requests,
          lt_tadir    TYPE scts_tadir,
          lv_package  TYPE devclass,
          ls_data     TYPE lcl_persistence_repo=>ty_repo,
          lo_repo     TYPE REF TO lcl_repo_offline,
          lv_trkorr   TYPE e070-trkorr.

    lv_trkorr = popup( ).
    IF lv_trkorr IS INITIAL.
      RETURN.
    ENDIF.

    lt_requests = read_requests( lv_trkorr ).
    lt_tadir = resolve( lt_requests ).
    IF lines( lt_tadir ) = 0.
      lcx_exception=>raise( 'empty transport' ).
    ENDIF.

    lv_package = find_top_package( lt_tadir ).
    IF lv_package IS INITIAL.
      lcx_exception=>raise( 'error finding super package' ).
    ENDIF.

    ls_data-key             = 'TZIP'.
    ls_data-package         = lv_package.
    ls_data-master_language = sy-langu.

    CREATE OBJECT lo_repo
      EXPORTING
        is_data = ls_data.

    lcl_zip=>export( io_repo = lo_repo
                     it_filter = lt_tadir ).

  ENDMETHOD.

  METHOD find_top_package.
* assumption: all objects in transport share a common super package

    DATA: lt_obj   TYPE lcl_sap_package=>ty_devclass_tt,
          lt_super TYPE lcl_sap_package=>ty_devclass_tt,
          lv_super LIKE LINE OF lt_super,
          lv_index TYPE i.

    FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF it_tadir.

    READ TABLE it_tadir INDEX 1 ASSIGNING <ls_tadir>.
    ASSERT sy-subrc = 0.
    lt_super = lcl_sap_package=>list_superpackages( <ls_tadir>-devclass ).

    LOOP AT it_tadir ASSIGNING <ls_tadir>.
      lt_obj = lcl_sap_package=>list_superpackages( <ls_tadir>-devclass ).

* filter out possibilities from lt_super
      LOOP AT lt_super INTO lv_super.
        lv_index = sy-tabix.
        READ TABLE lt_obj FROM lv_super TRANSPORTING NO FIELDS.
        IF sy-subrc <> 0.
          DELETE lt_super INDEX lv_index.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

    SORT lt_super.
    READ TABLE lt_super INDEX 1 INTO rv_package.

  ENDMETHOD.

  METHOD popup.

    CALL FUNCTION 'TR_F4_REQUESTS'
      EXPORTING
        iv_username         = sy-uname
        iv_trkorr_pattern   = rv_trkorr
        iv_trfunctions      = sctsc_types_all
        iv_trstatus         = sctsc_states_changeable
      IMPORTING
        ev_selected_request = rv_trkorr.

  ENDMETHOD.

  METHOD read_requests.

    CALL FUNCTION 'TR_READ_REQUEST_WITH_TASKS'
      EXPORTING
        iv_trkorr     = iv_trkorr
      IMPORTING
        et_requests   = rt_requests
      EXCEPTIONS
        invalid_input = 1
        OTHERS        = 2.
    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from TR_READ_REQUEST_WITH_TASKS' ).
    ENDIF.

  ENDMETHOD.

  METHOD resolve.

    DATA: lv_object     TYPE tadir-object,
          lv_obj_name   TYPE tadir-obj_name,
          lv_trobj_name TYPE trobj_name,
          ls_tadir      TYPE tadir.

    FIELD-SYMBOLS: <ls_request> LIKE LINE OF it_requests,
                   <ls_object>  LIKE LINE OF <ls_request>-objects.

    LOOP AT it_requests ASSIGNING <ls_request>.
      LOOP AT <ls_request>-objects ASSIGNING <ls_object>.
        IF <ls_object>-pgmid = 'LIMU'.
          CALL FUNCTION 'GET_R3TR_OBJECT_FROM_LIMU_OBJ'
            EXPORTING
              p_limu_objtype = <ls_object>-object
              p_limu_objname = <ls_object>-obj_name
            IMPORTING
              p_r3tr_objtype = lv_object
              p_r3tr_objname = lv_trobj_name
            EXCEPTIONS
              no_mapping     = 1
              OTHERS         = 2.
          IF sy-subrc <> 0.
            lcx_exception=>raise( 'error from GET_R3TR_OBJECT_FROM_LIMU_OBJ' ).
          ENDIF.
          lv_obj_name = lv_trobj_name.
        ELSE.
          lv_object   = <ls_object>-object.
          lv_obj_name = <ls_object>-obj_name.
        ENDIF.

        ls_tadir = lcl_tadir=>read_single(
          iv_object   = lv_object
          iv_obj_name = lv_obj_name ).

        APPEND ls_tadir TO rt_tadir.
      ENDLOOP.
    ENDLOOP.

    SORT rt_tadir BY object ASCENDING obj_name ASCENDING.
    DELETE ADJACENT DUPLICATES FROM rt_tadir COMPARING object obj_name.
    DELETE rt_tadir WHERE table_line IS INITIAL.
  ENDMETHOD.

ENDCLASS.

Delete blank lines from tadir objects

Delete blank lines from tadir objects

In "Transport to zip" option: Delete blank lines from tadir internal table before calculating the top package.