*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_PASSWORD_DIALOG
*&---------------------------------------------------------------------*

SELECTION-SCREEN BEGIN OF SCREEN 1002 TITLE s_title.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_url FOR FIELD p_url.
PARAMETERS: p_url TYPE string LOWER CASE VISIBLE LENGTH 40 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_user FOR FIELD p_user.
PARAMETERS: p_user TYPE string LOWER CASE VISIBLE LENGTH 40 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_pass FOR FIELD p_pass.
PARAMETERS: p_pass TYPE string LOWER CASE VISIBLE LENGTH 40 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF SCREEN 1002.

*-----------------------------------------------------------------------
* LCL_PASSWORD_DIALOG
*-----------------------------------------------------------------------
CLASS lcl_password_dialog DEFINITION FINAL.

**************
* This class will remain local in the report
**************

  PUBLIC SECTION.
    CONSTANTS c_dynnr TYPE c LENGTH 4 VALUE '1002'.

    CLASS-METHODS popup
      IMPORTING
        iv_repo_url TYPE string
      CHANGING
        cv_user     TYPE string
        cv_pass     TYPE string.

    CLASS-METHODS on_screen_init.
    CLASS-METHODS on_screen_output.
    CLASS-METHODS on_screen_event
      IMPORTING
        iv_ucomm TYPE sy-ucomm.

  PRIVATE SECTION.
    CLASS-DATA gv_confirm TYPE abap_bool.
    CLASS-METHODS enrich_title_by_hostname
      IMPORTING
        iv_repo_url TYPE string.

ENDCLASS.

CLASS lcl_password_dialog IMPLEMENTATION.

  METHOD popup.

    CLEAR p_pass.
    p_url      = iv_repo_url.
    p_user     = cv_user.
    gv_confirm = abap_false.

    enrich_title_by_hostname( iv_repo_url ).

    CALL SELECTION-SCREEN c_dynnr STARTING AT 5 5 ENDING AT 60 8.

    IF gv_confirm = abap_true.
      cv_user = p_user.
      cv_pass = p_pass.
    ELSE.
      CLEAR: cv_user, cv_pass.
    ENDIF.

    CLEAR: p_url, p_user, p_pass.

  ENDMETHOD.

  METHOD on_screen_init.
    s_title = 'Login'.
    s_url   = 'Repo URL'.
    s_user  = 'User'.
    s_pass  = 'Password'.
  ENDMETHOD.

  METHOD on_screen_output.
    DATA lt_ucomm TYPE TABLE OF sy-ucomm.

    ASSERT sy-dynnr = c_dynnr.

    LOOP AT SCREEN.
      IF screen-name = 'P_URL'.
        screen-input       = '0'.
        screen-intensified = '1'.
        screen-display_3d  = '0'.
        MODIFY SCREEN.
      ENDIF.
      IF screen-name = 'P_PASS'.
        screen-invisible   = '1'.
        MODIFY SCREEN.
      ENDIF.
    ENDLOOP.

    " Program RSSYSTDB, GUI Status %_CSP
    PERFORM set_pf_status IN PROGRAM rsdbrunt IF FOUND.
    APPEND 'NONE' TO lt_ucomm.  "Button Check
    APPEND 'SPOS' TO lt_ucomm.  "Save as Variant

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

    IF p_user IS NOT INITIAL.
      SET CURSOR FIELD 'P_PASS'.
    ENDIF.

  ENDMETHOD.

  METHOD on_screen_event.
    ASSERT sy-dynnr = c_dynnr.

    " CRET   - F8
    " OTHERS - simulate Enter press
    CASE iv_ucomm.
      WHEN 'CRET'.
        gv_confirm = abap_true.
      WHEN OTHERS. "TODO REFACTOR !!! A CLUTCH !
        " This will work unless any new specific logic appear
        " for other commands. The problem is that the password dialog
        " does not have Enter event (or I don't know how to activate it ;)
        " so Enter issues previous command from previous screen
        " But for now this works :) Fortunately Esc produces another flow
        gv_confirm = abap_true.
        LEAVE TO SCREEN 0.
    ENDCASE.

  ENDMETHOD.

  METHOD enrich_title_by_hostname.

    DATA lv_host TYPE string.

    FIND REGEX 'https?://([^/^:]*)' IN iv_repo_url SUBMATCHES lv_host.
    IF lv_host IS NOT INITIAL AND lv_host <> space.
      CLEAR s_title.
      CONCATENATE 'Login:' lv_host INTO s_title IN CHARACTER MODE SEPARATED BY space.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_PASSWORD_DIALOG
*&---------------------------------------------------------------------*

SELECTION-SCREEN BEGIN OF SCREEN 1002 TITLE s_title.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(18) s_url FOR FIELD p_url.
PARAMETERS: p_url TYPE string LOWER CASE VISIBLE LENGTH 60 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(18) s_user FOR FIELD p_user.
PARAMETERS: p_user TYPE string LOWER CASE VISIBLE LENGTH 60 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(18) s_pass FOR FIELD p_pass.
PARAMETERS: p_pass TYPE string LOWER CASE VISIBLE LENGTH 60 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF SCREEN 1002.

*-----------------------------------------------------------------------
* LCL_PASSWORD_DIALOG
*-----------------------------------------------------------------------
CLASS lcl_password_dialog DEFINITION FINAL.

**************
* This class will remain local in the report
**************

  PUBLIC SECTION.
    CONSTANTS c_dynnr TYPE c LENGTH 4 VALUE '1002'.

    CLASS-METHODS popup
      IMPORTING
        iv_repo_url TYPE string
      CHANGING
        cv_user     TYPE string
        cv_pass     TYPE string.

    CLASS-METHODS on_screen_init.
    CLASS-METHODS on_screen_output.
    CLASS-METHODS on_screen_event
      IMPORTING
        iv_ucomm TYPE sy-ucomm.

  PRIVATE SECTION.
    CLASS-DATA gv_confirm TYPE abap_bool.
    CLASS-METHODS enrich_title_by_hostname
      IMPORTING
        iv_repo_url TYPE string.

ENDCLASS.

CLASS lcl_password_dialog IMPLEMENTATION.

  METHOD popup.

    CLEAR p_pass.
    p_url      = iv_repo_url.
    p_user     = cv_user.
    gv_confirm = abap_false.

    enrich_title_by_hostname( iv_repo_url ).

    CALL SELECTION-SCREEN c_dynnr STARTING AT 5 5 ENDING AT 80 8.

    IF gv_confirm = abap_true.
      cv_user = p_user.
      cv_pass = p_pass.
    ELSE.
      CLEAR: cv_user, cv_pass.
    ENDIF.

    CLEAR: p_url, p_user, p_pass.

  ENDMETHOD.

  METHOD on_screen_init.
    s_title = 'Login'.
    s_url   = 'Repo URL'.
    s_user  = 'User'.
    s_pass  = 'Password or Token'.
  ENDMETHOD.

  METHOD on_screen_output.
    DATA lt_ucomm TYPE TABLE OF sy-ucomm.

    ASSERT sy-dynnr = c_dynnr.

    LOOP AT SCREEN.
      IF screen-name = 'P_URL'.
        screen-input       = '0'.
        screen-intensified = '1'.
        screen-display_3d  = '0'.
        MODIFY SCREEN.
      ENDIF.
      IF screen-name = 'P_PASS'.
        screen-invisible   = '1'.
        MODIFY SCREEN.
      ENDIF.
    ENDLOOP.

    " Program RSSYSTDB, GUI Status %_CSP
    PERFORM set_pf_status IN PROGRAM rsdbrunt IF FOUND.
    APPEND 'NONE' TO lt_ucomm.  "Button Check
    APPEND 'SPOS' TO lt_ucomm.  "Save as Variant

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

    IF p_user IS NOT INITIAL.
      SET CURSOR FIELD 'P_PASS'.
    ENDIF.

  ENDMETHOD.

  METHOD on_screen_event.
    ASSERT sy-dynnr = c_dynnr.

    " CRET   - F8
    " OTHERS - simulate Enter press
    CASE iv_ucomm.
      WHEN 'CRET'.
        gv_confirm = abap_true.
      WHEN OTHERS. "TODO REFACTOR !!! A CLUTCH !
        " This will work unless any new specific logic appear
        " for other commands. The problem is that the password dialog
        " does not have Enter event (or I don't know how to activate it ;)
        " so Enter issues previous command from previous screen
        " But for now this works :) Fortunately Esc produces another flow
        gv_confirm = abap_true.
        LEAVE TO SCREEN 0.
    ENDCASE.

  ENDMETHOD.

  METHOD enrich_title_by_hostname.

    DATA lv_host TYPE string.

    FIND REGEX 'https?://([^/^:]*)' IN iv_repo_url SUBMATCHES lv_host.
    IF lv_host IS NOT INITIAL AND lv_host <> space.
      CLEAR s_title.
      CONCATENATE 'Login:' lv_host INTO s_title IN CHARACTER MODE SEPARATED BY space.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

Improve label in user/password popup (#3934)

* Improve label in user/password popup

Change "Password" to "Password or Token"

* Fix size

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


*"* use this source file for your ABAP unit test classes
CLASS ltcl_sotr_handler DEFINITION FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.
  PRIVATE SECTION.
    METHODS is_wd_component_existing
      IMPORTING iv_component_name                  TYPE sobj_name
      RETURNING VALUE(rv_is_wd_component_existing) TYPE abap_bool.
    METHODS sotr_wda_0001 FOR TESTING.
    METHODS sotr_wda_0003_not_exist FOR TESTING.
    METHODS sotr_wda_0004 FOR TESTING.
    METHODS sotr_cx_0002 FOR TESTING.
ENDCLASS.

CLASS ltcl_sotr_handler IMPLEMENTATION.
  METHOD is_wd_component_existing.
    DATA ls_repository TYPE wdy_rr_cluster.
    DATA lv_component_name TYPE string.

    lv_component_name = iv_component_name.
    TRY.
        "need to regenerate for unit test to work
        CALL FUNCTION 'WDR_REPOSITORY_INFO'
          EXPORTING
            component_name = lv_component_name
            extended_read  = abap_true
          IMPORTING
            repository     = ls_repository.
        IF ls_repository IS NOT INITIAL.
          rv_is_wd_component_existing = abap_true.
        ENDIF.
      CATCH cx_wdr_rr_exception.
        "ignore and return false
    ENDTRY.
  ENDMETHOD.
  METHOD sotr_wda_0001.
    CONSTANTS lc_wd_component_name TYPE sobj_name VALUE 'SALV_WD_TEST_TABLE_SIMPLE'.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    IF is_wd_component_existing( lc_wd_component_name ) = abap_true.
      TRY.
          zcl_abapgit_sotr_handler=>read_sotr(
            EXPORTING
              iv_pgmid    = 'LIMU'
              iv_object   = 'WDYV'
              iv_obj_name = lc_wd_component_name
            IMPORTING
              et_sotr     = lt_sotr ).
          cl_aunit_assert=>assert_not_initial( lt_sotr ).
        CATCH zcx_abapgit_exception.
          cl_aunit_assert=>fail( quit = if_aunit_constants=>method ).
      ENDTRY.
    ENDIF.
  ENDMETHOD.
  METHOD sotr_wda_0003_not_exist.
    CONSTANTS lc_wd_not_exist_component_name TYPE sobj_name VALUE '_NOT_EXISTING'.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    IF is_wd_component_existing( lc_wd_not_exist_component_name ) <> abap_true.
      TRY.
          zcl_abapgit_sotr_handler=>read_sotr(
            EXPORTING
              iv_pgmid    = 'LIMU'
              iv_object   = 'WDYV'
              iv_obj_name = lc_wd_not_exist_component_name
            IMPORTING
              et_sotr     = lt_sotr ).
          cl_aunit_assert=>assert_initial( lt_sotr ).
        CATCH zcx_abapgit_exception.
          cl_aunit_assert=>fail( quit = if_aunit_constants=>method ).
      ENDTRY.
    ENDIF.
  ENDMETHOD.
  METHOD sotr_wda_0004.
    CONSTANTS lc_wd_component_name TYPE sobj_name VALUE 'SALV_WD_TEST_TABLE_SELECT'.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    IF is_wd_component_existing( lc_wd_component_name ) = abap_true.
      TRY.
          zcl_abapgit_sotr_handler=>read_sotr(
            EXPORTING
              iv_pgmid    = 'LIMU'
              iv_object   = 'WDYV'
              iv_obj_name = lc_wd_component_name
            IMPORTING
              et_sotr     = lt_sotr ).
          IF lines( lt_sotr ) < 50.
            cl_aunit_assert=>fail( quit = if_aunit_constants=>method ).
          ENDIF.
        CATCH zcx_abapgit_exception.
          cl_aunit_assert=>fail( quit = if_aunit_constants=>method ).
      ENDTRY.
    ENDIF.
  ENDMETHOD.
  METHOD sotr_cx_0002.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    TRY.
        zcl_abapgit_sotr_handler=>read_sotr(
          EXPORTING
            iv_pgmid    = 'LIMU'
            iv_object   = 'CPUB'
            iv_obj_name = 'CX_ABAP_INVALID_NAME'
          IMPORTING
            et_sotr     = lt_sotr ).
        cl_aunit_assert=>assert_not_initial( lt_sotr ).
      CATCH zcx_abapgit_exception.
        cl_aunit_assert=>fail( quit = if_aunit_constants=>method ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

CLASS ltcl_sotr_handler DEFINITION FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.
  PRIVATE SECTION.
    METHODS is_wd_component_existing
      IMPORTING iv_component_name                  TYPE sobj_name
      RETURNING VALUE(rv_is_wd_component_existing) TYPE abap_bool.
    METHODS sotr_wda_0001 FOR TESTING.
    METHODS sotr_wda_0003_not_exist FOR TESTING.
    METHODS sotr_wda_0004 FOR TESTING.
    METHODS sotr_cx_0002 FOR TESTING.
ENDCLASS.

CLASS ltcl_sotr_handler IMPLEMENTATION.
  METHOD is_wd_component_existing.
    DATA ls_repository TYPE wdy_rr_cluster.
    DATA lv_component_name TYPE string.

    lv_component_name = iv_component_name.
    TRY.
        "need to regenerate for unit test to work
        CALL FUNCTION 'WDR_REPOSITORY_INFO'
          EXPORTING
            component_name = lv_component_name
            extended_read  = abap_true
          IMPORTING
            repository     = ls_repository.
        IF ls_repository IS NOT INITIAL.
          rv_is_wd_component_existing = abap_true.
        ENDIF.
      CATCH cx_wdr_rr_exception.
        "ignore and return false
    ENDTRY.
  ENDMETHOD.
  METHOD sotr_wda_0001.
    CONSTANTS lc_wd_component_name TYPE sobj_name VALUE 'SALV_WD_TEST_TABLE_SIMPLE'.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    IF is_wd_component_existing( lc_wd_component_name ) = abap_true.
      TRY.
          zcl_abapgit_sotr_handler=>read_sotr(
            EXPORTING
              iv_pgmid    = 'LIMU'
              iv_object   = 'WDYV'
              iv_obj_name = lc_wd_component_name
            IMPORTING
              et_sotr     = lt_sotr ).
          cl_abap_unit_assert=>assert_not_initial( lt_sotr ).
        CATCH zcx_abapgit_exception.
          cl_abap_unit_assert=>fail( quit = if_aunit_constants=>method ).
      ENDTRY.
    ENDIF.
  ENDMETHOD.
  METHOD sotr_wda_0003_not_exist.
    CONSTANTS lc_wd_not_exist_component_name TYPE sobj_name VALUE '_NOT_EXISTING'.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    IF is_wd_component_existing( lc_wd_not_exist_component_name ) <> abap_true.
      TRY.
          zcl_abapgit_sotr_handler=>read_sotr(
            EXPORTING
              iv_pgmid    = 'LIMU'
              iv_object   = 'WDYV'
              iv_obj_name = lc_wd_not_exist_component_name
            IMPORTING
              et_sotr     = lt_sotr ).
          cl_abap_unit_assert=>assert_initial( lt_sotr ).
        CATCH zcx_abapgit_exception.
          cl_abap_unit_assert=>fail( quit = if_aunit_constants=>method ).
      ENDTRY.
    ENDIF.
  ENDMETHOD.
  METHOD sotr_wda_0004.
    CONSTANTS lc_wd_component_name TYPE sobj_name VALUE 'SALV_WD_TEST_TABLE_SELECT'.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    IF is_wd_component_existing( lc_wd_component_name ) = abap_true.
      TRY.
          zcl_abapgit_sotr_handler=>read_sotr(
            EXPORTING
              iv_pgmid    = 'LIMU'
              iv_object   = 'WDYV'
              iv_obj_name = lc_wd_component_name
            IMPORTING
              et_sotr     = lt_sotr ).
          IF lines( lt_sotr ) < 50.
            cl_abap_unit_assert=>fail( quit = if_aunit_constants=>method ).
          ENDIF.
        CATCH zcx_abapgit_exception.
          cl_abap_unit_assert=>fail( quit = if_aunit_constants=>method ).
      ENDTRY.
    ENDIF.
  ENDMETHOD.
  METHOD sotr_cx_0002.
    DATA lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
    TRY.
        zcl_abapgit_sotr_handler=>read_sotr(
          EXPORTING
            iv_pgmid    = 'LIMU'
            iv_object   = 'CPUB'
            iv_obj_name = 'CX_ABAP_INVALID_NAME'
          IMPORTING
            et_sotr     = lt_sotr ).
        cl_abap_unit_assert=>assert_not_initial( lt_sotr ).
      CATCH zcx_abapgit_exception.
        cl_abap_unit_assert=>fail( quit = if_aunit_constants=>method ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

Replace cl_aunit_assert with cl_abap_unit_assert (#4239)

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


*&---------------------------------------------------------------------*
*&  Include  zabapgit_object_shma
*&---------------------------------------------------------------------*

CLASS lcl_object_shma DEFINITION INHERITING FROM lcl_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES lif_object.

  PRIVATE SECTION.
    TYPES: db_startup_table     TYPE STANDARD TABLE OF shma_start      WITH DEFAULT KEY,
           db_startup_table_rts TYPE STANDARD TABLE OF shma_start_rts  WITH DEFAULT KEY.

    TYPES:
      BEGIN OF change_info,
        defined     TYPE shma_chg_info,
        rts         TYPE shma_chg_info,
        startup     TYPE shma_chg_info,
        startup_rts TYPE shma_chg_info,
      END OF change_info.

ENDCLASS.

CLASS lcl_object_shma IMPLEMENTATION.

  METHOD lif_object~has_changed_since.

    rv_changed = abap_true.

  ENDMETHOD.

  METHOD lif_object~changed_by.

    rv_user = c_user_unknown.

  ENDMETHOD.

  METHOD lif_object~get_metadata.

    rs_metadata = get_metadata( ).

  ENDMETHOD.

  METHOD lif_object~exists.

    DATA: area_name TYPE shm_area_name.

    SELECT SINGLE area_name
           FROM shma_attributes
           INTO area_name
           WHERE area_name = ms_item-obj_name.

    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.

  METHOD lif_object~serialize.

    DATA: area_name       TYPE shm_area_name,
          area_attributes TYPE shma_attributes,
          startup_list    TYPE db_startup_table.

    area_name = ms_item-obj_name.

    TRY.
        CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('READ_AREA_ATTRIBUTES_ALL')
          EXPORTING
            area_name       = area_name
          IMPORTING
            area_attributes = area_attributes
            startup_list    = startup_list.

        CLEAR: area_attributes-chg_user,
               area_attributes-chg_date,
               area_attributes-chg_time,
               area_attributes-cls_gen_user ,
               area_attributes-cls_gen_date ,
               area_attributes-cls_gen_time.

        io_xml->add( iv_name = 'AREA_ATTRIBUTES'
                     ig_data = area_attributes ).

        io_xml->add( iv_name = 'STARTUP_LIST'
                     ig_data = startup_list ).

      CATCH cx_root INTO DATA(error).
        lcx_exception=>raise( |Error serializing SHMA { ms_item-obj_name }| ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~deserialize.

    DATA: area_name       TYPE shm_area_name,
          area_attributes TYPE shma_attributes,
          startup_list    TYPE db_startup_table.

    area_name = ms_item-obj_name.

    io_xml->read(
      EXPORTING
        iv_name = 'AREA_ATTRIBUTES'
      CHANGING
        cg_data = area_attributes ).

    io_xml->read(
      EXPORTING
        iv_name = 'STARTUP_LIST'
      CHANGING
        cg_data = startup_list ).

    TRY.
        CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('INSERT_AREA')
          EXPORTING
            area_name           = area_name
            attributes          = area_attributes
            startup_list        = startup_list
            force_overwrite     = abap_true
            no_class_generation = abap_true
            silent_mode         = abap_true.

      CATCH cx_root INTO DATA(error).
        lcx_exception=>raise( |Error serializing SHMA { ms_item-obj_name }| ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~delete.

    " We can't use FM SHMA_DELETE_AREA because it depends
    " on the corresponding class, but in abapGit it has its own
    " lifecycle. Therefore we have to reimplement most of the
    " FMs logic

    CONSTANTS:
        c_request_delete TYPE i VALUE '4'.

    DATA: request   TYPE i,
          area_name TYPE shm_area_name,
          order     TYPE e070-trkorr,
          korrnum   TYPE tadir-korrnum,
          objname   TYPE tadir-obj_name,
          task      TYPE e070-trkorr,
          append    TYPE abap_bool,
          tadir     TYPE tadir,
          tdevc     TYPE tdevc,
          lo_cts_if TYPE REF TO object.

    area_name = ms_item-obj_name.

    TRY.
        CALL FUNCTION 'ENQUEUE_E_SHM_AREA'
          EXPORTING
            mode_shma_attributes = 'E'
            area_name            = area_name
            x_area_name          = ' '
            _scope               = '2'
            _wait                = ' '
            _collect             = ' '
          EXCEPTIONS
            foreign_lock         = 1
            system_failure       = 2
            OTHERS               = 3.

        IF sy-subrc <> 0.
          lcx_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
        ENDIF.

        CALL METHOD ('\PROGRAM=SAPMSHM_MONITOR\CLASS=LCL_SHMM')=>('FREE_AREA_BY_NAME')
          EXPORTING
            area_name     = area_name
            affect_server = cl_shm_area=>affect_all_servers.

        CREATE OBJECT lo_cts_if TYPE ('\FUNCTION-POOL=SHMA\CLASS=LCL_CTS_INTERFACE')
          EXPORTING
            area = area_name.

        CALL METHOD lo_cts_if->('CHECK_AREA')
          EXPORTING
            request     = c_request_delete
          IMPORTING
            access_mode = request
            appendable  = append.

        IF request <> c_request_delete.
          lcx_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
        ENDIF.

        CALL METHOD lo_cts_if->('INSERT_AREA')
          EXPORTING
            request = c_request_delete
          IMPORTING
            order   = order
            task    = task.

        DELETE FROM shma_attributes  WHERE area_name = area_name.
        DELETE FROM shma_start       WHERE area_name = area_name.

        korrnum = order.
        objname = area_name.

        CALL FUNCTION 'TR_TADIR_INTERFACE'
          EXPORTING
            wi_read_only      = abap_true
            wi_tadir_pgmid    = 'R3TR'
            wi_tadir_object   = 'SHMA'
            wi_tadir_obj_name = objname
          IMPORTING
            new_tadir_entry   = tadir
          EXCEPTIONS
            OTHERS            = 0.

        CALL FUNCTION 'TR_DEVCLASS_GET'
          EXPORTING
            iv_devclass = tadir-devclass
          IMPORTING
            es_tdevc    = tdevc
          EXCEPTIONS
            OTHERS      = 1.

        IF  sy-subrc = 0 AND tdevc-korrflag IS INITIAL.

          " TADIR entries for local objects must be deleted 'by hand'

          CALL FUNCTION 'TR_TADIR_INTERFACE'
            EXPORTING
              wi_test_modus         = abap_false
              wi_delete_tadir_entry = abap_true
              wi_tadir_pgmid        = 'R3TR'
              wi_tadir_object       = 'SHMA'
              wi_tadir_obj_name     = objname
              wi_tadir_korrnum      = korrnum
            EXCEPTIONS
              OTHERS                = 0.

          CALL FUNCTION 'TR_TADIR_INTERFACE'
            EXPORTING
              wi_test_modus         = abap_false
              wi_delete_tadir_entry = abap_true
              wi_tadir_pgmid        = 'R3TR'
              wi_tadir_object       = 'CLAS'
              wi_tadir_obj_name     = objname
              wi_tadir_korrnum      = korrnum
            EXCEPTIONS
              OTHERS                = 0.

        ENDIF.

        CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('DELETE_RUNTIME_SETTINGS')
          EXPORTING
            area_name = area_name.

        CALL FUNCTION 'DEQUEUE_E_SHM_AREA'
          EXPORTING
            mode_shma_attributes = 'E'
            area_name            = area_name
            x_area_name          = ' '
            _scope               = '3'
            _synchron            = ' '
            _collect             = ' '.

      CATCH cx_root.
        lcx_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~jump.

    DATA: ls_bcdata TYPE bdcdata,
          lt_bcdata TYPE STANDARD TABLE OF bdcdata.

    ls_bcdata-program  = 'SAPLSHMA'.
    ls_bcdata-dynpro   = '0100'.
    ls_bcdata-dynbegin = 'X'.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'SHMA_ATTRIBUTES-AREA_NAME'.
    ls_bcdata-fval = ms_item-obj_name.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'BDC_OKCODE'.
    ls_bcdata-fval = '=SHOW'.
    APPEND ls_bcdata TO lt_bcdata.

    CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
      STARTING NEW TASK 'GIT'
      EXPORTING
        tcode     = 'SHMA'
        mode_val  = 'E'
      TABLES
        using_tab = lt_bcdata
      EXCEPTIONS
        OTHERS    = 1.

    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SHMA' ).
    ENDIF.

  ENDMETHOD.

  METHOD lif_object~compare_to_remote_version.

    CREATE OBJECT ro_comparison_result TYPE lcl_comparison_null.

  ENDMETHOD.

ENDCLASS.

*&---------------------------------------------------------------------*
*&  Include  zabapgit_object_shma
*&---------------------------------------------------------------------*

CLASS lcl_object_shma DEFINITION INHERITING FROM lcl_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES lif_object.

  PRIVATE SECTION.
    TYPES: db_startup_table     TYPE STANDARD TABLE OF shma_start      WITH DEFAULT KEY,
           db_startup_table_rts TYPE STANDARD TABLE OF shma_start_rts  WITH DEFAULT KEY.

ENDCLASS.

CLASS lcl_object_shma IMPLEMENTATION.

  METHOD lif_object~has_changed_since.

    rv_changed = abap_true.

  ENDMETHOD.

  METHOD lif_object~changed_by.

    rv_user = c_user_unknown.

  ENDMETHOD.

  METHOD lif_object~get_metadata.

    rs_metadata = get_metadata( ).

  ENDMETHOD.

  METHOD lif_object~exists.

    DATA: area_name TYPE shm_area_name.

    SELECT SINGLE area_name
           FROM shma_attributes
           INTO area_name
           WHERE area_name = ms_item-obj_name.

    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.

  METHOD lif_object~serialize.

    DATA: area_name       TYPE shm_area_name,
          area_attributes TYPE shma_attributes,
          startup_list    TYPE db_startup_table.

    area_name = ms_item-obj_name.

    TRY.
        CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('READ_AREA_ATTRIBUTES_ALL')
          EXPORTING
            area_name       = area_name
          IMPORTING
            area_attributes = area_attributes
            startup_list    = startup_list.

        CLEAR: area_attributes-chg_user,
               area_attributes-chg_date,
               area_attributes-chg_time,
               area_attributes-cls_gen_user ,
               area_attributes-cls_gen_date ,
               area_attributes-cls_gen_time.

        io_xml->add( iv_name = 'AREA_ATTRIBUTES'
                     ig_data = area_attributes ).

        io_xml->add( iv_name = 'STARTUP_LIST'
                     ig_data = startup_list ).

      CATCH cx_root INTO DATA(error).
        lcx_exception=>raise( |Error serializing SHMA { ms_item-obj_name }| ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~deserialize.

    DATA: area_name       TYPE shm_area_name,
          area_attributes TYPE shma_attributes,
          startup_list    TYPE db_startup_table.

    area_name = ms_item-obj_name.

    io_xml->read(
      EXPORTING
        iv_name = 'AREA_ATTRIBUTES'
      CHANGING
        cg_data = area_attributes ).

    io_xml->read(
      EXPORTING
        iv_name = 'STARTUP_LIST'
      CHANGING
        cg_data = startup_list ).

    TRY.
        CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('INSERT_AREA')
          EXPORTING
            area_name           = area_name
            attributes          = area_attributes
            startup_list        = startup_list
            force_overwrite     = abap_true
            no_class_generation = abap_true
            silent_mode         = abap_true.

      CATCH cx_root INTO DATA(error).
        lcx_exception=>raise( |Error serializing SHMA { ms_item-obj_name }| ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~delete.

    " We can't use FM SHMA_DELETE_AREA because it depends
    " on the corresponding class, but in abapGit it has its own
    " lifecycle. Therefore we have to reimplement most of the
    " FMs logic

    CONSTANTS:
        c_request_delete TYPE i VALUE '4'.

    DATA: request   TYPE i,
          area_name TYPE shm_area_name,
          order     TYPE e070-trkorr,
          korrnum   TYPE tadir-korrnum,
          objname   TYPE tadir-obj_name,
          task      TYPE e070-trkorr,
          append    TYPE abap_bool,
          tadir     TYPE tadir,
          tdevc     TYPE tdevc,
          lo_cts_if TYPE REF TO object.

    area_name = ms_item-obj_name.

    TRY.
        CALL FUNCTION 'ENQUEUE_E_SHM_AREA'
          EXPORTING
            mode_shma_attributes = 'E'
            area_name            = area_name
            x_area_name          = ' '
            _scope               = '2'
            _wait                = ' '
            _collect             = ' '
          EXCEPTIONS
            foreign_lock         = 1
            system_failure       = 2
            OTHERS               = 3.

        IF sy-subrc <> 0.
          lcx_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
        ENDIF.

        CALL METHOD ('\PROGRAM=SAPMSHM_MONITOR\CLASS=LCL_SHMM')=>('FREE_AREA_BY_NAME')
          EXPORTING
            area_name     = area_name
            affect_server = cl_shm_area=>affect_all_servers.

        CREATE OBJECT lo_cts_if TYPE ('\FUNCTION-POOL=SHMA\CLASS=LCL_CTS_INTERFACE')
          EXPORTING
            area = area_name.

        CALL METHOD lo_cts_if->('CHECK_AREA')
          EXPORTING
            request     = c_request_delete
          IMPORTING
            access_mode = request
            appendable  = append.

        IF request <> c_request_delete.
          lcx_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
        ENDIF.

        CALL METHOD lo_cts_if->('INSERT_AREA')
          EXPORTING
            request = c_request_delete
          IMPORTING
            order   = order
            task    = task.

        DELETE FROM shma_attributes  WHERE area_name = area_name.
        DELETE FROM shma_start       WHERE area_name = area_name.

        korrnum = order.
        objname = area_name.

        CALL FUNCTION 'TR_TADIR_INTERFACE'
          EXPORTING
            wi_read_only      = abap_true
            wi_tadir_pgmid    = 'R3TR'
            wi_tadir_object   = 'SHMA'
            wi_tadir_obj_name = objname
          IMPORTING
            new_tadir_entry   = tadir
          EXCEPTIONS
            OTHERS            = 0.

        CALL FUNCTION 'TR_DEVCLASS_GET'
          EXPORTING
            iv_devclass = tadir-devclass
          IMPORTING
            es_tdevc    = tdevc
          EXCEPTIONS
            OTHERS      = 1.

        IF  sy-subrc = 0 AND tdevc-korrflag IS INITIAL.

          " TADIR entries for local objects must be deleted 'by hand'

          CALL FUNCTION 'TR_TADIR_INTERFACE'
            EXPORTING
              wi_test_modus         = abap_false
              wi_delete_tadir_entry = abap_true
              wi_tadir_pgmid        = 'R3TR'
              wi_tadir_object       = 'SHMA'
              wi_tadir_obj_name     = objname
              wi_tadir_korrnum      = korrnum
            EXCEPTIONS
              OTHERS                = 0.

          CALL FUNCTION 'TR_TADIR_INTERFACE'
            EXPORTING
              wi_test_modus         = abap_false
              wi_delete_tadir_entry = abap_true
              wi_tadir_pgmid        = 'R3TR'
              wi_tadir_object       = 'CLAS'
              wi_tadir_obj_name     = objname
              wi_tadir_korrnum      = korrnum
            EXCEPTIONS
              OTHERS                = 0.

        ENDIF.

        CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('DELETE_RUNTIME_SETTINGS')
          EXPORTING
            area_name = area_name.

        CALL FUNCTION 'DEQUEUE_E_SHM_AREA'
          EXPORTING
            mode_shma_attributes = 'E'
            area_name            = area_name
            x_area_name          = ' '
            _scope               = '3'
            _synchron            = ' '
            _collect             = ' '.

      CATCH cx_root.
        lcx_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~jump.

    DATA: ls_bcdata TYPE bdcdata,
          lt_bcdata TYPE STANDARD TABLE OF bdcdata.

    ls_bcdata-program  = 'SAPLSHMA'.
    ls_bcdata-dynpro   = '0100'.
    ls_bcdata-dynbegin = 'X'.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'SHMA_ATTRIBUTES-AREA_NAME'.
    ls_bcdata-fval = ms_item-obj_name.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'BDC_OKCODE'.
    ls_bcdata-fval = '=SHOW'.
    APPEND ls_bcdata TO lt_bcdata.

    CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
      STARTING NEW TASK 'GIT'
      EXPORTING
        tcode     = 'SHMA'
        mode_val  = 'E'
      TABLES
        using_tab = lt_bcdata
      EXCEPTIONS
        OTHERS    = 1.

    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SHMA' ).
    ENDIF.

  ENDMETHOD.

  METHOD lif_object~compare_to_remote_version.

    CREATE OBJECT ro_comparison_result TYPE lcl_comparison_null.

  ENDMETHOD.

ENDCLASS.

delete superfluos type definition

delete superfluos type definition


*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_OBJECT_TOBJ
*&---------------------------------------------------------------------*

*----------------------------------------------------------------------*
*       CLASS lcl_object_tobj DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_object_tobj DEFINITION INHERITING FROM lcl_objects_super FINAL.

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

ENDCLASS.                    "lcl_object_tobj DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_object_tobj IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_object_tobj IMPLEMENTATION.

  METHOD lif_object~has_changed_since.
    rv_changed = abap_true.
  ENDMETHOD.  "lif_object~has_changed_since

  METHOD lif_object~changed_by.

    DATA: lv_type_pos TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    SELECT SINGLE luser FROM objh INTO rv_user
      WHERE objectname = ms_item-obj_name(lv_type_pos)
      AND objecttype = ms_item-obj_name+lv_type_pos.    "#EC CI_GENBUFF
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD lif_object~get_metadata.
    rs_metadata = get_metadata( ).
    rs_metadata-late_deser = abap_true.
  ENDMETHOD.                    "lif_object~get_metadata

  METHOD lif_object~exists.

    DATA: lv_objectname TYPE objh-objectname,
          lv_type_pos   TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    SELECT SINGLE objectname FROM objh INTO lv_objectname
      WHERE objectname = ms_item-obj_name(lv_type_pos)
      AND objecttype = ms_item-obj_name+lv_type_pos.    "#EC CI_GENBUFF
    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.                    "lif_object~exists

  METHOD lif_object~serialize.

    DATA: ls_objh     TYPE objh,
          ls_objt     TYPE objt,
          lt_objs     TYPE tt_objs,
          lt_objsl    TYPE tt_objsl,
          lt_objm     TYPE tt_objm,
          lv_type_pos TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    ls_objh-objectname = ms_item-obj_name(lv_type_pos).
    ls_objh-objecttype = ms_item-obj_name+lv_type_pos.

    CALL FUNCTION 'CTO_OBJECT_GET'
      EXPORTING
        iv_objectname      = ls_objh-objectname
        iv_objecttype      = ls_objh-objecttype
        iv_language        = mv_language
        iv_sel_objt        = abap_true
        iv_sel_objs        = abap_true
        iv_sel_objsl       = abap_true
        iv_sel_objm        = abap_true
      IMPORTING
        es_objh            = ls_objh
        es_objt            = ls_objt
      TABLES
        tt_objs            = lt_objs
        tt_objsl           = lt_objsl
        tt_objm            = lt_objm
      EXCEPTIONS
        object_not_defined = 1
        OTHERS             = 2.
    IF sy-subrc = 1.
      RETURN.
    ELSEIF sy-subrc <> 0.
      lcx_exception=>raise( 'error from CTO_OBJECT_GET' ).
    ENDIF.

    CLEAR: ls_objh-luser,
           ls_objh-ldate.

    io_xml->add( iv_name = 'OBJH'
                 ig_data = ls_objh ).
    io_xml->add( iv_name = 'OBJT'
                 ig_data = ls_objt ).
    io_xml->add( iv_name = 'OBJS'
                 ig_data = lt_objs ).
    io_xml->add( iv_name = 'OBJSL'
                 ig_data = lt_objsl ).
    io_xml->add( iv_name = 'OBJM'
                 ig_data = lt_objm ).

  ENDMETHOD.                    "serialize

  METHOD lif_object~deserialize.

    DATA: ls_objh  TYPE objh,
          ls_objt  TYPE objt,
          lt_objs  TYPE tt_objs,
          lt_objsl TYPE tt_objsl,
          lt_objm  TYPE tt_objm.

    io_xml->read( EXPORTING iv_name = 'OBJH'
                  CHANGING cg_data = ls_objh ).
    io_xml->read( EXPORTING iv_name = 'OBJT'
                  CHANGING cg_data = ls_objt ).
    io_xml->read( EXPORTING iv_name = 'OBJS'
                  CHANGING cg_data = lt_objs ).
    io_xml->read( EXPORTING iv_name = 'OBJSL'
                  CHANGING cg_data = lt_objsl ).
    io_xml->read( EXPORTING iv_name = 'OBJM'
                  CHANGING cg_data = lt_objm ).

    CALL FUNCTION 'OBJ_GENERATE'
      EXPORTING
        iv_objectname         = ls_objh-objectname
        iv_objecttype         = ls_objh-objecttype
        iv_maint_mode         = 'I'
        iv_objecttext         = ls_objt-ddtext
        iv_objcateg           = ls_objh-objcateg
        iv_objtransp          = ls_objh-objtransp
        iv_devclass           = iv_package
      TABLES
        tt_v_obj_s            = lt_objs
        tt_objm               = lt_objm
      EXCEPTIONS
        illegal_call          = 1
        object_not_found      = 2
        generate_error        = 3
        transport_error       = 4
        object_enqueue_failed = 5
        OTHERS                = 6.
    IF sy-subrc <> 0.
* TOBJ has to be saved/generated after the DDIC tables have been
* activated - fixed with late deserialization
      lcx_exception=>raise( 'error from OBJ_GENERATE' ).
    ENDIF.

  ENDMETHOD.                    "deserialize

  METHOD lif_object~delete.

    DATA: ls_objh     TYPE objh,
          lv_type_pos TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    ls_objh-objectname = ms_item-obj_name(lv_type_pos).
    ls_objh-objecttype = ms_item-obj_name+lv_type_pos.

    CALL FUNCTION 'OBJ_GENERATE'
      EXPORTING
        iv_objectname         = ls_objh-objectname
        iv_objecttype         = ls_objh-objecttype
        iv_maint_mode         = 'D'
      EXCEPTIONS
        illegal_call          = 1
        object_not_found      = 2
        generate_error        = 3
        transport_error       = 4
        object_enqueue_failed = 5
        OTHERS                = 6.
    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from OBJ_GENERATE' ).
    ENDIF.

  ENDMETHOD.                    "delete

  METHOD lif_object~jump.

    DATA: ls_bcdata TYPE bdcdata,
          lt_bcdata TYPE STANDARD TABLE OF bdcdata.

    ls_bcdata-program  = 'SAPMSVIM'.
    ls_bcdata-dynpro   = '0050'.
    ls_bcdata-dynbegin = 'X'.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'VIMDYNFLDS-VIEWNAME'.
    ls_bcdata-fval = substring( val = ms_item-obj_name
                                len = strlen( ms_item-obj_name ) - 1 ).
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'VIMDYNFLDS-ELEM_GEN'.
    ls_bcdata-fval = abap_true.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'BDC_OKCODE'.
    ls_bcdata-fval = '=SHOW'.
    APPEND ls_bcdata TO lt_bcdata.

    CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
      STARTING NEW TASK 'GIT'
      EXPORTING
        tcode     = 'SE54'
        mode_val  = 'E'
      TABLES
        using_tab = lt_bcdata
      EXCEPTIONS
        OTHERS    = 1.

    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, TOBJ' ).
    ENDIF.

  ENDMETHOD.                    "jump

  METHOD lif_object~compare_to_remote_version.
    CREATE OBJECT ro_comparison_result TYPE lcl_comparison_null.
  ENDMETHOD.

ENDCLASS.                    "lcl_object_tobj IMPLEMENTATION

*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_OBJECT_TOBJ
*&---------------------------------------------------------------------*

*----------------------------------------------------------------------*
*       CLASS lcl_object_tobj DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_object_tobj DEFINITION INHERITING FROM lcl_objects_super FINAL.

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

  PRIVATE SECTION.
    TYPES: BEGIN OF ty_tobj,
             tddat TYPE tddat,
             tvdir TYPE tvdir,
             tvimf TYPE STANDARD TABLE OF tvimf WITH DEFAULT KEY,
           END OF ty_tobj.

    METHODS:
      read_extra IMPORTING iv_tabname     TYPE vim_name
                 RETURNING VALUE(rs_tobj) TYPE ty_tobj,
      update_extra IMPORTING is_tobj TYPE ty_tobj,
      delete_extra IMPORTING iv_tabname TYPE vim_name.

ENDCLASS.                    "lcl_object_tobj DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_object_tobj IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_object_tobj IMPLEMENTATION.

  METHOD read_extra.

    SELECT SINGLE * FROM tddat INTO rs_tobj-tddat WHERE tabname = iv_tabname.

    SELECT SINGLE * FROM tvdir INTO rs_tobj-tvdir WHERE tabname = iv_tabname.

    SELECT * FROM tvimf INTO TABLE rs_tobj-tvimf WHERE tabname = iv_tabname.

  ENDMETHOD.

  METHOD update_extra.

    MODIFY tddat FROM is_tobj-tddat.
    MODIFY tvdir FROM is_tobj-tvdir.
    MODIFY tvimf FROM TABLE is_tobj-tvimf.

  ENDMETHOD.

  METHOD delete_extra.

    DELETE FROM tddat WHERE tabname = iv_tabname.
    DELETE FROM tvdir WHERE tabname = iv_tabname.
    DELETE FROM tvimf WHERE tabname = iv_tabname.

  ENDMETHOD.

  METHOD lif_object~has_changed_since.
    rv_changed = abap_true.
  ENDMETHOD.  "lif_object~has_changed_since

  METHOD lif_object~changed_by.

    DATA: lv_type_pos TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    SELECT SINGLE luser FROM objh INTO rv_user
      WHERE objectname = ms_item-obj_name(lv_type_pos)
      AND objecttype = ms_item-obj_name+lv_type_pos.    "#EC CI_GENBUFF
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD lif_object~get_metadata.
    rs_metadata = get_metadata( ).
    rs_metadata-late_deser = abap_true.
  ENDMETHOD.                    "lif_object~get_metadata

  METHOD lif_object~exists.

    DATA: lv_objectname TYPE objh-objectname,
          lv_type_pos   TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    SELECT SINGLE objectname FROM objh INTO lv_objectname
      WHERE objectname = ms_item-obj_name(lv_type_pos)
      AND objecttype = ms_item-obj_name+lv_type_pos.    "#EC CI_GENBUFF
    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.                    "lif_object~exists

  METHOD lif_object~serialize.

    DATA: ls_objh     TYPE objh,
          ls_objt     TYPE objt,
          lt_objs     TYPE tt_objs,
          lt_objsl    TYPE tt_objsl,
          lt_objm     TYPE tt_objm,
          ls_tobj     TYPE ty_tobj,
          lv_type_pos TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    ls_objh-objectname = ms_item-obj_name(lv_type_pos).
    ls_objh-objecttype = ms_item-obj_name+lv_type_pos.

    CALL FUNCTION 'CTO_OBJECT_GET'
      EXPORTING
        iv_objectname      = ls_objh-objectname
        iv_objecttype      = ls_objh-objecttype
        iv_language        = mv_language
        iv_sel_objt        = abap_true
        iv_sel_objs        = abap_true
        iv_sel_objsl       = abap_true
        iv_sel_objm        = abap_true
      IMPORTING
        es_objh            = ls_objh
        es_objt            = ls_objt
      TABLES
        tt_objs            = lt_objs
        tt_objsl           = lt_objsl
        tt_objm            = lt_objm
      EXCEPTIONS
        object_not_defined = 1
        OTHERS             = 2.
    IF sy-subrc = 1.
      RETURN.
    ELSEIF sy-subrc <> 0.
      lcx_exception=>raise( 'error from CTO_OBJECT_GET' ).
    ENDIF.

    CLEAR: ls_objh-luser,
           ls_objh-ldate.

    io_xml->add( iv_name = 'OBJH'
                 ig_data = ls_objh ).
    io_xml->add( iv_name = 'OBJT'
                 ig_data = ls_objt ).
    io_xml->add( iv_name = 'OBJS'
                 ig_data = lt_objs ).
    io_xml->add( iv_name = 'OBJSL'
                 ig_data = lt_objsl ).
    io_xml->add( iv_name = 'OBJM'
                 ig_data = lt_objm ).

    ls_tobj = read_extra( ls_objh-objectname ).

    io_xml->add( iv_name = 'TOBJ'
                 ig_data = ls_tobj ).

  ENDMETHOD.                    "serialize

  METHOD lif_object~deserialize.

    DATA: ls_objh  TYPE objh,
          ls_objt  TYPE objt,
          lt_objs  TYPE tt_objs,
          lt_objsl TYPE tt_objsl,
          lt_objm  TYPE tt_objm,
          ls_tobj  TYPE ty_tobj.

    io_xml->read( EXPORTING iv_name = 'OBJH'
                  CHANGING cg_data = ls_objh ).
    io_xml->read( EXPORTING iv_name = 'OBJT'
                  CHANGING cg_data = ls_objt ).
    io_xml->read( EXPORTING iv_name = 'OBJS'
                  CHANGING cg_data = lt_objs ).
    io_xml->read( EXPORTING iv_name = 'OBJSL'
                  CHANGING cg_data = lt_objsl ).
    io_xml->read( EXPORTING iv_name = 'OBJM'
                  CHANGING cg_data = lt_objm ).

    CALL FUNCTION 'OBJ_GENERATE'
      EXPORTING
        iv_objectname         = ls_objh-objectname
        iv_objecttype         = ls_objh-objecttype
        iv_maint_mode         = 'I'
        iv_objecttext         = ls_objt-ddtext
        iv_objcateg           = ls_objh-objcateg
        iv_objtransp          = ls_objh-objtransp
        iv_devclass           = iv_package
      TABLES
        tt_v_obj_s            = lt_objs
        tt_objm               = lt_objm
      EXCEPTIONS
        illegal_call          = 1
        object_not_found      = 2
        generate_error        = 3
        transport_error       = 4
        object_enqueue_failed = 5
        OTHERS                = 6.
    IF sy-subrc <> 0.
* TOBJ has to be saved/generated after the DDIC tables have been
* activated - fixed with late deserialization
      lcx_exception=>raise( 'error from OBJ_GENERATE' ).
    ENDIF.

    io_xml->read( EXPORTING iv_name = 'TOBJ'
                  CHANGING cg_data = ls_tobj ).

    update_extra( ls_tobj ).

  ENDMETHOD.                    "deserialize

  METHOD lif_object~delete.

    DATA: ls_objh     TYPE objh,
          lv_type_pos TYPE i.

    lv_type_pos = strlen( ms_item-obj_name ) - 1.

    ls_objh-objectname = ms_item-obj_name(lv_type_pos).
    ls_objh-objecttype = ms_item-obj_name+lv_type_pos.

    CALL FUNCTION 'OBJ_GENERATE'
      EXPORTING
        iv_objectname         = ls_objh-objectname
        iv_objecttype         = ls_objh-objecttype
        iv_maint_mode         = 'D'
      EXCEPTIONS
        illegal_call          = 1
        object_not_found      = 2
        generate_error        = 3
        transport_error       = 4
        object_enqueue_failed = 5
        OTHERS                = 6.
    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from OBJ_GENERATE' ).
    ENDIF.

    delete_extra( ls_objh-objectname ).

  ENDMETHOD.                    "delete

  METHOD lif_object~jump.

    DATA: ls_bcdata TYPE bdcdata,
          lt_bcdata TYPE STANDARD TABLE OF bdcdata.

    ls_bcdata-program  = 'SAPMSVIM'.
    ls_bcdata-dynpro   = '0050'.
    ls_bcdata-dynbegin = 'X'.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'VIMDYNFLDS-VIEWNAME'.
    ls_bcdata-fval = substring( val = ms_item-obj_name
                                len = strlen( ms_item-obj_name ) - 1 ).
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'VIMDYNFLDS-ELEM_GEN'.
    ls_bcdata-fval = abap_true.
    APPEND ls_bcdata TO lt_bcdata.

    CLEAR ls_bcdata.
    ls_bcdata-fnam = 'BDC_OKCODE'.
    ls_bcdata-fval = '=SHOW'.
    APPEND ls_bcdata TO lt_bcdata.

    CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
      STARTING NEW TASK 'GIT'
      EXPORTING
        tcode     = 'SE54'
        mode_val  = 'E'
      TABLES
        using_tab = lt_bcdata
      EXCEPTIONS
        OTHERS    = 1.

    IF sy-subrc <> 0.
      lcx_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, TOBJ' ).
    ENDIF.

  ENDMETHOD.                    "jump

  METHOD lif_object~compare_to_remote_version.
    CREATE OBJECT ro_comparison_result TYPE lcl_comparison_null.
  ENDMETHOD.

ENDCLASS.                    "lcl_object_tobj IMPLEMENTATION

fix #880

fix #880


CLASS zcl_abapgit_gui_page_repo_sett DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_gui_page
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    METHODS constructor
      IMPORTING
        !io_repo TYPE REF TO zcl_abapgit_repo
      RAISING zcx_abapgit_exception.

    METHODS zif_abapgit_gui_event_handler~on_event
        REDEFINITION .
  PROTECTED SECTION.

    CONSTANTS:
      BEGIN OF c_action,
        save_settings TYPE string VALUE 'save_settings',
      END OF c_action .
    DATA mo_repo TYPE REF TO zcl_abapgit_repo.

    METHODS render_dot_abapgit
      IMPORTING
        !io_html TYPE REF TO zcl_abapgit_html .
    METHODS render_local_settings
      IMPORTING
        !io_html TYPE REF TO zcl_abapgit_html
      RAISING
        zcx_abapgit_exception .
    METHODS save
      IMPORTING
        !it_postdata TYPE cnht_post_data_tab
      RAISING
        zcx_abapgit_exception .
    METHODS save_dot_abap
      IMPORTING
        !it_post_fields TYPE tihttpnvp
      RAISING
        zcx_abapgit_exception .
    METHODS save_local_settings
      IMPORTING
        !it_post_fields TYPE tihttpnvp
      RAISING
        zcx_abapgit_exception .
    METHODS parse_post
      IMPORTING
        !it_postdata          TYPE cnht_post_data_tab
      RETURNING
        VALUE(rt_post_fields) TYPE tihttpnvp .
    METHODS render_dot_abapgit_reqs
      IMPORTING
        io_html TYPE REF TO zcl_abapgit_html
        it_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt.
    METHODS render_table_row
      IMPORTING
        iv_name TYPE string
        iv_value TYPE string
      RETURNING
        VALUE(rv_html) TYPE string.

    METHODS render_content
        REDEFINITION .

  PRIVATE SECTION.

ENDCLASS.

CLASS ZCL_ABAPGIT_GUI_PAGE_REPO_SETT IMPLEMENTATION.

  METHOD constructor.
    super->constructor( ).
    ms_control-page_title = 'REPO SETTINGS'.
    mo_repo = io_repo.
  ENDMETHOD.

  METHOD parse_post.

    DATA lv_serialized_post_data TYPE string.

    CONCATENATE LINES OF it_postdata INTO lv_serialized_post_data.
    rt_post_fields = zcl_abapgit_html_action_utils=>parse_fields( lv_serialized_post_data ).

  ENDMETHOD.

  METHOD render_content.

    CREATE OBJECT ro_html.
    ro_html->add( '
' ).
    ro_html->add( |<form id="settings_form" method="post" action="sapevent:{ c_action-save_settings }">| ).

    render_dot_abapgit( ro_html ).
    render_local_settings( ro_html ).

    ro_html->add( '<input type="submit" value="Save" class="floating-button blue-set emphasis">' ).
    ro_html->add( '</form>' ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_dot_abapgit.

    DATA: ls_dot               TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit,
          lv_select_html       TYPE string,
          lv_selected          TYPE string,
          lt_folder_logic      TYPE string_table.

    FIELD-SYMBOLS: <lv_folder_logic> TYPE LINE OF string_table.

    ls_dot = mo_repo->get_dot_abapgit( )->get_data( ).

    APPEND zif_abapgit_dot_abapgit=>c_folder_logic-full TO lt_folder_logic.
    APPEND zif_abapgit_dot_abapgit=>c_folder_logic-prefix TO lt_folder_logic.

    io_html->add( '
.abapgit.xml
' ).
    io_html->add( '
' ).

    lv_select_html = '<select name="folder_logic">'.
    LOOP AT lt_folder_logic ASSIGNING <lv_folder_logic>.

      IF ls_dot-folder_logic = <lv_folder_logic>.
        lv_selected = ' selected'.
      ELSE.
        CLEAR: lv_selected.
      ENDIF.

      lv_select_html = lv_select_html
        && |<option value="{ <lv_folder_logic> }"{ lv_selected }>{ <lv_folder_logic> }</option>|.

    ENDLOOP.
    lv_select_html = lv_select_html && '</select>'.

    io_html->add( render_table_row(
      iv_name  = 'Folder logic'
      iv_value = lv_select_html
    ) ).

    io_html->add( render_table_row(
      iv_name  = 'Starting folder'
      iv_value = |<input name="starting_folder" type="text" size="10" value="{ ls_dot-starting_folder }">|
    ) ).

    io_html->add( '
' ).

    render_dot_abapgit_reqs(
      it_requirements = ls_dot-requirements
      io_html         = io_html ).

  ENDMETHOD.

  METHOD render_dot_abapgit_reqs.

    CONSTANTS: lc_requirement_edit_min_count TYPE i VALUE 5.
    DATA lv_req_index TYPE i.
    DATA lv_requirement_count TYPE i.
    DATA lt_requirements LIKE it_requirements.
    FIELD-SYMBOLS <ls_requirement> TYPE zif_abapgit_dot_abapgit=>ty_requirement.

    lt_requirements      = it_requirements.
    lv_requirement_count = lines( lt_requirements ).
    IF lv_requirement_count < lc_requirement_edit_min_count.
      DO - lv_requirement_count + lc_requirement_edit_min_count TIMES.
        APPEND INITIAL LINE TO lt_requirements.
      ENDDO.
    ENDIF.

    io_html->add( '
Requirements
' ).
    io_html->add( '
' ).
    io_html->add( '
Software Component	Min Release	Min Patch
' ).

    LOOP AT lt_requirements ASSIGNING <ls_requirement>.
      lv_req_index = sy-tabix.

      io_html->add( '
' ).
      io_html->add( |<input name="req_com_{ lv_req_index }" maxlength=30 type="text" | &&
                    |value="{ <ls_requirement>-component }">	| ).
      io_html->add( |<input name="req_rel_{ lv_req_index }" maxlength=10 type="text" | &&
                    |value="{ <ls_requirement>-min_release }">	| ).
      io_html->add( |<input name="req_pat_{ lv_req_index }" maxlength=10 type="text" | &&
                    |value="{ <ls_requirement>-min_patch }">	| ).
      io_html->add( '
' ).
    ENDLOOP.

    io_html->add( '
' ).

  ENDMETHOD.

  METHOD render_local_settings.

    DATA: lv_checked  TYPE string,
          ls_settings TYPE zif_abapgit_persistence=>ty_repo-local_settings.

    ls_settings = mo_repo->get_local_settings( ).

    io_html->add( '
Local settings
' ).
    io_html->add( '
' ).

    IF mo_repo->is_offline( ) = abap_false.
      io_html->add( render_table_row(
        iv_name  = 'Display name'
        iv_value = |<input name="display_name" type="text" size="30" value="{ ls_settings-display_name }">|
      ) ).
    ENDIF.

    CLEAR lv_checked.
    IF ls_settings-write_protected = abap_true.
      IF zcl_abapgit_factory=>get_environment( )->is_repo_object_changes_allowed( ) = abap_true.
        lv_checked = | checked|.
      ELSE.
        lv_checked = | checked disabled|.
      ENDIF.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Write protected'
      iv_value = |<input name="write_protected" type="checkbox"{ lv_checked }>|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-ignore_subpackages = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Ignore subpackages'
      iv_value = |<input name="ignore_subpackages" type="checkbox"{ lv_checked }>|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-only_local_objects = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Only local objects'
      iv_value = |<input name="only_local_objects" type="checkbox"{ lv_checked }>|
    ) ).

    io_html->add( render_table_row(
      iv_name  = 'Code inspector check variant'
      iv_value = |<input name="check_variant" type="text" size="30" value="{
        ls_settings-code_inspector_check_variant }">|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-block_commit = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Block commit if code inspection has errors'
      iv_value = |<input name="block_commit" type="checkbox"{ lv_checked }>|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-serialize_master_lang_only = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Serialize master language only'
      iv_value = |<input name="serialize_master_lang_only" type="checkbox"{ lv_checked }>|
    ) ).

    io_html->add( '
' ).

  ENDMETHOD.

  METHOD render_table_row.

    rv_html = '
'
      && |{ iv_name }	|
      && |{ iv_value }	|
      && '
'.

  ENDMETHOD.

  METHOD save.

    DATA: lt_post_fields TYPE tihttpnvp.

    lt_post_fields = parse_post( it_postdata ).

    save_dot_abap( lt_post_fields ).
    save_local_settings( lt_post_fields ).

    mo_repo->refresh( ).

  ENDMETHOD.

  METHOD save_dot_abap.

    DATA: lo_dot          TYPE REF TO zcl_abapgit_dot_abapgit,
          ls_post_field   LIKE LINE OF it_post_fields,
          lo_requirements TYPE REF TO lcl_requirements.

    lo_dot = mo_repo->get_dot_abapgit( ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'folder_logic'.
    ASSERT sy-subrc = 0.
    lo_dot->set_folder_logic( ls_post_field-value ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'starting_folder'.
    ASSERT sy-subrc = 0.
    lo_dot->set_starting_folder( ls_post_field-value ).

    lo_requirements = lcl_requirements=>new( ).
    LOOP AT it_post_fields INTO ls_post_field WHERE name CP 'req_*'.
      CASE ls_post_field-name+4(3).
        WHEN 'com'.
          lo_requirements->set_component( ls_post_field-value ).
        WHEN 'rel'.
          lo_requirements->set_min_release( ls_post_field-value ).
        WHEN 'pat'.
          lo_requirements->set_min_patch( ls_post_field-value ).
      ENDCASE.
    ENDLOOP.

    lo_dot->set_requirements( lo_requirements->get_as_table( ) ).

    mo_repo->set_dot_abapgit( lo_dot ).

  ENDMETHOD.

  METHOD save_local_settings.

    DATA: ls_settings      TYPE zif_abapgit_persistence=>ty_repo-local_settings,
          ls_post_field    LIKE LINE OF it_post_fields,
          lv_check_variant TYPE sci_chkv.

    ls_settings = mo_repo->get_local_settings( ).

    IF mo_repo->is_offline( ) = abap_false.
      READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'display_name'.
      ASSERT sy-subrc = 0.
      ls_settings-display_name = ls_post_field-value.
    ENDIF.

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'write_protected' value = 'on'.
    ls_settings-write_protected = boolc( sy-subrc = 0 ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'ignore_subpackages' value = 'on'.
    ls_settings-ignore_subpackages = boolc( sy-subrc = 0 ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'only_local_objects' value = 'on'.
    ls_settings-only_local_objects = boolc( sy-subrc = 0 ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'check_variant'.
    ASSERT sy-subrc = 0.
    lv_check_variant = to_upper( ls_post_field-value ).
    IF ls_post_field-value IS NOT INITIAL.
      zcl_abapgit_code_inspector=>validate_check_variant( lv_check_variant ).
    ENDIF.
    ls_settings-code_inspector_check_variant = lv_check_variant.

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'block_commit' value = 'on'.
    ls_settings-block_commit = boolc( sy-subrc = 0 ).

    IF ls_settings-block_commit = abap_true
        AND ls_settings-code_inspector_check_variant IS INITIAL.
      zcx_abapgit_exception=>raise( |If block commit is active, a check variant has to be maintained.| ).
    ENDIF.

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'serialize_master_lang_only' value = 'on'.
    ls_settings-serialize_master_lang_only = boolc( sy-subrc = 0 ).

    mo_repo->set_local_settings( ls_settings ).

  ENDMETHOD.

  METHOD zif_abapgit_gui_event_handler~on_event.

    CASE iv_action.
      WHEN c_action-save_settings.
        save( it_postdata ).
        ev_state = zcl_abapgit_gui=>c_event_state-go_back.
    ENDCASE.

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_gui_page_repo_sett DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_gui_page
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    METHODS constructor
      IMPORTING
        !io_repo TYPE REF TO zcl_abapgit_repo
      RAISING zcx_abapgit_exception.

    METHODS zif_abapgit_gui_event_handler~on_event
        REDEFINITION .
  PROTECTED SECTION.

    CONSTANTS:
      BEGIN OF c_action,
        save_settings TYPE string VALUE 'save_settings',
      END OF c_action .
    DATA mo_repo TYPE REF TO zcl_abapgit_repo.

    METHODS render_dot_abapgit
      IMPORTING
        !io_html TYPE REF TO zcl_abapgit_html .
    METHODS render_local_settings
      IMPORTING
        !io_html TYPE REF TO zcl_abapgit_html
      RAISING
        zcx_abapgit_exception .
    METHODS save
      IMPORTING
        !it_postdata TYPE cnht_post_data_tab
      RAISING
        zcx_abapgit_exception .
    METHODS save_dot_abap
      IMPORTING
        !it_post_fields TYPE tihttpnvp
      RAISING
        zcx_abapgit_exception .
    METHODS save_local_settings
      IMPORTING
        !it_post_fields TYPE tihttpnvp
      RAISING
        zcx_abapgit_exception .
    METHODS parse_post
      IMPORTING
        !it_postdata          TYPE cnht_post_data_tab
      RETURNING
        VALUE(rt_post_fields) TYPE tihttpnvp .
    METHODS render_dot_abapgit_reqs
      IMPORTING
        io_html TYPE REF TO zcl_abapgit_html
        it_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt.
    METHODS render_table_row
      IMPORTING
        iv_name TYPE string
        iv_value TYPE string
      RETURNING
        VALUE(rv_html) TYPE string.

    METHODS render_content
        REDEFINITION .

  PRIVATE SECTION.

ENDCLASS.

CLASS ZCL_ABAPGIT_GUI_PAGE_REPO_SETT IMPLEMENTATION.

  METHOD constructor.
    super->constructor( ).
    ms_control-page_title = 'REPO SETTINGS'.
    mo_repo = io_repo.
  ENDMETHOD.

  METHOD parse_post.

    DATA lv_serialized_post_data TYPE string.

    CONCATENATE LINES OF it_postdata INTO lv_serialized_post_data.
    rt_post_fields = zcl_abapgit_html_action_utils=>parse_fields( lv_serialized_post_data ).

  ENDMETHOD.

  METHOD render_content.

    CREATE OBJECT ro_html.
    ro_html->add( '
' ).
    ro_html->add( |<form id="settings_form" method="post" action="sapevent:{ c_action-save_settings }">| ).

    render_dot_abapgit( ro_html ).
    render_local_settings( ro_html ).

    ro_html->add( '<input type="submit" value="Save" class="floating-button blue-set emphasis">' ).
    ro_html->add( '</form>' ).
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_dot_abapgit.

    DATA: ls_dot               TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit,
          lv_select_html       TYPE string,
          lv_selected          TYPE string,
          lt_folder_logic      TYPE string_table.

    FIELD-SYMBOLS: <lv_folder_logic> TYPE LINE OF string_table.

    ls_dot = mo_repo->get_dot_abapgit( )->get_data( ).

    APPEND zif_abapgit_dot_abapgit=>c_folder_logic-full TO lt_folder_logic.
    APPEND zif_abapgit_dot_abapgit=>c_folder_logic-prefix TO lt_folder_logic.

    io_html->add( '
.abapgit.xml
' ).
    io_html->add( '
' ).

    lv_select_html = '<select name="folder_logic">'.
    LOOP AT lt_folder_logic ASSIGNING <lv_folder_logic>.

      IF ls_dot-folder_logic = <lv_folder_logic>.
        lv_selected = ' selected'.
      ELSE.
        CLEAR: lv_selected.
      ENDIF.

      lv_select_html = lv_select_html
        && |<option value="{ <lv_folder_logic> }"{ lv_selected }>{ <lv_folder_logic> }</option>|.

    ENDLOOP.
    lv_select_html = lv_select_html && '</select>'.

    io_html->add( render_table_row(
      iv_name  = 'Folder logic'
      iv_value = lv_select_html
    ) ).

    io_html->add( render_table_row(
      iv_name  = 'Starting folder'
      iv_value = |<input name="starting_folder" type="text" size="10" value="{ ls_dot-starting_folder }">|
    ) ).

    io_html->add( '
' ).

    render_dot_abapgit_reqs(
      it_requirements = ls_dot-requirements
      io_html         = io_html ).

  ENDMETHOD.

  METHOD render_dot_abapgit_reqs.

    CONSTANTS: lc_requirement_edit_min_count TYPE i VALUE 5.
    DATA lv_req_index TYPE i.
    DATA lv_requirement_count TYPE i.
    DATA lt_requirements LIKE it_requirements.
    FIELD-SYMBOLS <ls_requirement> TYPE zif_abapgit_dot_abapgit=>ty_requirement.

    lt_requirements      = it_requirements.
    lv_requirement_count = lines( lt_requirements ).
    IF lv_requirement_count < lc_requirement_edit_min_count.
      DO - lv_requirement_count + lc_requirement_edit_min_count TIMES.
        APPEND INITIAL LINE TO lt_requirements.
      ENDDO.
    ENDIF.

    io_html->add( '
Requirements
' ).
    io_html->add( '
' ).
    io_html->add( '
Software Component	Min Release	Min Patch
' ).

    LOOP AT lt_requirements ASSIGNING <ls_requirement>.
      lv_req_index = sy-tabix.

      io_html->add( '
' ).
      io_html->add( |<input name="req_com_{ lv_req_index }" maxlength=30 type="text" | &&
                    |value="{ <ls_requirement>-component }">	| ).
      io_html->add( |<input name="req_rel_{ lv_req_index }" maxlength=10 type="text" | &&
                    |value="{ <ls_requirement>-min_release }">	| ).
      io_html->add( |<input name="req_pat_{ lv_req_index }" maxlength=10 type="text" | &&
                    |value="{ <ls_requirement>-min_patch }">	| ).
      io_html->add( '
' ).
    ENDLOOP.

    io_html->add( '
' ).

  ENDMETHOD.

  METHOD render_local_settings.

    DATA: lv_checked  TYPE string,
          ls_settings TYPE zif_abapgit_persistence=>ty_repo-local_settings.

    ls_settings = mo_repo->get_local_settings( ).

    io_html->add( '
Local settings
' ).
    io_html->add( '
' ).

    io_html->add( render_table_row(
      iv_name  = 'Display name'
      iv_value = |<input name="display_name" type="text" size="30" value="{ ls_settings-display_name }">|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-write_protected = abap_true.
      IF zcl_abapgit_factory=>get_environment( )->is_repo_object_changes_allowed( ) = abap_true.
        lv_checked = | checked|.
      ELSE.
        lv_checked = | checked disabled|.
      ENDIF.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Write protected'
      iv_value = |<input name="write_protected" type="checkbox"{ lv_checked }>|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-ignore_subpackages = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Ignore subpackages'
      iv_value = |<input name="ignore_subpackages" type="checkbox"{ lv_checked }>|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-only_local_objects = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Only local objects'
      iv_value = |<input name="only_local_objects" type="checkbox"{ lv_checked }>|
    ) ).

    io_html->add( render_table_row(
      iv_name  = 'Code inspector check variant'
      iv_value = |<input name="check_variant" type="text" size="30" value="{
        ls_settings-code_inspector_check_variant }">|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-block_commit = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Block commit if code inspection has errors'
      iv_value = |<input name="block_commit" type="checkbox"{ lv_checked }>|
    ) ).

    CLEAR lv_checked.
    IF ls_settings-serialize_master_lang_only = abap_true.
      lv_checked = | checked|.
    ENDIF.
    io_html->add( render_table_row(
      iv_name  = 'Serialize master language only'
      iv_value = |<input name="serialize_master_lang_only" type="checkbox"{ lv_checked }>|
    ) ).

    io_html->add( '
' ).

  ENDMETHOD.

  METHOD render_table_row.

    rv_html = '
'
      && |{ iv_name }	|
      && |{ iv_value }	|
      && '
'.

  ENDMETHOD.

  METHOD save.

    DATA: lt_post_fields TYPE tihttpnvp.

    lt_post_fields = parse_post( it_postdata ).

    save_dot_abap( lt_post_fields ).
    save_local_settings( lt_post_fields ).

    mo_repo->refresh( ).

  ENDMETHOD.

  METHOD save_dot_abap.

    DATA: lo_dot          TYPE REF TO zcl_abapgit_dot_abapgit,
          ls_post_field   LIKE LINE OF it_post_fields,
          lo_requirements TYPE REF TO lcl_requirements.

    lo_dot = mo_repo->get_dot_abapgit( ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'folder_logic'.
    ASSERT sy-subrc = 0.
    lo_dot->set_folder_logic( ls_post_field-value ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'starting_folder'.
    ASSERT sy-subrc = 0.
    lo_dot->set_starting_folder( ls_post_field-value ).

    lo_requirements = lcl_requirements=>new( ).
    LOOP AT it_post_fields INTO ls_post_field WHERE name CP 'req_*'.
      CASE ls_post_field-name+4(3).
        WHEN 'com'.
          lo_requirements->set_component( ls_post_field-value ).
        WHEN 'rel'.
          lo_requirements->set_min_release( ls_post_field-value ).
        WHEN 'pat'.
          lo_requirements->set_min_patch( ls_post_field-value ).
      ENDCASE.
    ENDLOOP.

    lo_dot->set_requirements( lo_requirements->get_as_table( ) ).

    mo_repo->set_dot_abapgit( lo_dot ).

  ENDMETHOD.

  METHOD save_local_settings.

    DATA: ls_settings      TYPE zif_abapgit_persistence=>ty_repo-local_settings,
          ls_post_field    LIKE LINE OF it_post_fields,
          lv_check_variant TYPE sci_chkv.

    ls_settings = mo_repo->get_local_settings( ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'display_name'.
    ASSERT sy-subrc = 0.
    ls_settings-display_name = ls_post_field-value.

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'write_protected' value = 'on'.
    ls_settings-write_protected = boolc( sy-subrc = 0 ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'ignore_subpackages' value = 'on'.
    ls_settings-ignore_subpackages = boolc( sy-subrc = 0 ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'only_local_objects' value = 'on'.
    ls_settings-only_local_objects = boolc( sy-subrc = 0 ).

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'check_variant'.
    ASSERT sy-subrc = 0.
    lv_check_variant = to_upper( ls_post_field-value ).
    IF ls_post_field-value IS NOT INITIAL.
      zcl_abapgit_code_inspector=>validate_check_variant( lv_check_variant ).
    ENDIF.
    ls_settings-code_inspector_check_variant = lv_check_variant.

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'block_commit' value = 'on'.
    ls_settings-block_commit = boolc( sy-subrc = 0 ).

    IF ls_settings-block_commit = abap_true
        AND ls_settings-code_inspector_check_variant IS INITIAL.
      zcx_abapgit_exception=>raise( |If block commit is active, a check variant has to be maintained.| ).
    ENDIF.

    READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'serialize_master_lang_only' value = 'on'.
    ls_settings-serialize_master_lang_only = boolc( sy-subrc = 0 ).

    mo_repo->set_local_settings( ls_settings ).

  ENDMETHOD.

  METHOD zif_abapgit_gui_event_handler~on_event.

    CASE iv_action.
      WHEN c_action-save_settings.
        save( it_postdata ).
        ev_state = zcl_abapgit_gui=>c_event_state-go_back.
    ENDCASE.

  ENDMETHOD.
ENDCLASS.

Allow setting of display name for offline repos (#3359)

Minor improvement to enable "Display Name" setting for offline projects which is shown in favorites for example


CLASS zcl_abapgit_tadir DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    CLASS-METHODS read
      IMPORTING
        !iv_package            TYPE tadir-devclass
        !iv_ignore_subpackages TYPE abap_bool DEFAULT abap_false
        !iv_only_local_objects TYPE abap_bool DEFAULT abap_false
        !io_dot                TYPE REF TO zcl_abapgit_dot_abapgit OPTIONAL
        !io_log                TYPE REF TO zcl_abapgit_log OPTIONAL
      RETURNING
        VALUE(rt_tadir)        TYPE zif_abapgit_definitions=>ty_tadir_tt
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS read_single
      IMPORTING
        !iv_pgmid       TYPE tadir-pgmid DEFAULT 'R3TR'
        !iv_object      TYPE tadir-object
        !iv_obj_name    TYPE tadir-obj_name
      RETURNING
        VALUE(rs_tadir) TYPE tadir
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS get_object_package
      IMPORTING
        !iv_pgmid          TYPE tadir-pgmid DEFAULT 'R3TR'
        !iv_object         TYPE tadir-object
        !iv_obj_name       TYPE tadir-obj_name
      RETURNING
        VALUE(rv_devclass) TYPE tadir-devclass
      RAISING
        zcx_abapgit_exception .

  PRIVATE SECTION.

    CLASS-METHODS exists
      IMPORTING
        is_item          TYPE zif_abapgit_definitions=>ty_item
      RETURNING
        VALUE(rv_exists) TYPE abap_bool.
    CLASS-METHODS check_exists
      IMPORTING
        !it_tadir       TYPE zif_abapgit_definitions=>ty_tadir_tt
      RETURNING
        VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS build
      IMPORTING
        !iv_package            TYPE tadir-devclass
        !iv_top                TYPE tadir-devclass
        !io_dot                TYPE REF TO zcl_abapgit_dot_abapgit
        !iv_ignore_subpackages TYPE abap_bool DEFAULT abap_false
        !iv_only_local_objects TYPE abap_bool
        !io_log                TYPE REF TO zcl_abapgit_log OPTIONAL
      RETURNING
        VALUE(rt_tadir)        TYPE zif_abapgit_definitions=>ty_tadir_tt
      RAISING
        zcx_abapgit_exception .
ENDCLASS.

CLASS zcl_abapgit_tadir IMPLEMENTATION.

  METHOD build.

    DATA: lt_tadir        TYPE zif_abapgit_definitions=>ty_tadir_tt,
          lt_tdevc        TYPE STANDARD TABLE OF tdevc,
          lv_path         TYPE string,
          lo_skip_objects TYPE REF TO zcl_abapgit_skip_objects,
          lt_excludes     TYPE RANGE OF trobjtype,
          lt_srcsystem    TYPE RANGE OF tadir-srcsystem,
          ls_srcsystem    LIKE LINE OF lt_srcsystem,
          ls_exclude      LIKE LINE OF lt_excludes.

    FIELD-SYMBOLS: <ls_tdevc> LIKE LINE OF lt_tdevc,
                   <ls_tadir> LIKE LINE OF rt_tadir.

    ls_exclude-sign = 'I'.
    ls_exclude-option = 'EQ'.

    ls_exclude-low = 'SOTR'.
    APPEND ls_exclude TO lt_excludes.
    ls_exclude-low = 'SFB1'.
    APPEND ls_exclude TO lt_excludes.
    ls_exclude-low = 'SFB2'.
    APPEND ls_exclude TO lt_excludes.
    ls_exclude-low = 'STOB'. " auto generated by core data services
    APPEND ls_exclude TO lt_excludes.

    IF iv_only_local_objects = abap_true.
      ls_srcsystem-sign   = 'I'.
      ls_srcsystem-option = 'EQ'.
      ls_srcsystem-low    = sy-sysid.
      APPEND ls_srcsystem TO lt_srcsystem.
    ENDIF.

    SELECT * FROM tadir
      INTO CORRESPONDING FIELDS OF TABLE rt_tadir
      WHERE devclass = iv_package
      AND pgmid = 'R3TR'
      AND object NOT IN lt_excludes
      AND delflag = abap_false
      AND srcsystem IN lt_srcsystem
      ORDER BY PRIMARY KEY.               "#EC CI_GENBUFF "#EC CI_SUBRC

    CREATE OBJECT lo_skip_objects.
    rt_tadir = lo_skip_objects->skip_sadl_generated_objects(
      it_tadir = rt_tadir
      io_log   = io_log ).

    " Local packages are not in TADIR, only in TDEVC, act as if they were
    IF iv_package CP '$*'. " OR iv_package CP 'T*' ).
      APPEND INITIAL LINE TO rt_tadir ASSIGNING <ls_tadir>.
      <ls_tadir>-pgmid    = 'R3TR'.
      <ls_tadir>-object   = 'DEVC'.
      <ls_tadir>-obj_name = iv_package.
      <ls_tadir>-devclass = iv_package.
    ENDIF.

    IF NOT io_dot IS INITIAL.
      lv_path = zcl_abapgit_folder_logic=>package_to_path(
        iv_top     = iv_top
        io_dot     = io_dot
        iv_package = iv_package ).
    ENDIF.

    LOOP AT rt_tadir ASSIGNING <ls_tadir>.
      <ls_tadir>-path = lv_path.

      CASE <ls_tadir>-object.
        WHEN 'SICF'.
* replace the internal GUID with a hash of the path
          <ls_tadir>-obj_name+15 = zcl_abapgit_object_sicf=>read_sicf_url( <ls_tadir>-obj_name ).
      ENDCASE.
    ENDLOOP.

* look for subpackages
    IF iv_ignore_subpackages = abap_false.
      SELECT * FROM tdevc INTO TABLE lt_tdevc
        WHERE parentcl = iv_package
        ORDER BY PRIMARY KEY.             "#EC CI_SUBRC "#EC CI_GENBUFF
    ENDIF.

    LOOP AT lt_tdevc ASSIGNING <ls_tdevc>.
      lt_tadir = build( iv_package            = <ls_tdevc>-devclass
                        iv_only_local_objects = iv_only_local_objects
                        iv_top                = iv_top
                        io_dot                = io_dot
                        io_log                = io_log ).
      APPEND LINES OF lt_tadir TO rt_tadir.
    ENDLOOP.

  ENDMETHOD.                    "build

  METHOD check_exists.

    DATA: lv_exists   TYPE abap_bool,
          lo_progress TYPE REF TO zcl_abapgit_progress,
          ls_item     TYPE zif_abapgit_definitions=>ty_item.

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

    CREATE OBJECT lo_progress
      EXPORTING
        iv_total = lines( it_tadir ).

* rows from database table TADIR are not removed for
* transportable objects until the transport is released
    LOOP AT it_tadir ASSIGNING <ls_tadir>.
      IF sy-tabix MOD 200 = 0.
        lo_progress->show(
          iv_current = sy-tabix
          iv_text    = |Check object exists { <ls_tadir>-object } { <ls_tadir>-obj_name }| ).
      ENDIF.

      ls_item-obj_type = <ls_tadir>-object.
      ls_item-obj_name = <ls_tadir>-obj_name.
      ls_item-devclass = <ls_tadir>-devclass.

      IF exists( ls_item ) = abap_true.
        APPEND <ls_tadir> TO rt_tadir.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.                    "check_exists

  METHOD exists.

    IF zcl_abapgit_objects=>is_supported( is_item ) = abap_false.
      rv_exists = abap_true.
      RETURN.
    ENDIF.

    rv_exists = zcl_abapgit_objects=>exists( is_item ).

  ENDMETHOD.

  METHOD get_object_package.

    DATA: ls_tadir TYPE tadir,
          ls_item  TYPE zif_abapgit_definitions=>ty_item.

    ls_tadir = read_single( iv_pgmid    = iv_pgmid
                            iv_object   = iv_object
                            iv_obj_name = iv_obj_name ).

    IF ls_tadir-delflag = 'X'.
      RETURN. "Mark for deletion -> return nothing
    ENDIF.

    ls_item-obj_type = ls_tadir-object.
    ls_item-obj_name = ls_tadir-obj_name.
    ls_item-devclass = ls_tadir-devclass.
    IF exists( ls_item ) = abap_false.
      RETURN.
    ENDIF.

    rv_devclass = ls_tadir-devclass.

  ENDMETHOD.  "get_object_package.

  METHOD read.

* start recursion
* hmm, some problems here, should TADIR also build path?
    rt_tadir = build( iv_package            = iv_package
                      iv_top                = iv_package
                      io_dot                = io_dot
                      iv_ignore_subpackages = iv_ignore_subpackages
                      iv_only_local_objects = iv_only_local_objects
                      io_log                = io_log ).

    rt_tadir = check_exists( rt_tadir ).

  ENDMETHOD.                    "read

  METHOD read_single.

    IF iv_object = 'SICF'.
      rs_tadir = zcl_abapgit_object_sicf=>read_tadir_sicf(
        iv_pgmid    = iv_pgmid
        iv_obj_name = iv_obj_name ).
    ELSE.
      SELECT SINGLE * FROM tadir INTO rs_tadir
        WHERE pgmid = iv_pgmid
        AND object = iv_object
        AND obj_name = iv_obj_name.                       "#EC CI_SUBRC
    ENDIF.

  ENDMETHOD.                    "read_single
ENDCLASS.

CLASS zcl_abapgit_tadir DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    CLASS-METHODS read
      IMPORTING
        !iv_package            TYPE tadir-devclass
        !iv_ignore_subpackages TYPE abap_bool DEFAULT abap_false
        !iv_only_local_objects TYPE abap_bool DEFAULT abap_false
        !io_dot                TYPE REF TO zcl_abapgit_dot_abapgit OPTIONAL
        !io_log                TYPE REF TO zcl_abapgit_log OPTIONAL
      RETURNING
        VALUE(rt_tadir)        TYPE zif_abapgit_definitions=>ty_tadir_tt
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS read_single
      IMPORTING
        !iv_pgmid       TYPE tadir-pgmid DEFAULT 'R3TR'
        !iv_object      TYPE tadir-object
        !iv_obj_name    TYPE tadir-obj_name
      RETURNING
        VALUE(rs_tadir) TYPE tadir
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS get_object_package
      IMPORTING
        !iv_pgmid          TYPE tadir-pgmid DEFAULT 'R3TR'
        !iv_object         TYPE tadir-object
        !iv_obj_name       TYPE tadir-obj_name
      RETURNING
        VALUE(rv_devclass) TYPE tadir-devclass
      RAISING
        zcx_abapgit_exception .

  PRIVATE SECTION.

    CLASS-METHODS exists
      IMPORTING
        is_item          TYPE zif_abapgit_definitions=>ty_item
      RETURNING
        VALUE(rv_exists) TYPE abap_bool.
    CLASS-METHODS check_exists
      IMPORTING
        !it_tadir       TYPE zif_abapgit_definitions=>ty_tadir_tt
      RETURNING
        VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt
      RAISING
        zcx_abapgit_exception .
    CLASS-METHODS build
      IMPORTING
        !iv_package            TYPE tadir-devclass
        !iv_top                TYPE tadir-devclass
        !io_dot                TYPE REF TO zcl_abapgit_dot_abapgit
        !iv_ignore_subpackages TYPE abap_bool DEFAULT abap_false
        !iv_only_local_objects TYPE abap_bool
        !io_log                TYPE REF TO zcl_abapgit_log OPTIONAL
      RETURNING
        VALUE(rt_tadir)        TYPE zif_abapgit_definitions=>ty_tadir_tt
      RAISING
        zcx_abapgit_exception .
ENDCLASS.

CLASS ZCL_ABAPGIT_TADIR IMPLEMENTATION.

  METHOD build.

    DATA: lt_tadir        TYPE zif_abapgit_definitions=>ty_tadir_tt,
          lt_tdevc        TYPE STANDARD TABLE OF tdevc,
          lv_path         TYPE string,
          lo_skip_objects TYPE REF TO zcl_abapgit_skip_objects,
          lt_excludes     TYPE RANGE OF trobjtype,
          lt_srcsystem    TYPE RANGE OF tadir-srcsystem,
          ls_srcsystem    LIKE LINE OF lt_srcsystem,
          ls_exclude      LIKE LINE OF lt_excludes.

    FIELD-SYMBOLS: <ls_tdevc> LIKE LINE OF lt_tdevc,
                   <ls_tadir> LIKE LINE OF rt_tadir.

    ls_exclude-sign = 'I'.
    ls_exclude-option = 'EQ'.

    ls_exclude-low = 'SOTR'.
    APPEND ls_exclude TO lt_excludes.
    ls_exclude-low = 'SFB1'.
    APPEND ls_exclude TO lt_excludes.
    ls_exclude-low = 'SFB2'.
    APPEND ls_exclude TO lt_excludes.
    ls_exclude-low = 'STOB'. " auto generated by core data services
    APPEND ls_exclude TO lt_excludes.

    IF iv_only_local_objects = abap_true.
      ls_srcsystem-sign   = 'I'.
      ls_srcsystem-option = 'EQ'.
      ls_srcsystem-low    = sy-sysid.
      APPEND ls_srcsystem TO lt_srcsystem.
    ENDIF.

    SELECT * FROM tadir
      INTO CORRESPONDING FIELDS OF TABLE rt_tadir
      WHERE devclass = iv_package
      AND pgmid = 'R3TR'
      AND object NOT IN lt_excludes
      AND delflag = abap_false
      AND srcsystem IN lt_srcsystem
      ORDER BY PRIMARY KEY.               "#EC CI_GENBUFF "#EC CI_SUBRC

    CREATE OBJECT lo_skip_objects.
    rt_tadir = lo_skip_objects->skip_sadl_generated_objects(
      it_tadir = rt_tadir
      io_log   = io_log ).

    " Local packages are not in TADIR, only in TDEVC, act as if they were
    IF iv_package CP '$*'. " OR iv_package CP 'T*' ).
      APPEND INITIAL LINE TO rt_tadir ASSIGNING <ls_tadir>.
      <ls_tadir>-pgmid    = 'R3TR'.
      <ls_tadir>-object   = 'DEVC'.
      <ls_tadir>-obj_name = iv_package.
      <ls_tadir>-devclass = iv_package.
    ENDIF.

    IF NOT io_dot IS INITIAL.
      lv_path = zcl_abapgit_folder_logic=>package_to_path(
        iv_top     = iv_top
        io_dot     = io_dot
        iv_package = iv_package ).
    ENDIF.

    LOOP AT rt_tadir ASSIGNING <ls_tadir>.
      <ls_tadir>-path = lv_path.

      CASE <ls_tadir>-object.
        WHEN 'SICF'.
* replace the internal GUID with a hash of the path
          <ls_tadir>-obj_name+15 = zcl_abapgit_object_sicf=>read_sicf_url( <ls_tadir>-obj_name ).
      ENDCASE.
    ENDLOOP.

* look for subpackages
    IF iv_ignore_subpackages = abap_false.
      SELECT * FROM tdevc INTO TABLE lt_tdevc
        WHERE parentcl = iv_package
        ORDER BY PRIMARY KEY.             "#EC CI_SUBRC "#EC CI_GENBUFF
    ENDIF.

    LOOP AT lt_tdevc ASSIGNING <ls_tdevc>.
      lt_tadir = build( iv_package            = <ls_tdevc>-devclass
                        iv_only_local_objects = iv_only_local_objects
                        iv_top                = iv_top
                        io_dot                = io_dot
                        io_log                = io_log ).
      APPEND LINES OF lt_tadir TO rt_tadir.
    ENDLOOP.

  ENDMETHOD.                    "build

  METHOD check_exists.

    DATA: lv_exists   TYPE abap_bool,
          lo_progress TYPE REF TO zcl_abapgit_progress,
          ls_item     TYPE zif_abapgit_definitions=>ty_item.

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

    CREATE OBJECT lo_progress
      EXPORTING
        iv_total = lines( it_tadir ).

* rows from database table TADIR are not removed for
* transportable objects until the transport is released
    LOOP AT it_tadir ASSIGNING <ls_tadir>.
      IF sy-tabix MOD 200 = 0.
        lo_progress->show(
          iv_current = sy-tabix
          iv_text    = |Check object exists { <ls_tadir>-object } { <ls_tadir>-obj_name }| ).
      ENDIF.

      ls_item-obj_type = <ls_tadir>-object.
      ls_item-obj_name = <ls_tadir>-obj_name.
      ls_item-devclass = <ls_tadir>-devclass.

      IF exists( ls_item ) = abap_true.
        APPEND <ls_tadir> TO rt_tadir.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.                    "check_exists

  METHOD exists.

    IF is_item IS INITIAL.
      RETURN.
    ENDIF.

    IF zcl_abapgit_objects=>is_supported( is_item ) = abap_false.
      rv_exists = abap_true.
      RETURN.
    ENDIF.

    rv_exists = zcl_abapgit_objects=>exists( is_item ).

  ENDMETHOD.

  METHOD get_object_package.

    DATA: ls_tadir TYPE tadir,
          ls_item  TYPE zif_abapgit_definitions=>ty_item.

    ls_tadir = read_single( iv_pgmid    = iv_pgmid
                            iv_object   = iv_object
                            iv_obj_name = iv_obj_name ).

    IF ls_tadir-delflag = 'X'.
      RETURN. "Mark for deletion -> return nothing
    ENDIF.

    ls_item-obj_type = ls_tadir-object.
    ls_item-obj_name = ls_tadir-obj_name.
    ls_item-devclass = ls_tadir-devclass.
    IF exists( ls_item ) = abap_false.
      RETURN.
    ENDIF.

    rv_devclass = ls_tadir-devclass.

  ENDMETHOD.  "get_object_package.

  METHOD read.

* start recursion
* hmm, some problems here, should TADIR also build path?
    rt_tadir = build( iv_package            = iv_package
                      iv_top                = iv_package
                      io_dot                = io_dot
                      iv_ignore_subpackages = iv_ignore_subpackages
                      iv_only_local_objects = iv_only_local_objects
                      io_log                = io_log ).

    rt_tadir = check_exists( rt_tadir ).

  ENDMETHOD.                    "read

  METHOD read_single.

    IF iv_object = 'SICF'.
      rs_tadir = zcl_abapgit_object_sicf=>read_tadir_sicf(
        iv_pgmid    = iv_pgmid
        iv_obj_name = iv_obj_name ).
    ELSE.
      SELECT SINGLE * FROM tadir INTO rs_tadir
        WHERE pgmid = iv_pgmid
        AND object = iv_object
        AND obj_name = iv_obj_name.                       "#EC CI_SUBRC
    ENDIF.

  ENDMETHOD.                    "read_single
ENDCLASS.

fix dump

fix dump