*&---------------------------------------------------------------------*
*&  Include  zabapgit_object_dcls
*&---------------------------------------------------------------------*

CLASS lcl_object_dcls DEFINITION INHERITING FROM lcl_objects_super FINAL.

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

ENDCLASS.

CLASS lcl_object_dcls 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( ).

    rs_metadata-ddic         = abap_true.
    rs_metadata-delete_tadir = abap_true.
  ENDMETHOD.

  METHOD lif_object~exists.

    DATA: li_dcl TYPE REF TO object.

    TRY.
        CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
          RECEIVING
            ro_handler = li_dcl.

        CALL METHOD li_dcl->('CHECK_EXISTENCE')
          EXPORTING
            iv_objectname = ms_item-obj_name
          RECEIVING
            rv_exists     = rv_bool.

      CATCH cx_root.
        rv_bool = abap_false.
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~jump.

    DATA: adt_link          TYPE string,
          obj_name          TYPE e071-obj_name,
          li_object         TYPE REF TO cl_wb_object,
          li_adt            TYPE REF TO object,
          li_adt_uri_mapper TYPE REF TO object,
          li_adt_objref     TYPE REF TO object.

    FIELD-SYMBOLS: <uri> TYPE string.

    TRY.

        obj_name = ms_item-obj_name.

        li_object = cl_wb_object=>create_from_transport_key( p_object = ms_item-obj_type p_obj_name = obj_name ).

        CALL METHOD ('CL_ADT_TOOLS_CORE_FACTORY')=>('GET_INSTANCE')
          RECEIVING
            result = li_adt.

        CALL METHOD li_adt->('IF_ADT_TOOLS_CORE_FACTORY~GET_URI_MAPPER')
          RECEIVING
            result = li_adt_uri_mapper.

        CALL METHOD li_adt_uri_mapper->('IF_ADT_URI_MAPPER~MAP_WB_OBJECT_TO_OBJREF')
          EXPORTING
            wb_object = li_object
          RECEIVING
            result    = li_adt_objref.

        ASSIGN ('li_adt_objref->ref_data-uri') TO <uri>.

        CONCATENATE 'adt://' sy-sysid <uri> INTO adt_link.

        cl_gui_frontend_services=>execute( EXPORTING  document = adt_link
                                           EXCEPTIONS OTHERS   = 1 ).

      CATCH cx_root.
        lcx_exception=>raise( 'DCLS Jump Error' ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~delete.

    DATA: li_dcl TYPE REF TO object.

    TRY.
        CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
          RECEIVING
            ro_handler = li_dcl.

        CALL METHOD li_dcl->('DELETE')
          EXPORTING
            iv_dclname = ms_item-obj_name.

      CATCH cx_root.
        lcx_exception=>raise( 'DCLS error' ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~serialize.

    DATA: lr_data TYPE REF TO data,
          li_dcl  TYPE REF TO object.

    FIELD-SYMBOLS: <ls_data> TYPE any,
                   <field>   TYPE any.

    CREATE DATA lr_data TYPE ('ACM_S_DCLSRC').
    ASSIGN lr_data->* TO <ls_data>.

    TRY.
        CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
          RECEIVING
            ro_handler = li_dcl.

        CALL METHOD li_dcl->('READ')
          EXPORTING
            iv_dclname = ms_item-obj_name
          IMPORTING
            es_dclsrc  = <ls_data>.

        ASSIGN COMPONENT 'AS4USER' OF STRUCTURE <ls_data> TO <field>.
        ASSERT sy-subrc = 0.
        CLEAR <field>.

        ASSIGN COMPONENT 'AS4DATE' OF STRUCTURE <ls_data> TO <field>.
        ASSERT sy-subrc = 0.
        CLEAR <field>.

        ASSIGN COMPONENT 'AS4TIME' OF STRUCTURE <ls_data> TO <field>.
        ASSERT sy-subrc = 0.
        CLEAR <field>.

        ASSIGN COMPONENT 'CREATED_BY'	OF STRUCTURE <ls_data> TO <field>.
        ASSERT sy-subrc = 0.
        CLEAR <field>.

        ASSIGN COMPONENT 'CREATED_DATE' OF STRUCTURE <ls_data> TO <field>.
        ASSERT sy-subrc = 0.
        CLEAR <field>.

        ASSIGN COMPONENT 'SOURCE' OF STRUCTURE <ls_data> TO <field>.
        ASSERT sy-subrc = 0.

        mo_files->add_string( iv_ext = 'asdcls'  iv_string = <field> ).

        CLEAR <field>.

        io_xml->add( iv_name = 'DCLS'
                     ig_data = <ls_data> ).

      CATCH cx_root.
        lcx_exception=>raise( 'DCLS error' ).
    ENDTRY.

  ENDMETHOD.

  METHOD lif_object~deserialize.

    DATA: lr_data TYPE REF TO data,
          li_dcl  TYPE REF TO object.

    FIELD-SYMBOLS: <ls_data> TYPE any,
                   <field>   TYPE any.

    CREATE DATA lr_data TYPE ('ACM_S_DCLSRC').
    ASSIGN lr_data->* TO <ls_data>.

    io_xml->read(
      EXPORTING
        iv_name = 'DCLS'
      CHANGING
        cg_data = <ls_data> ).

    ASSIGN COMPONENT 'SOURCE' OF STRUCTURE <ls_data> TO <field>.
    ASSERT sy-subrc = 0.
    <field> = mo_files->read_string( 'asdcls' ).

    TRY.
        CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
          RECEIVING
            ro_handler = li_dcl.

        CALL METHOD li_dcl->('SAVE')
          EXPORTING
            iv_dclname     = ms_item-obj_name
            iv_put_state   = 'A'
            is_dclsrc      = <ls_data>
            iv_devclass    = iv_package
            iv_access_mode = 'INSERT'.

        tadir_insert( iv_package ).

      CATCH cx_root.
        lcx_exception=>raise( 'DCLS error' ).
    ENDTRY.

    lcl_objects_activation=>add_item( ms_item ).

  ENDMETHOD.

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

ENDCLASS.

Update zabapgit_object_dcls.prog.abap

Update zabapgit_object_dcls.prog.abap

fixed linter errors 3


REPORT zwabap_installer.

PARAMETERS: p_zip  TYPE text_512 OBLIGATORY,
            p_devc TYPE devclass DEFAULT '$WABAP_FRONTEND' OBLIGATORY.

CLASS lcl_app DEFINITION FINAL.

  PUBLIC SECTION.
    CLASS-METHODS:
      run,
      initialization,
      select_file.

  PRIVATE SECTION.
    TYPES: BEGIN OF ty_file,
             path     TYPE string,
             filename TYPE string,
             data     TYPE xstring,
           END OF ty_file.
    TYPES: ty_files_tt TYPE STANDARD TABLE OF ty_file WITH DEFAULT KEY.

    CLASS-METHODS:
      read_file
        RETURNING VALUE(rv_xstr) TYPE xstring,
      unzip
        IMPORTING iv_xstr         TYPE xstring
        RETURNING VALUE(rt_files) TYPE ty_files_tt,
      create_folder,
      create_mimes
        IMPORTING it_files TYPE ty_files_tt,
      filename
        IMPORTING iv_str             TYPE string
        RETURNING VALUE(rv_filename) TYPE string.

ENDCLASS.

CLASS lcl_app IMPLEMENTATION.

  METHOD filename.

    DATA: lv_path TYPE string.                              "#EC NEEDED

    IF iv_str CA '/'.
      FIND REGEX '(.*/)(.*)' IN iv_str
        SUBMATCHES lv_path rv_filename.
      ASSERT sy-subrc = 0.
    ELSE.
      rv_filename = iv_str.
    ENDIF.
    TRANSLATE rv_filename TO LOWER CASE.

  ENDMETHOD.

  METHOD unzip.

    DATA: lo_zip    TYPE REF TO cl_abap_zip,
          lv_xstr   TYPE xstring,
          lt_splice TYPE cl_abap_zip=>t_splice_entries.

    FIELD-SYMBOLS: <ls_splice> LIKE LINE OF lt_splice,
                   <ls_file>   LIKE LINE OF rt_files.

    CREATE OBJECT lo_zip.
    lo_zip->load( EXPORTING
                    zip             = iv_xstr
                  EXCEPTIONS
                    zip_parse_error = 1
                    OTHERS          = 2 ).
    ASSERT sy-subrc = 0.

    lt_splice = cl_abap_zip=>splice( iv_xstr ).

    LOOP AT lt_splice ASSIGNING <ls_splice>.
      lo_zip->get(
        EXPORTING
          name                    = <ls_splice>-name
        IMPORTING
          content                 = lv_xstr
        EXCEPTIONS
          zip_index_error         = 1
          zip_decompression_error = 2
          OTHERS                  = 3 ).
      ASSERT sy-subrc = 0.

      APPEND INITIAL LINE TO rt_files ASSIGNING <ls_file>.
      <ls_file>-path     = '/'.
      <ls_file>-filename = filename( <ls_splice>-name ).
      <ls_file>-data     = lv_xstr.

    ENDLOOP.

  ENDMETHOD.

  METHOD initialization.

    CALL FUNCTION 'RS_SUPPORT_SELECTIONS'
      EXPORTING
        report               = sy-cprog
        variant              = 'DEFAULT'
      EXCEPTIONS
        variant_not_existent = 01
        variant_obsolete     = 02
        ##fm_subrc_ok. "#EC CI_SUBRC

  ENDMETHOD.

  METHOD read_file.

    TYPES: ty_hex200 TYPE x LENGTH 200.

    DATA: lv_length   TYPE i,
          lv_filename TYPE string,
          lt_data     TYPE STANDARD TABLE OF ty_hex200.

    lv_filename = p_zip.

    cl_gui_frontend_services=>gui_upload(
      EXPORTING
        filename                = lv_filename
        filetype                = 'BIN'
      IMPORTING
        filelength              = lv_length
      CHANGING
        data_tab                = lt_data
      EXCEPTIONS
        file_open_error         = 1
        file_read_error         = 2
        no_batch                = 3
        gui_refuse_filetransfer = 4
        invalid_type            = 5
        no_authority            = 6
        unknown_error           = 7
        bad_data_format         = 8
        header_not_allowed      = 9
        separator_not_allowed   = 10
        header_too_long         = 11
        unknown_dp_error        = 12
        access_denied           = 13
        dp_out_of_memory        = 14
        disk_full               = 15
        dp_timeout              = 16
        not_supported_by_gui    = 17
        error_no_gui            = 18
        OTHERS                  = 19 ).
    ASSERT sy-subrc = 0.

    CONCATENATE LINES OF lt_data INTO rv_xstr IN BYTE MODE.

    rv_xstr = rv_xstr(lv_length).

  ENDMETHOD.

  METHOD run.

    create_mimes( unzip( read_file( ) ) ).

    WRITE: / 'Done'(001).

  ENDMETHOD.

  METHOD create_folder.

    DATA: li_api TYPE REF TO if_mr_api.

    li_api = cl_mime_repository_api=>if_mr_api~get_api( ).

    li_api->create_folder(
      EXPORTING
        i_url              = zcl_wabap_service=>cv_url
        i_description      = 'wabap'
        i_dev_package      = p_devc
      EXCEPTIONS
        parameter_missing  = 1
        error_occured      = 2
        cancelled          = 3
        permission_failure = 4
        folder_exists      = 5
        OTHERS             = 6 ) ##NO_TEXT.
    ASSERT sy-subrc = 0 OR sy-subrc = 5.

  ENDMETHOD.

  METHOD create_mimes.

    DATA: lv_url TYPE string,
          li_api TYPE REF TO if_mr_api.

    FIELD-SYMBOLS: <ls_file> LIKE LINE OF it_files.

    create_folder( ).

    li_api = cl_mime_repository_api=>if_mr_api~get_api( ).

    LOOP AT it_files ASSIGNING <ls_file>.
      lv_url = zcl_wabap_service=>cv_url && '/' && <ls_file>-filename.

      WRITE: / lv_url.

      li_api->put(
        EXPORTING
          i_url                   = lv_url
          i_content               = <ls_file>-data
          i_dev_package           = p_devc
        EXCEPTIONS
          parameter_missing       = 1
          error_occured           = 2
          cancelled               = 3
          permission_failure      = 4
          data_inconsistency      = 5
          new_loio_already_exists = 6
          is_folder               = 7
          OTHERS                  = 8 ).
      ASSERT sy-subrc = 0.

    ENDLOOP.

  ENDMETHOD.

  METHOD select_file.

    DATA: lt_filetable TYPE filetable,
          lv_rc        TYPE i.

    cl_gui_frontend_services=>file_open_dialog(
      EXPORTING
        default_filename        = '*.zip'
      CHANGING
        file_table              = lt_filetable
        rc                      = lv_rc
      EXCEPTIONS
        file_open_dialog_failed = 1
        cntl_error              = 2
        error_no_gui            = 3
        not_supported_by_gui    = 4
        OTHERS                  = 5 ).
    ASSERT sy-subrc = 0.

    IF lv_rc = 1.
      p_zip = lt_filetable[ 1 ]-filename.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_zip.
  lcl_app=>select_file( ).

INITIALIZATION.
  lcl_app=>initialization( ).

START-OF-SELECTION.
  lcl_app=>run( ).

REPORT zwabap_installer.

PARAMETERS: p_zip  TYPE text_512 OBLIGATORY,
            p_devc TYPE devclass DEFAULT '$WABAP_FRONTEND' OBLIGATORY.

CLASS lcl_app DEFINITION FINAL.

  PUBLIC SECTION.
    CLASS-METHODS:
      run,
      initialization,
      select_file.

  PRIVATE SECTION.
    TYPES: BEGIN OF ty_file,
             path     TYPE string,
             filename TYPE string,
             data     TYPE xstring,
           END OF ty_file.
    TYPES: ty_files_tt TYPE STANDARD TABLE OF ty_file WITH DEFAULT KEY.

    CLASS-METHODS:
      read_file
        RETURNING VALUE(rv_xstr) TYPE xstring,
      unzip
        IMPORTING iv_xstr         TYPE xstring
        RETURNING VALUE(rt_files) TYPE ty_files_tt,
      create_folder,
      create_mimes
        IMPORTING it_files TYPE ty_files_tt,
      filename
        IMPORTING iv_str             TYPE string
        RETURNING VALUE(rv_filename) TYPE string.

ENDCLASS.

CLASS lcl_app IMPLEMENTATION.

  METHOD filename.

    DATA: lv_path TYPE string.                              "#EC NEEDED

    IF iv_str CA '/'.
      FIND REGEX '(.*/)(.*)' IN iv_str
        SUBMATCHES lv_path rv_filename.
      ASSERT sy-subrc = 0.
    ELSE.
      rv_filename = iv_str.
    ENDIF.
    TRANSLATE rv_filename TO LOWER CASE.

  ENDMETHOD.

  METHOD unzip.

    DATA: lo_zip    TYPE REF TO cl_abap_zip,
          lv_xstr   TYPE xstring,
          lt_splice TYPE cl_abap_zip=>t_splice_entries.

    FIELD-SYMBOLS: <ls_splice> LIKE LINE OF lt_splice,
                   <ls_file>   LIKE LINE OF rt_files.

    CREATE OBJECT lo_zip.
    lo_zip->load( EXPORTING
                    zip             = iv_xstr
                  EXCEPTIONS
                    zip_parse_error = 1
                    OTHERS          = 2 ).
    ASSERT sy-subrc = 0.

    lt_splice = cl_abap_zip=>splice( iv_xstr ).

    LOOP AT lt_splice ASSIGNING <ls_splice>.
      lo_zip->get(
        EXPORTING
          name                    = <ls_splice>-name
        IMPORTING
          content                 = lv_xstr
        EXCEPTIONS
          zip_index_error         = 1
          zip_decompression_error = 2
          OTHERS                  = 3 ).
      ASSERT sy-subrc = 0.

      APPEND INITIAL LINE TO rt_files ASSIGNING <ls_file>.
      <ls_file>-path     = '/'.
      <ls_file>-filename = filename( <ls_splice>-name ).
      <ls_file>-data     = lv_xstr.

    ENDLOOP.

  ENDMETHOD.

  METHOD initialization.

    CALL FUNCTION 'RS_SUPPORT_SELECTIONS'
      EXPORTING
        report               = sy-cprog
        variant              = 'DEFAULT'
      EXCEPTIONS
        variant_not_existent = 01
        variant_obsolete     = 02
        ##fm_subrc_ok. "#EC CI_SUBRC

  ENDMETHOD.

  METHOD read_file.

    TYPES: ty_hex200 TYPE x LENGTH 200.

    DATA: lv_length   TYPE i,
          lv_filename TYPE string,
          lt_data     TYPE STANDARD TABLE OF ty_hex200.

    lv_filename = p_zip.

    cl_gui_frontend_services=>gui_upload(
      EXPORTING
        filename                = lv_filename
        filetype                = 'BIN'
      IMPORTING
        filelength              = lv_length
      CHANGING
        data_tab                = lt_data
      EXCEPTIONS
        file_open_error         = 1
        file_read_error         = 2
        no_batch                = 3
        gui_refuse_filetransfer = 4
        invalid_type            = 5
        no_authority            = 6
        unknown_error           = 7
        bad_data_format         = 8
        header_not_allowed      = 9
        separator_not_allowed   = 10
        header_too_long         = 11
        unknown_dp_error        = 12
        access_denied           = 13
        dp_out_of_memory        = 14
        disk_full               = 15
        dp_timeout              = 16
        not_supported_by_gui    = 17
        error_no_gui            = 18
        OTHERS                  = 19 ).
    ASSERT sy-subrc = 0.

    CONCATENATE LINES OF lt_data INTO rv_xstr IN BYTE MODE.

    rv_xstr = rv_xstr(lv_length).

  ENDMETHOD.

  METHOD run.

    create_mimes( unzip( read_file( ) ) ).

    WRITE: / 'Done'(001).

  ENDMETHOD.

  METHOD create_folder.

    DATA: li_api TYPE REF TO if_mr_api.

    li_api = cl_mime_repository_api=>if_mr_api~get_api( ).

    li_api->create_folder(
      EXPORTING
        i_url              = zcl_wabap_service=>c_url
        i_description      = 'wabap'
        i_dev_package      = p_devc
      EXCEPTIONS
        parameter_missing  = 1
        error_occured      = 2
        cancelled          = 3
        permission_failure = 4
        folder_exists      = 5
        OTHERS             = 6 ) ##NO_TEXT.
    ASSERT sy-subrc = 0 OR sy-subrc = 5.

  ENDMETHOD.

  METHOD create_mimes.

    DATA: lv_url TYPE string,
          li_api TYPE REF TO if_mr_api.

    FIELD-SYMBOLS: <ls_file> LIKE LINE OF it_files.

    create_folder( ).

    li_api = cl_mime_repository_api=>if_mr_api~get_api( ).

    LOOP AT it_files ASSIGNING <ls_file>.
      lv_url = zcl_wabap_service=>c_url && '/' && <ls_file>-filename.

      WRITE: / lv_url.

      li_api->put(
        EXPORTING
          i_url                   = lv_url
          i_content               = <ls_file>-data
          i_dev_package           = p_devc
        EXCEPTIONS
          parameter_missing       = 1
          error_occured           = 2
          cancelled               = 3
          permission_failure      = 4
          data_inconsistency      = 5
          new_loio_already_exists = 6
          is_folder               = 7
          OTHERS                  = 8 ).
      ASSERT sy-subrc = 0.

    ENDLOOP.

  ENDMETHOD.

  METHOD select_file.

    DATA: lt_filetable TYPE filetable,
          lv_rc        TYPE i.

    cl_gui_frontend_services=>file_open_dialog(
      EXPORTING
        default_filename        = '*.zip'
      CHANGING
        file_table              = lt_filetable
        rc                      = lv_rc
      EXCEPTIONS
        file_open_dialog_failed = 1
        cntl_error              = 2
        error_no_gui            = 3
        not_supported_by_gui    = 4
        OTHERS                  = 5 ).
    ASSERT sy-subrc = 0.

    IF lv_rc = 1.
      p_zip = lt_filetable[ 1 ]-filename.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_zip.
  lcl_app=>select_file( ).

INITIALIZATION.
  lcl_app=>initialization( ).

START-OF-SELECTION.
  lcl_app=>run( ).

fix syntax error

fix syntax error


CLASS zcl_abapgit_object_iaxu DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES zif_abapgit_object.

  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA: mc_source_style_2006 TYPE w3style VALUE 'XML',
          mc_generator_class   TYPE w3styleclass VALUE 'CL_ITS_GENERATE_XML3'.

    METHODS:
      read
        EXPORTING es_attr TYPE w3tempattr
        RAISING   zcx_abapgit_exception,
      save
        IMPORTING is_attr TYPE w3tempattr
        RAISING   zcx_abapgit_exception,
      w3_api_load
        IMPORTING is_name    TYPE iacikeyt
        EXPORTING eo_xml_api TYPE REF TO cl_w3_api_xml3
                  es_attr    TYPE w3tempattr
        RAISING   zcx_abapgit_exception,
      w3_api_set_changeable
        IMPORTING io_xml_api    TYPE REF TO cl_w3_api_xml3
                  iv_changeable TYPE abap_bool
        RAISING   zcx_abapgit_exception,
      w3_api_delete
        IMPORTING io_xml_api TYPE REF TO cl_w3_api_xml3
        RAISING   zcx_abapgit_exception,
      w3_api_save
        IMPORTING io_xml_api TYPE REF TO cl_w3_api_xml3
        RAISING   zcx_abapgit_exception,
      w3_api_create_new
        IMPORTING is_attr    TYPE w3tempattr
        EXPORTING eo_xml_api TYPE REF TO cl_w3_api_xml3
        RAISING   zcx_abapgit_exception.

ENDCLASS.

CLASS zcl_abapgit_object_iaxu IMPLEMENTATION.

  METHOD read.

    DATA: ls_name TYPE iacikeyt.

    ls_name = ms_item-obj_name.

    w3_api_load( EXPORTING is_name = ls_name
                 IMPORTING es_attr = es_attr ).

    CLEAR: es_attr-chname,
           es_attr-tdate,
           es_attr-ttime,
           es_attr-devclass.

  ENDMETHOD.

  METHOD save.

    DATA: lo_xml_api TYPE REF TO cl_w3_api_xml3.

    w3_api_create_new( EXPORTING is_attr    = is_attr
                       IMPORTING eo_xml_api = lo_xml_api ).

    w3_api_save( io_xml_api = lo_xml_api ).

    w3_api_set_changeable( io_xml_api    = lo_xml_api
                           iv_changeable = abap_false ).

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.
    rv_user = c_user_unknown. " todo
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lo_xml_api TYPE REF TO cl_w3_api_xml3,
          ls_name    TYPE iacikeyt.

    ls_name = ms_item-obj_name.

    w3_api_load( EXPORTING is_name    = ls_name
                 IMPORTING eo_xml_api = lo_xml_api ).

    w3_api_set_changeable( io_xml_api    = lo_xml_api
                           iv_changeable = abap_true ).

    w3_api_delete( io_xml_api = lo_xml_api ).

    w3_api_save( io_xml_api = lo_xml_api ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: ls_attr TYPE w3tempattr.

    io_xml->read( EXPORTING iv_name = 'ATTR'
                  CHANGING  cg_data = ls_attr ).

    ls_attr-devclass = iv_package.

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

    save( is_attr = ls_attr ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: ls_name  TYPE iacikeyt.

    ls_name = ms_item-obj_name.

    cl_w3_api_xml3=>s_check_exist( EXPORTING p_xml_name = ls_name
                                   IMPORTING p_exists   = rv_bool ).

  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    RETURN.
  ENDMETHOD.

  METHOD zif_abapgit_object~get_deserialize_steps.
    APPEND zif_abapgit_object=>gc_step_id-abap TO rt_steps.
  ENDMETHOD.

  METHOD zif_abapgit_object~get_metadata.
    rs_metadata = get_metadata( ).
  ENDMETHOD.

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

  METHOD zif_abapgit_object~is_locked.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

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

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: ls_attr TYPE w3tempattr.

    IF zif_abapgit_object~exists( ) = abap_false.
      RETURN.
    ENDIF.

    read( IMPORTING es_attr = ls_attr ).

    io_xml->add( iv_name = 'ATTR'
                 ig_data = ls_attr ).

  ENDMETHOD.

  METHOD w3_api_load.

    cl_w3_api_xml3=>load(
      EXPORTING
        p_xml_name          = is_name
      IMPORTING
        p_attributes        = es_attr
        p_xml               = eo_xml_api
      EXCEPTIONS
        object_not_existing = 1
        permission_failure  = 2
        data_corrupt        = 3
        error_occured       = 4
        OTHERS              = 5 ).

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

  ENDMETHOD.

  METHOD w3_api_set_changeable.

    io_xml_api->if_w3_api_object~set_changeable(
      EXPORTING
        p_changeable                 = iv_changeable
      EXCEPTIONS
        action_cancelled             = 1
        object_locked_by_other_user  = 2
        permission_failure           = 3
        object_already_changeable    = 4
        object_already_unlocked      = 5
        object_just_created          = 6
        object_deleted               = 7
        object_modified              = 8
        object_not_existing          = 9
        object_invalid               = 10
        error_occured                = 11
        content_data_error           = 12
        OTHERS                       = 13 ).

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

  ENDMETHOD.

  METHOD w3_api_create_new.

    cl_w3_api_xml3=>create_new(
      EXPORTING
        p_source_style_2006       = mc_source_style_2006
        p_xml_data                = is_attr
        p_generator_class         = mc_generator_class
        p_program_name            = is_attr-programm
      IMPORTING
        p_xml                     = eo_xml_api
      EXCEPTIONS
        undefined_name            = 1
        error_occured             = 2
        object_already_existing   = 3
        not_authorized            = 4
        action_cancelled          = 5
        OTHERS                    = 6 ).

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

  ENDMETHOD.

  METHOD w3_api_delete.

    io_xml_api->if_w3_api_object~delete(
      EXCEPTIONS
        object_not_empty      = 1
        object_not_changeable = 2
        object_invalid        = 3
        error_occured         = 4
        OTHERS                = 5 ).

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

  ENDMETHOD.

  METHOD w3_api_save.

    io_xml_api->if_w3_api_object~save(
      EXCEPTIONS
        object_invalid        = 1
        object_not_changeable = 2
        action_cancelled      = 3
        permission_failure    = 4
        not_changed           = 5
        data_invalid          = 6
        error_occured         = 7
        OTHERS                = 8 ).

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

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_object_iaxu DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES zif_abapgit_object.

  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA: mc_source_style_2006 TYPE w3style VALUE 'XML',
          mc_generator_class   TYPE w3styleclass VALUE 'CL_ITS_GENERATE_XML3'.

    METHODS:
      read
        EXPORTING es_attr TYPE w3tempattr
        RAISING   zcx_abapgit_exception,
      save
        IMPORTING is_attr TYPE w3tempattr
        RAISING   zcx_abapgit_exception,
      w3_api_load
        IMPORTING is_name    TYPE iacikeyt
        EXPORTING eo_xml_api TYPE REF TO cl_w3_api_xml3
                  es_attr    TYPE w3tempattr
        RAISING   zcx_abapgit_exception,
      w3_api_set_changeable
        IMPORTING io_xml_api    TYPE REF TO cl_w3_api_xml3
                  iv_changeable TYPE abap_bool
        RAISING   zcx_abapgit_exception,
      w3_api_delete
        IMPORTING io_xml_api TYPE REF TO cl_w3_api_xml3
        RAISING   zcx_abapgit_exception,
      w3_api_save
        IMPORTING io_xml_api TYPE REF TO cl_w3_api_xml3
        RAISING   zcx_abapgit_exception,
      w3_api_create_new
        IMPORTING is_attr    TYPE w3tempattr
        EXPORTING eo_xml_api TYPE REF TO cl_w3_api_xml3
        RAISING   zcx_abapgit_exception.

ENDCLASS.

CLASS zcl_abapgit_object_iaxu IMPLEMENTATION.

  METHOD read.

    DATA: ls_name TYPE iacikeyt.

    ls_name = ms_item-obj_name.

    w3_api_load( EXPORTING is_name = ls_name
                 IMPORTING es_attr = es_attr ).

    CLEAR: es_attr-chname,
           es_attr-tdate,
           es_attr-ttime,
           es_attr-devclass.

  ENDMETHOD.

  METHOD save.

    DATA: lo_xml_api TYPE REF TO cl_w3_api_xml3.

    w3_api_create_new( EXPORTING is_attr    = is_attr
                       IMPORTING eo_xml_api = lo_xml_api ).

    w3_api_save( io_xml_api = lo_xml_api ).

    w3_api_set_changeable( io_xml_api    = lo_xml_api
                           iv_changeable = abap_false ).

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.
    rv_user = c_user_unknown. " todo
  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lo_xml_api TYPE REF TO cl_w3_api_xml3,
          ls_name    TYPE iacikeyt.

    ls_name = ms_item-obj_name.

    w3_api_load( EXPORTING is_name    = ls_name
                 IMPORTING eo_xml_api = lo_xml_api ).

    w3_api_set_changeable( io_xml_api    = lo_xml_api
                           iv_changeable = abap_true ).

    w3_api_delete( io_xml_api = lo_xml_api ).

    w3_api_save( io_xml_api = lo_xml_api ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: ls_attr TYPE w3tempattr.

    io_xml->read( EXPORTING iv_name = 'ATTR'
                  CHANGING  cg_data = ls_attr ).

    ls_attr-devclass = iv_package.

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

    save( is_attr = ls_attr ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA: ls_name  TYPE iacikeyt.

    ls_name = ms_item-obj_name.

    cl_w3_api_xml3=>s_check_exist( EXPORTING p_xml_name = ls_name
                                   IMPORTING p_exists   = rv_bool ).

  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    RETURN.
  ENDMETHOD.

  METHOD zif_abapgit_object~get_deserialize_steps.
    APPEND zif_abapgit_object=>gc_step_id-abap TO rt_steps.
  ENDMETHOD.

  METHOD zif_abapgit_object~get_metadata.
    rs_metadata = get_metadata( ).
  ENDMETHOD.

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

  METHOD zif_abapgit_object~is_locked.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

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

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: ls_attr TYPE w3tempattr.

    IF zif_abapgit_object~exists( ) = abap_false.
      RETURN.
    ENDIF.

    read( IMPORTING es_attr = ls_attr ).

    io_xml->add( iv_name = 'ATTR'
                 ig_data = ls_attr ).

  ENDMETHOD.

  METHOD w3_api_load.

    cl_w3_api_xml3=>load(
      EXPORTING
        p_xml_name          = is_name
      IMPORTING
        p_attributes        = es_attr
        p_xml               = eo_xml_api
      EXCEPTIONS
        object_not_existing = 1
        permission_failure  = 2
        data_corrupt        = 3
        error_occured       = 4
        OTHERS              = 5 ).

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

  ENDMETHOD.

  METHOD w3_api_set_changeable.

    io_xml_api->if_w3_api_object~set_changeable(
      EXPORTING
        p_changeable                 = iv_changeable
      EXCEPTIONS
        action_cancelled             = 1
        object_locked_by_other_user  = 2
        permission_failure           = 3
        object_already_changeable    = 4
        object_already_unlocked      = 5
        object_just_created          = 6
        object_deleted               = 7
        object_modified              = 8
        object_not_existing          = 9
        object_invalid               = 10
        error_occured                = 11
        OTHERS                       = 12 ).

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

  ENDMETHOD.

  METHOD w3_api_create_new.

    cl_w3_api_xml3=>create_new(
      EXPORTING
        p_source_style_2006       = mc_source_style_2006
        p_xml_data                = is_attr
        p_generator_class         = mc_generator_class
        p_program_name            = is_attr-programm
      IMPORTING
        p_xml                     = eo_xml_api
      EXCEPTIONS
        undefined_name            = 1
        error_occured             = 2
        object_already_existing   = 3
        not_authorized            = 4
        action_cancelled          = 5
        OTHERS                    = 6 ).

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

  ENDMETHOD.

  METHOD w3_api_delete.

    io_xml_api->if_w3_api_object~delete(
      EXCEPTIONS
        object_not_empty      = 1
        object_not_changeable = 2
        object_invalid        = 3
        error_occured         = 4
        OTHERS                = 5 ).

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

  ENDMETHOD.

  METHOD w3_api_save.

    io_xml_api->if_w3_api_object~save(
      EXCEPTIONS
        object_invalid        = 1
        object_not_changeable = 2
        action_cancelled      = 3
        permission_failure    = 4
        not_changed           = 5
        data_invalid          = 6
        error_occured         = 7
        OTHERS                = 8 ).

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

  ENDMETHOD.
ENDCLASS.

Fix applied (#3037)

Fix applied (#3037)


CLASS ltcl_determine_max_threads DEFINITION DEFERRED.
CLASS zcl_abapgit_serialize DEFINITION LOCAL FRIENDS ltcl_determine_max_threads.

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

  PRIVATE SECTION.
    DATA:
      mo_cut TYPE REF TO zcl_abapgit_serialize.

    METHODS:
      setup,
      determine_max_threads FOR TESTING RAISING zcx_abapgit_exception,
      force FOR TESTING RAISING zcx_abapgit_exception.

ENDCLASS.

CLASS ltcl_determine_max_threads IMPLEMENTATION.

  METHOD setup.
    CREATE OBJECT mo_cut.
  ENDMETHOD.

  METHOD determine_max_threads.

    DATA: lv_threads TYPE i.

    lv_threads = mo_cut->determine_max_threads( ).

    cl_abap_unit_assert=>assert_differs(
      act = lv_threads
      exp = 0 ).

  ENDMETHOD.

  METHOD force.

    DATA: lv_threads TYPE i.

    lv_threads = mo_cut->determine_max_threads( abap_true ).

    cl_abap_unit_assert=>assert_equals(
      act = lv_threads
      exp = 1 ).

  ENDMETHOD.

ENDCLASS.

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

  PRIVATE SECTION.
    DATA:
      mo_cut TYPE REF TO zcl_abapgit_serialize.

    METHODS:
      setup,
      test FOR TESTING RAISING zcx_abapgit_exception,
      unsupported FOR TESTING RAISING zcx_abapgit_exception.

ENDCLASS.

CLASS ltcl_serialize IMPLEMENTATION.

  METHOD setup.
    CREATE OBJECT mo_cut.
  ENDMETHOD.

  METHOD test.

    DATA: lt_tadir      TYPE zif_abapgit_definitions=>ty_tadir_tt,
          lt_sequential TYPE zif_abapgit_definitions=>ty_files_item_tt,
          lt_parallel   TYPE zif_abapgit_definitions=>ty_files_item_tt.

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

    APPEND INITIAL LINE TO lt_tadir ASSIGNING <ls_tadir>.
    <ls_tadir>-object   = 'PROG'.
    <ls_tadir>-obj_name = 'RSABAPPROGRAM'.
    <ls_tadir>-devclass = 'PACKAGE'.
    <ls_tadir>-path     = 'foobar'.

    lt_sequential = mo_cut->serialize(
      it_tadir            = lt_tadir
      iv_force_sequential = abap_true ).

    lt_parallel = mo_cut->serialize(
      it_tadir            = lt_tadir
      iv_force_sequential = abap_false ).

    cl_abap_unit_assert=>assert_equals(
      act = lt_sequential
      exp = lt_parallel ).

  ENDMETHOD.

  METHOD unsupported.

    DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
          li_log1  TYPE REF TO zif_abapgit_log,
          li_log2  TYPE REF TO zif_abapgit_log.

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

    APPEND INITIAL LINE TO lt_tadir ASSIGNING <ls_tadir>.
    <ls_tadir>-object   = 'ABCD'.
    <ls_tadir>-obj_name = 'OBJECT'.

    CREATE OBJECT li_log1 TYPE zcl_abapgit_log.
    mo_cut->serialize(
      it_tadir            = lt_tadir
      ii_log              = li_log1
      iv_force_sequential = abap_true ).

    CREATE OBJECT li_log2 TYPE zcl_abapgit_log.
    mo_cut->serialize(
      it_tadir            = lt_tadir
      ii_log              = li_log2
      iv_force_sequential = abap_false ).

    cl_abap_unit_assert=>assert_char_cp(
      act = zcl_abapgit_log_viewer=>to_html( li_log1 )->render( )
      exp = '*Object type ignored, not supported*' ).

    cl_abap_unit_assert=>assert_char_cp(
      act = zcl_abapgit_log_viewer=>to_html( li_log2 )->render( )
      exp = '*Object type ignored, not supported*' ).

  ENDMETHOD.

ENDCLASS.

CLASS ltcl_determine_max_threads DEFINITION DEFERRED.
CLASS zcl_abapgit_serialize DEFINITION LOCAL FRIENDS ltcl_determine_max_threads.

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

  PRIVATE SECTION.
    DATA:
      mo_cut TYPE REF TO zcl_abapgit_serialize.

    METHODS:
      setup,
      determine_max_threads FOR TESTING RAISING zcx_abapgit_exception,
      force FOR TESTING RAISING zcx_abapgit_exception.

ENDCLASS.

CLASS ltcl_determine_max_threads IMPLEMENTATION.

  METHOD setup.
    CREATE OBJECT mo_cut.
  ENDMETHOD.

  METHOD determine_max_threads.

    DATA: lv_threads TYPE i.

    lv_threads = mo_cut->determine_max_threads( ).

    cl_abap_unit_assert=>assert_differs(
      act = lv_threads
      exp = 0 ).

  ENDMETHOD.

  METHOD force.

    DATA: lv_threads TYPE i.

    lv_threads = mo_cut->determine_max_threads( abap_true ).

    cl_abap_unit_assert=>assert_equals(
      act = lv_threads
      exp = 1 ).

  ENDMETHOD.

ENDCLASS.

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

  PRIVATE SECTION.
    DATA:
      mo_cut TYPE REF TO zcl_abapgit_serialize.

    METHODS:
      setup,
      test FOR TESTING RAISING zcx_abapgit_exception,
      unsupported FOR TESTING RAISING zcx_abapgit_exception.

ENDCLASS.

CLASS ltcl_serialize IMPLEMENTATION.

  METHOD setup.
    CREATE OBJECT mo_cut.
  ENDMETHOD.

  METHOD test.

    DATA: lt_tadir      TYPE zif_abapgit_definitions=>ty_tadir_tt,
          lt_sequential TYPE zif_abapgit_definitions=>ty_files_item_tt,
          lt_parallel   TYPE zif_abapgit_definitions=>ty_files_item_tt.

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

    APPEND INITIAL LINE TO lt_tadir ASSIGNING <ls_tadir>.
    <ls_tadir>-object   = 'PROG'.
    <ls_tadir>-obj_name = 'RSABAPPROGRAM'.
    <ls_tadir>-devclass = 'PACKAGE'.
    <ls_tadir>-path     = 'foobar'.

    lt_sequential = mo_cut->serialize(
      it_tadir            = lt_tadir
      iv_force_sequential = abap_true ).

    lt_parallel = mo_cut->serialize(
      it_tadir            = lt_tadir
      iv_force_sequential = abap_false ).

    cl_abap_unit_assert=>assert_equals(
      act = lt_sequential
      exp = lt_parallel ).

  ENDMETHOD.

  METHOD unsupported.

    DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
          li_log1  TYPE REF TO zif_abapgit_log,
          li_log2  TYPE REF TO zif_abapgit_log.

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

    APPEND INITIAL LINE TO lt_tadir ASSIGNING <ls_tadir>.
    <ls_tadir>-object   = 'ABCD'.
    <ls_tadir>-obj_name = 'OBJECT'.

    CREATE OBJECT li_log1 TYPE zcl_abapgit_log.
    mo_cut->serialize(
      it_tadir            = lt_tadir
      ii_log              = li_log1
      iv_force_sequential = abap_true ).

    CREATE OBJECT li_log2 TYPE zcl_abapgit_log.
    mo_cut->serialize(
      it_tadir            = lt_tadir
      ii_log              = li_log2
      iv_force_sequential = abap_false ).

    cl_abap_unit_assert=>assert_char_cp(
      act = zcl_abapgit_log_viewer=>to_html( li_log1 )->render( )
      exp = '*Object type ABCD not supported*' ).

    cl_abap_unit_assert=>assert_char_cp(
      act = zcl_abapgit_log_viewer=>to_html( li_log2 )->render( )
      exp = '*Object type ABCD not supported*' ).

  ENDMETHOD.

ENDCLASS.

Update unit test to match changed message (#4631)


CLASS zcl_abapgit_gui_page_bkg DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_gui_page
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    METHODS constructor
      IMPORTING
        !iv_key TYPE zif_abapgit_persistence=>ty_repo-key .

    METHODS zif_abapgit_gui_page~on_event
        REDEFINITION .
  PROTECTED SECTION.

    METHODS read_persist
      IMPORTING
        !io_repo          TYPE REF TO zcl_abapgit_repo_online
      RETURNING
        VALUE(rs_persist) TYPE zcl_abapgit_persist_background=>ty_background
      RAISING
        zcx_abapgit_exception .
    METHODS render_methods
      IMPORTING
        !is_per        TYPE zcl_abapgit_persist_background=>ty_background
      RETURNING
        VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
    METHODS render_settings
      IMPORTING
        !is_per        TYPE zcl_abapgit_persist_background=>ty_background
      RETURNING
        VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
    METHODS build_menu
      RETURNING
        VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar .
    CLASS-METHODS update
      IMPORTING
        !is_bg_task TYPE zcl_abapgit_persist_background=>ty_background
      RAISING
        zcx_abapgit_exception .
    METHODS render
      RETURNING
        VALUE(ro_html) TYPE REF TO zcl_abapgit_html
      RAISING
        zcx_abapgit_exception .
    METHODS decode
      IMPORTING
        !iv_getdata      TYPE clike
      RETURNING
        VALUE(rs_fields) TYPE zcl_abapgit_persist_background=>ty_background .

    METHODS render_content
        REDEFINITION .
  PRIVATE SECTION.

    DATA mv_key TYPE zif_abapgit_persistence=>ty_repo-key .
ENDCLASS.

CLASS ZCL_ABAPGIT_GUI_PAGE_BKG IMPLEMENTATION.

  METHOD build_menu.

    CREATE OBJECT ro_menu.

    ro_menu->add( iv_txt = 'Run background logic'
                  iv_act = zif_abapgit_definitions=>gc_action-go_background_run ) ##NO_TEXT.

  ENDMETHOD.

  METHOD constructor.

    super->constructor( ).

    mv_key = iv_key.
    ms_control-page_title = 'BACKGROUND'.
    ms_control-page_menu  = build_menu( ).

  ENDMETHOD.

  METHOD decode.

    DATA: lt_fields TYPE tihttpnvp.

    FIELD-SYMBOLS: <ls_setting> LIKE LINE OF rs_fields-settings.

    rs_fields-key = mv_key.

    lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( iv_getdata ).

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        name = 'METHOD'
        it   = lt_fields
      CHANGING
        cv   = rs_fields ).
    IF rs_fields-method IS INITIAL.
      RETURN.
    ENDIF.

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        name = 'USERNAME'
        it   = lt_fields
      CHANGING
        cv   = rs_fields ).

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        name = 'PASSWORD'
        it   = lt_fields
      CHANGING
        cv   = rs_fields ).

    CALL METHOD (rs_fields-method)=>zif_abapgit_background~get_settings
      CHANGING
        ct_settings = rs_fields-settings.
    LOOP AT rs_fields-settings ASSIGNING <ls_setting>.
      zcl_abapgit_html_action_utils=>get_field(
        EXPORTING
          name = <ls_setting>-key
          it   = lt_fields
        CHANGING
          cv   = <ls_setting>-value ).
    ENDLOOP.

    ASSERT NOT rs_fields IS INITIAL.

  ENDMETHOD.

  METHOD read_persist.

    DATA: lo_per TYPE REF TO zcl_abapgit_persist_background,
          lt_per TYPE zcl_abapgit_persist_background=>tt_background.

    CREATE OBJECT lo_per.
    lt_per = lo_per->list( ).

    READ TABLE lt_per INTO rs_persist WITH KEY key = io_repo->get_key( ).
    IF sy-subrc <> 0.
      CLEAR rs_persist.
    ENDIF.

  ENDMETHOD.

  METHOD render.

    DATA: lo_repo    TYPE REF TO zcl_abapgit_repo_online,
          ls_per     TYPE zcl_abapgit_persist_background=>ty_background,
          lv_nothing TYPE string,
          lv_push    TYPE string,
          lv_pull    TYPE string,
          lv_afixed  TYPE string,
          lv_aauto   TYPE string,
          lv_auser   TYPE string.

    lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( mv_key ).
    ls_per = read_persist( lo_repo ).

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).

    ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( lo_repo ) ).
    ro_html->add( '
' ).

    ro_html->add( render_methods( ls_per ) ).

    ro_html->add( 'HTTP Authentication, optional
' ) ##NO_TEXT.
    ro_html->add( '(password will be saved in clear text)
' ) ##NO_TEXT.
    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( 'Username:	' ).
    ro_html->add( '<input type="text" name="username" value="' &&
      ls_per-username && '">	' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( 'Password:	' ).
    ro_html->add( '<input type="text" name="password" value="' &&
      ls_per-password && '">	' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).

    ro_html->add( '
' ).

    ro_html->add( render_settings( ls_per ) ).

    ro_html->add( '
' ).
    ro_html->add( '<input type="submit" value="Save">' ).

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

    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_content.

    CREATE OBJECT ro_html.

    ro_html->add( render( ) ).

  ENDMETHOD.

  METHOD render_methods.

    DATA: lt_methods TYPE zcl_abapgit_background=>ty_methods_tt,
          ls_method  LIKE LINE OF lt_methods,
          lv_checked TYPE string.

    CREATE OBJECT ro_html.

    lt_methods = zcl_abapgit_background=>list_methods( ).

    ro_html->add( 'Method
' ) ##NO_TEXT.
    ro_html->add( |<form method="get" action="sapevent:{ zif_abapgit_definitions=>gc_action-bg_update }">| ).

    IF is_per-method IS INITIAL.
      lv_checked = ' checked' ##NO_TEXT.
    ENDIF.

    ro_html->add( '<input type="radio" name="method" value=""' &&
      lv_checked && '>Do nothing
' ) ##NO_TEXT.

    LOOP AT lt_methods INTO ls_method.
      CLEAR lv_checked.
      IF is_per-method = ls_method-class.
        lv_checked = ' checked' ##NO_TEXT.
      ENDIF.

      ro_html->add( '<input type="radio" name="method" value="' &&
        ls_method-class && '"' &&
        lv_checked && '>' &&
        ls_method-description && '
' ) ##NO_TEXT.
    ENDLOOP.

    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_settings.

    DATA: lt_settings LIKE is_per-settings,
          ls_setting  LIKE LINE OF lt_settings.

    CREATE OBJECT ro_html.

    IF is_per-method IS INITIAL.
      RETURN.
    ENDIF.

    lt_settings = is_per-settings.

    CALL METHOD (is_per-method)=>zif_abapgit_background~get_settings
      CHANGING
        ct_settings = lt_settings.

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

    ro_html->add( '
' ).
    LOOP AT lt_settings INTO ls_setting.
      ro_html->add( '
' ).
      ro_html->add( '' && ls_setting-key && ':	' ).
      ro_html->add( '<input type="text" name="' &&
        ls_setting-key && '" value="' &&
        ls_setting-value && '">	' ).
      ro_html->add( '
' ).
    ENDLOOP.
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD update.

    DATA lo_persistence TYPE REF TO zcl_abapgit_persist_background.

    CREATE OBJECT lo_persistence.

    IF is_bg_task-method IS INITIAL.
      lo_persistence->delete( is_bg_task-key ).
    ELSE.
      lo_persistence->modify( is_bg_task ).
    ENDIF.

    MESSAGE 'Saved' TYPE 'S' ##NO_TEXT.

    COMMIT WORK.

  ENDMETHOD.

  METHOD zif_abapgit_gui_page~on_event.

    CASE iv_action.
      WHEN zif_abapgit_definitions=>gc_action-bg_update.
        update( decode( iv_getdata ) ).
        ev_state = zif_abapgit_definitions=>gc_event_state-re_render.
    ENDCASE.

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_gui_page_bkg DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_gui_page
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    METHODS constructor
      IMPORTING
        !iv_key TYPE zif_abapgit_persistence=>ty_repo-key .

    METHODS zif_abapgit_gui_page~on_event
        REDEFINITION .
  PROTECTED SECTION.

    METHODS read_persist
      IMPORTING
        !io_repo          TYPE REF TO zcl_abapgit_repo_online
      RETURNING
        VALUE(rs_persist) TYPE zcl_abapgit_persist_background=>ty_background
      RAISING
        zcx_abapgit_exception .
    METHODS render_methods
      IMPORTING
        !is_per        TYPE zcl_abapgit_persist_background=>ty_background
      RETURNING
        VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
    METHODS render_settings
      IMPORTING
        !is_per        TYPE zcl_abapgit_persist_background=>ty_background
      RETURNING
        VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
    METHODS build_menu
      RETURNING
        VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar .
    CLASS-METHODS update
      IMPORTING
        !is_bg_task TYPE zcl_abapgit_persist_background=>ty_background
      RAISING
        zcx_abapgit_exception .
    METHODS render
      RETURNING
        VALUE(ro_html) TYPE REF TO zcl_abapgit_html
      RAISING
        zcx_abapgit_exception .
    METHODS decode
      IMPORTING
        !iv_getdata      TYPE clike
      RETURNING
        VALUE(rs_fields) TYPE zcl_abapgit_persist_background=>ty_background .

    METHODS render_content
        REDEFINITION .
  PRIVATE SECTION.

    DATA mv_key TYPE zif_abapgit_persistence=>ty_repo-key .
ENDCLASS.

CLASS ZCL_ABAPGIT_GUI_PAGE_BKG IMPLEMENTATION.

  METHOD build_menu.

    CREATE OBJECT ro_menu.

    ro_menu->add( iv_txt = 'Run background logic'
                  iv_act = zif_abapgit_definitions=>gc_action-go_background_run ) ##NO_TEXT.

  ENDMETHOD.

  METHOD constructor.

    super->constructor( ).

    mv_key = iv_key.
    ms_control-page_title = 'BACKGROUND'.
    ms_control-page_menu  = build_menu( ).

  ENDMETHOD.

  METHOD decode.

    DATA: lt_fields TYPE tihttpnvp.

    FIELD-SYMBOLS: <ls_setting> LIKE LINE OF rs_fields-settings.

    rs_fields-key = mv_key.

    lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( iv_getdata ).

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        name = 'METHOD'
        it   = lt_fields
      CHANGING
        cv   = rs_fields ).
    IF rs_fields-method IS INITIAL.
      RETURN.
    ENDIF.

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        name = 'USERNAME'
        it   = lt_fields
      CHANGING
        cv   = rs_fields ).

    zcl_abapgit_html_action_utils=>get_field(
      EXPORTING
        name = 'PASSWORD'
        it   = lt_fields
      CHANGING
        cv   = rs_fields ).

    CALL METHOD (rs_fields-method)=>zif_abapgit_background~get_settings
      CHANGING
        ct_settings = rs_fields-settings.
    LOOP AT rs_fields-settings ASSIGNING <ls_setting>.
      zcl_abapgit_html_action_utils=>get_field(
        EXPORTING
          name = <ls_setting>-key
          it   = lt_fields
        CHANGING
          cv   = <ls_setting>-value ).
    ENDLOOP.

    ASSERT NOT rs_fields IS INITIAL.

  ENDMETHOD.

  METHOD read_persist.

    DATA: lo_per TYPE REF TO zcl_abapgit_persist_background,
          lt_per TYPE zcl_abapgit_persist_background=>tt_background.

    CREATE OBJECT lo_per.
    lt_per = lo_per->list( ).

    READ TABLE lt_per INTO rs_persist WITH KEY key = io_repo->get_key( ).
    IF sy-subrc <> 0.
      CLEAR rs_persist.
    ENDIF.

  ENDMETHOD.

  METHOD render.

    DATA: lo_repo    TYPE REF TO zcl_abapgit_repo_online,
          ls_per     TYPE zcl_abapgit_persist_background=>ty_background,
          lv_nothing TYPE string,
          lv_push    TYPE string,
          lv_pull    TYPE string,
          lv_afixed  TYPE string,
          lv_aauto   TYPE string,
          lv_auser   TYPE string.

    lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( mv_key ).
    ls_per = read_persist( lo_repo ).

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).

    ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( lo_repo ) ).
    ro_html->add( '
' ).

    ro_html->add( render_methods( ls_per ) ).

    ro_html->add( 'HTTP Authentication, optional
' ) ##NO_TEXT.
    ro_html->add( '(password will be saved in clear text)
' ) ##NO_TEXT.
    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( 'Username:	' ).
    ro_html->add( '<input type="text" name="username" value="' &&
      ls_per-username && '">	' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).
    ro_html->add( 'Password:	' ).
    ro_html->add( '<input type="text" name="password" value="' &&
      ls_per-password && '">	' ).
    ro_html->add( '
' ).
    ro_html->add( '
' ).

    ro_html->add( '
' ).

    ro_html->add( render_settings( ls_per ) ).

    ro_html->add( '
' ).
    ro_html->add( '<input type="submit" value="Save">' ).

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

    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_content.

    CREATE OBJECT ro_html.

    ro_html->add( render( ) ).

  ENDMETHOD.

  METHOD render_methods.

    DATA: lt_methods TYPE zcl_abapgit_background=>ty_methods_tt,
          ls_method  LIKE LINE OF lt_methods,
          lv_checked TYPE string.

    CREATE OBJECT ro_html.

    lt_methods = zcl_abapgit_background=>list_methods( ).

    ro_html->add( 'Method
' ) ##NO_TEXT.
    ro_html->add( |<form method="get" action="sapevent:{ zif_abapgit_definitions=>gc_action-bg_update }">| ).

    IF is_per-method IS INITIAL.
      lv_checked = ' checked' ##NO_TEXT.
    ENDIF.

    ro_html->add( '<input type="radio" name="method" value=""' &&
      lv_checked && '>Do nothing
' ) ##NO_TEXT.

    LOOP AT lt_methods INTO ls_method.
      CLEAR lv_checked.
      IF is_per-method = ls_method-class.
        lv_checked = ' checked' ##NO_TEXT.
      ENDIF.

      ro_html->add( '<input type="radio" name="method" value="' &&
        ls_method-class && '"' &&
        lv_checked && '>' &&
        ls_method-description && '
' ) ##NO_TEXT.
    ENDLOOP.

    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD render_settings.

    DATA: lt_settings LIKE is_per-settings,
          ls_setting  LIKE LINE OF lt_settings.

    CREATE OBJECT ro_html.

    IF is_per-method IS INITIAL.
      RETURN.
    ENDIF.

    lt_settings = is_per-settings.

* skip invalid values, from old background logic
    IF is_per-method <> 'push' AND is_per-method <> 'pull' AND is_per-method <> 'nothing'.
      CALL METHOD (is_per-method)=>zif_abapgit_background~get_settings
        CHANGING
          ct_settings = lt_settings.
    ENDIF.

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

    ro_html->add( '
' ).
    LOOP AT lt_settings INTO ls_setting.
      ro_html->add( '
' ).
      ro_html->add( '' && ls_setting-key && ':	' ).
      ro_html->add( '<input type="text" name="' &&
        ls_setting-key && '" value="' &&
        ls_setting-value && '">	' ).
      ro_html->add( '
' ).
    ENDLOOP.
    ro_html->add( '
' ).

  ENDMETHOD.

  METHOD update.

    DATA lo_persistence TYPE REF TO zcl_abapgit_persist_background.

    CREATE OBJECT lo_persistence.

    IF is_bg_task-method IS INITIAL.
      lo_persistence->delete( is_bg_task-key ).
    ELSE.
      lo_persistence->modify( is_bg_task ).
    ENDIF.

    MESSAGE 'Saved' TYPE 'S' ##NO_TEXT.

    COMMIT WORK.

  ENDMETHOD.

  METHOD zif_abapgit_gui_page~on_event.

    CASE iv_action.
      WHEN zif_abapgit_definitions=>gc_action-bg_update.
        update( decode( iv_getdata ) ).
        ev_state = zif_abapgit_definitions=>gc_event_state-re_render.
    ENDCASE.

  ENDMETHOD.
ENDCLASS.

fix dump when reconfiguring

background: fix dump when reconfiguring

fix dump due to old background settings


CLASS zcl_abapgit_migrations DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    CLASS-METHODS run
      RAISING zcx_abapgit_exception.

  PROTECTED SECTION.
  PRIVATE SECTION.

    CLASS-METHODS local_dot_abapgit
      RAISING
        zcx_abapgit_exception .
ENDCLASS.

CLASS zcl_abapgit_migrations IMPLEMENTATION.

  METHOD local_dot_abapgit.

    DATA: lt_repos       TYPE zif_abapgit_repo_srv=>ty_repo_list,
          lo_dot_abapgit TYPE REF TO zcl_abapgit_dot_abapgit.

    FIELD-SYMBOLS: <lo_repo> LIKE LINE OF lt_repos.

    lt_repos = zcl_abapgit_repo_srv=>get_instance( )->list( ).

    LOOP AT lt_repos ASSIGNING <lo_repo>.
      lo_dot_abapgit = <lo_repo>->get_dot_abapgit( ).
      IF lo_dot_abapgit->get_data( ) IS INITIAL.
        CALL FUNCTION 'POPUP_TO_INFORM'
          EXPORTING
            titel = 'Migration'
            txt1  = 'Automatic migration of .abapgit.xml removed'
            txt2  = 'Remove all repos and install latest abapGit version'.
      ENDIF.

    ENDLOOP.

  ENDMETHOD.

  METHOD run.

    " Migrate STDTEXT to TABLE
    zcl_abapgit_persist_migrate=>run( ).

    " Create ZIF_APACK_MANIFEST interface
    zcl_abapgit_apack_migration=>run( ).

    " local .abapgit.xml state, issue #630
    local_dot_abapgit( ).

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_migrations DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    CLASS-METHODS run
      RAISING zcx_abapgit_exception.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_abapgit_migrations IMPLEMENTATION.

  METHOD run.

    " Migrate STDTEXT to TABLE
    zcl_abapgit_persist_migrate=>run( ).

    " Create ZIF_APACK_MANIFEST interface
    zcl_abapgit_apack_migration=>run( ).

  ENDMETHOD.

ENDCLASS.

Remove local_dot_abapgit migration (#4543)

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


*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_PAGE_STAGE
*&---------------------------------------------------------------------*

CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page_super.

  PUBLIC SECTION.
    CONSTANTS: BEGIN OF c_action,
                 stage_all    TYPE string VALUE 'stage_all',
                 stage_commit TYPE string VALUE 'stage_commit',
               END OF c_action.

    METHODS:
      constructor
        IMPORTING io_repo TYPE REF TO lcl_repo_online
        RAISING   lcx_exception,
      lif_gui_page~render REDEFINITION,
      lif_gui_page~on_event REDEFINITION.

  PRIVATE SECTION.
    DATA: mo_repo  TYPE REF TO lcl_repo_online,
          ms_files TYPE ty_stage_files,
          mo_stage TYPE REF TO lcl_stage.

    METHODS:
      render_list
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      render_file
        IMPORTING is_file     TYPE ty_file
                  iv_context  TYPE string
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      render_menu
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      styles
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      scripts
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper.

    METHODS process_stage_list
      IMPORTING it_postdata  TYPE cnht_post_data_tab
      RAISING   lcx_exception.

ENDCLASS.

CLASS lcl_gui_page_stage IMPLEMENTATION.

  METHOD constructor.

    super->constructor( ).
    mo_repo = io_repo.

    ms_files = lcl_stage_logic=>get( mo_repo ).

    CREATE OBJECT mo_stage
      EXPORTING
        iv_branch_name = io_repo->get_branch_name( )
        iv_branch_sha1 = io_repo->get_sha1_remote( ).

  ENDMETHOD.

  METHOD lif_gui_page~on_event.

    FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local.

    CASE iv_action.
      WHEN c_action-stage_all.
        mo_stage->reset_all( ).
        LOOP AT ms_files-local ASSIGNING <ls_file>.
          mo_stage->add( iv_path     = <ls_file>-file-path
                         iv_filename = <ls_file>-file-filename
                         iv_data     = <ls_file>-file-data ).
        ENDLOOP.
      WHEN c_action-stage_commit.
        mo_stage->reset_all( ).
        process_stage_list( it_postdata ).
      WHEN OTHERS.
        RETURN.
    ENDCASE.

    CREATE OBJECT ei_page TYPE lcl_gui_page_commit
      EXPORTING
        io_repo  = mo_repo
        io_stage = mo_stage.

    ev_state = gc_event_state-new_page.

  ENDMETHOD.

  METHOD process_stage_list.

    DATA: lv_string TYPE string,
          lt_fields TYPE tihttpnvp,
          ls_file TYPE ty_file.

    FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local,
                   <ls_item> LIKE LINE OF lt_fields.

    CONCATENATE LINES OF it_postdata INTO lv_string.
    lt_fields = cl_http_utility=>if_http_utility~string_to_fields( |{ lv_string }| ).

    IF lines( lt_fields ) = 0.
      lcx_exception=>raise( 'process_stage_list: empty list' ).
    ENDIF.

    LOOP AT lt_fields ASSIGNING <ls_item>.

      lcl_url=>split_file_location( EXPORTING iv_fullpath = <ls_item>-name
                                    IMPORTING ev_path     = ls_file-path
                                              ev_filename = ls_file-filename ).

      CASE <ls_item>-value.
        WHEN lcl_stage=>c_method-add.
          READ TABLE ms_files-local ASSIGNING <ls_file>
            WITH KEY file-path     = ls_file-path
                     file-filename = ls_file-filename.
          ASSERT sy-subrc = 0.
          mo_stage->add(    iv_path     = <ls_file>-file-path
                            iv_filename = <ls_file>-file-filename
                            iv_data     = <ls_file>-file-data ).
        WHEN lcl_stage=>c_method-ignore.
          mo_stage->ignore( iv_path     = ls_file-path
                            iv_filename = ls_file-filename ).
        WHEN lcl_stage=>c_method-rm.
          mo_stage->rm(     iv_path     = ls_file-path
                            iv_filename = ls_file-filename ).
        WHEN lcl_stage=>c_method-skip.
          " Do nothing
        WHEN OTHERS.
          lcx_exception=>raise( |process_stage_list: unknown method { <ls_item>-value }| ).
      ENDCASE.
    ENDLOOP.

  ENDMETHOD.        "process_stage_list

  METHOD render_list.

    FIELD-SYMBOLS: <ls_remote> LIKE LINE OF ms_files-remote,
                   <ls_local>  LIKE LINE OF ms_files-local.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).

    " Local changes
    LOOP AT ms_files-local ASSIGNING <ls_local>.
      AT FIRST.
        ro_html->add('

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

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

      ro_html->add( render_file( is_file = <ls_local>-file iv_context = 'local' ) ).

      AT LAST.
        ro_html->add('
').
      ENDAT.
    ENDLOOP.

    " Remote changes
    LOOP AT ms_files-remote ASSIGNING <ls_remote>.
      AT FIRST.
        ro_html->add('

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

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

      ro_html->add( render_file( is_file = <ls_remote> iv_context = 'remote' ) ).

      AT LAST.
        ro_html->add('
').
      ENDAT.
    ENDLOOP.

    ro_html->add( '
' ).

  ENDMETHOD.      "render_lines

  METHOD render_file.

    DATA lv_param TYPE string.

    CREATE OBJECT ro_html.

    ro_html->add( |
| ).
    ro_html->add( |?	| ).
    ro_html->add( |{ is_file-path && is_file-filename }	| ).

    CASE iv_context.
      WHEN 'local'.
        lv_param = lcl_html_action_utils=>file_encode( iv_key  = mo_repo->get_key( )
                                                       ig_file = is_file ).
        ro_html->add( 'add	' ).
        ro_html->add( '' ).
        ro_html->add_anchor( iv_txt = 'diff' iv_act = |{ gc_action-go_diff }?{ lv_param }| ).
        ro_html->add( '	' ).
      WHEN 'remote'.
        ro_html->add( 'ignoreremove	' ).
        ro_html->add( |-	| ).
    ENDCASE.

    ro_html->add( '
' ).

  ENDMETHOD.  "render_file

  METHOD lif_gui_page~render.

    CREATE OBJECT ro_html.

    ro_html->add( header( io_include_style = styles( ) ) ).
    ro_html->add( title( 'STAGE' ) ).

    ro_html->add( '
' ).
    ro_html->add( render_repo_top( mo_repo ) ).
    ro_html->add( render_menu( ) ).
    ro_html->add( render_list( ) ).
    ro_html->add( '
' ).

    ro_html->add( footer( scripts( ) ) ).

  ENDMETHOD.      "lif_gui_page~render

  METHOD render_menu.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).
    ro_html->add_anchor( iv_act   = 'commit();'
                         iv_typ   = gc_action_type-onclick
                         iv_id    = 'act_commit'
                         iv_style = 'display: none'
                         iv_txt   = 'Commit'
                         iv_opt   = gc_html_opt-emphas ) ##NO_TEXT.
    ro_html->add_anchor( iv_act   = |{ c_action-stage_all }|
                         iv_id    = 'act_commit_all'
                         iv_txt   = 'Add all and commit') ##NO_TEXT.
    ro_html->add( '
' ).

  ENDMETHOD.      "render_menu

  METHOD styles.

    CREATE OBJECT ro_html.

    _add '/* STAGE */'.
    _add '.stage_tab {'.
    _add '  border: 1px solid #DDD;'.
    _add '  background: #fff;'.
    _add '  margin-top: 0.2em;'.
    _add '}'.
    _add '.stage_tab td {'.
    _add '  border-top: 1px solid #eee;'.
    _add '  color: #333;'.
    _add '  vertical-align: middle;'.
    _add '  padding: 2px 0.5em;'.
    _add '}'.
    _add '.stage_tab th {'.
    _add '  color: #BBB;'.
    _add '  font-size: 10pt;'.
    _add '  text-align: left;'.
    _add '  font-weight: normal;'.
    _add '  background-color: #edf2f9;'.
    _add '  padding: 4px 0.5em;'.
    _add '}'.
    _add '.stage_tab td.status {'.
    _add '  width: 2em;'.
    _add '  text-align: center;'.
    _add '}'.
    _add '.stage_tab tbody tr:first-child td { padding-top: 0.5em; }'.
    _add '.stage_tab tbody tr:last-child td { padding-bottom: 0.5em; }'.
    _add '.stage_tab td.cmd a { padding: 0px 4px; }'.

  ENDMETHOD.    "styles

  METHOD scripts.

    CREATE OBJECT ro_html.

    " Hook global click listener on table, global action counter
    _add 'document.getElementById("stage_tab").addEventListener("click", onEvent);'.
    _add 'var gChoiceCount = 0;'.

    " Event handler, change status
    _add 'function onEvent(event) {'.
    _add '  if (event.target.tagName != "A") return;'.
    _add '  var td = event.target.parentNode;'.
    _add '  if (!td || td.tagName != "TD" || td.className != "cmd") return;'.
    _add '  var cmd     = event.target.innerText;'.
    _add '  var tr      = td.parentNode;'.
    _add '  var context = tr.parentNode.className;'.
    _add '  switch (cmd) {'.
    _add '    case "add":    cmd = "A"; gChoiceCount++; break;'.
    _add '    case "remove": cmd = "R"; gChoiceCount++; break;'.
    _add '    case "ignore": cmd = "I"; gChoiceCount++; break;'.
    _add '    case "reset":  cmd = "?"; gChoiceCount--; break;'.
    _add '  }'.
    _add '  formatTR(tr, cmd, context);'.
    _add '  updateMenu();'.
    _add '}'.

    " Re-format table line
    _add 'function formatTR(tr, cmd, context) {'.
    _add '  const cmdReset  = "reset"; '.
    _add '  const cmdLocal  = "add"; '.
    _add '  const cmdRemote = "ignoreremove";'.
    _add '  tr.cells[0].innerText   = cmd;'.
    _add '  tr.cells[0].style.color = (cmd == "?")?"#CCC":"";'.
    _add '  tr.cells[2].innerHTML   = (cmd != "?")?cmdReset'.
    _add '    :(context == "local")?cmdLocal:cmdRemote;'.
    _add '}'.

    " Update menu items visibility
    _add 'function updateMenu() {'.
    _add '  if (gChoiceCount > 0) {'.
    _add '    document.getElementById("act_commit").style.display     = "inline";'.
    _add '    document.getElementById("act_commit_all").style.display = "none";'.
    _add '  } else {'.
    _add '    document.getElementById("act_commit").style.display     = "none";'.
    _add '    document.getElementById("act_commit_all").style.display = "inline";'.
    _add '  }'.
    _add '}'.

    " Commit change to the server
    _add 'function commit() {'.
    _add '  var data = collectData();'.
    ro_html->add( |  submitForm(data, "{ c_action-stage_commit }");| ).
    _add '}'.

    " Extract data from the table
    _add 'function collectData() {'.
    _add '  var stage = document.getElementById("stage_tab");'.
    _add '  var data = {};'.
    _add '  for (var i = stage.rows.length - 1; i >= 0; i--) {'.
    _add '    var row = stage.rows[i];'.
    _add '    if (row.parentNode.tagName == "THEAD") continue;'.
    _add '    data[row.cells[1].innerText] = row.cells[0].innerText;'.
    _add '  }'.
    _add '  return data;      '.
    _add '}'.

  ENDMETHOD.  "scripts

ENDCLASS.

*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_PAGE_STAGE
*&---------------------------------------------------------------------*

CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page_super.

  PUBLIC SECTION.
    CONSTANTS: BEGIN OF c_action,
                 stage_all    TYPE string VALUE 'stage_all',
                 stage_commit TYPE string VALUE 'stage_commit',
               END OF c_action.

    METHODS:
      constructor
        IMPORTING io_repo TYPE REF TO lcl_repo_online
        RAISING   lcx_exception,
      lif_gui_page~render REDEFINITION,
      lif_gui_page~on_event REDEFINITION.

  PRIVATE SECTION.
    DATA: mo_repo  TYPE REF TO lcl_repo_online,
          ms_files TYPE ty_stage_files,
          mo_stage TYPE REF TO lcl_stage.

    METHODS:
      render_list
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      render_file
        IMPORTING is_file     TYPE ty_file
                  iv_context  TYPE string
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      render_menu
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      styles
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
      scripts
        RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper.

    METHODS process_stage_list
      IMPORTING it_postdata  TYPE cnht_post_data_tab
      RAISING   lcx_exception.

ENDCLASS.

CLASS lcl_gui_page_stage IMPLEMENTATION.

  METHOD constructor.

    super->constructor( ).
    mo_repo = io_repo.

    ms_files = lcl_stage_logic=>get( mo_repo ).

    CREATE OBJECT mo_stage
      EXPORTING
        iv_branch_name = io_repo->get_branch_name( )
        iv_branch_sha1 = io_repo->get_sha1_remote( ).

  ENDMETHOD.

  METHOD lif_gui_page~on_event.

    FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local.

    CASE iv_action.
      WHEN c_action-stage_all.
        mo_stage->reset_all( ).
        LOOP AT ms_files-local ASSIGNING <ls_file>.
          mo_stage->add( iv_path     = <ls_file>-file-path
                         iv_filename = <ls_file>-file-filename
                         iv_data     = <ls_file>-file-data ).
        ENDLOOP.
      WHEN c_action-stage_commit.
        mo_stage->reset_all( ).
        process_stage_list( it_postdata ).
      WHEN OTHERS.
        RETURN.
    ENDCASE.

    CREATE OBJECT ei_page TYPE lcl_gui_page_commit
      EXPORTING
        io_repo  = mo_repo
        io_stage = mo_stage.

    ev_state = gc_event_state-new_page.

  ENDMETHOD.

  METHOD process_stage_list.

    DATA: lv_string TYPE string,
          lt_fields TYPE tihttpnvp,
          ls_file TYPE ty_file.

    FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local,
                   <ls_item> LIKE LINE OF lt_fields.

    CONCATENATE LINES OF it_postdata INTO lv_string.
    lt_fields = cl_http_utility=>if_http_utility~string_to_fields( |{ lv_string }| ).

    IF lines( lt_fields ) = 0.
      lcx_exception=>raise( 'process_stage_list: empty list' ).
    ENDIF.

    LOOP AT lt_fields ASSIGNING <ls_item>.

      lcl_url=>split_file_location( EXPORTING iv_fullpath = <ls_item>-name
                                    IMPORTING ev_path     = ls_file-path
                                              ev_filename = ls_file-filename ).

      CASE <ls_item>-value.
        WHEN lcl_stage=>c_method-add.
          READ TABLE ms_files-local ASSIGNING <ls_file>
            WITH KEY file-path     = ls_file-path
                     file-filename = ls_file-filename.
          ASSERT sy-subrc = 0.
          mo_stage->add(    iv_path     = <ls_file>-file-path
                            iv_filename = <ls_file>-file-filename
                            iv_data     = <ls_file>-file-data ).
        WHEN lcl_stage=>c_method-ignore.
          mo_stage->ignore( iv_path     = ls_file-path
                            iv_filename = ls_file-filename ).
        WHEN lcl_stage=>c_method-rm.
          mo_stage->rm(     iv_path     = ls_file-path
                            iv_filename = ls_file-filename ).
        WHEN lcl_stage=>c_method-skip.
          " Do nothing
        WHEN OTHERS.
          lcx_exception=>raise( |process_stage_list: unknown method { <ls_item>-value }| ).
      ENDCASE.
    ENDLOOP.

  ENDMETHOD.        "process_stage_list

  METHOD render_list.

    FIELD-SYMBOLS: <ls_remote> LIKE LINE OF ms_files-remote,
                   <ls_local>  LIKE LINE OF ms_files-local.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).

    " Local changes
    LOOP AT ms_files-local ASSIGNING <ls_local>.
      AT FIRST.
        ro_html->add('

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

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

      ro_html->add( render_file( is_file = <ls_local>-file iv_context = 'local' ) ).

      AT LAST.
        ro_html->add('
').
      ENDAT.
    ENDLOOP.

    " Remote changes
    LOOP AT ms_files-remote ASSIGNING <ls_remote>.
      AT FIRST.
        ro_html->add('

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

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

      ro_html->add( render_file( is_file = <ls_remote> iv_context = 'remote' ) ).

      AT LAST.
        ro_html->add('
').
      ENDAT.
    ENDLOOP.

    ro_html->add( '
' ).

  ENDMETHOD.      "render_lines

  METHOD render_file.

    DATA lv_param TYPE string.

    CREATE OBJECT ro_html.

    ro_html->add( |
| ).
    ro_html->add( |?	| ).
    ro_html->add( |{ is_file-path && is_file-filename }	| ).

    CASE iv_context.
      WHEN 'local'.
        lv_param = lcl_html_action_utils=>file_encode( iv_key  = mo_repo->get_key( )
                                                       ig_file = is_file ).
        ro_html->add( 'add	' ).
        ro_html->add( '' ).
        ro_html->add_anchor( iv_txt = 'diff' iv_act = |{ gc_action-go_diff }?{ lv_param }| ).
        ro_html->add( '	' ).
      WHEN 'remote'.
        ro_html->add( 'ignoreremove	' ).
        ro_html->add( |-	| ).
    ENDCASE.

    ro_html->add( '
' ).

  ENDMETHOD.  "render_file

  METHOD lif_gui_page~render.

    CREATE OBJECT ro_html.

    ro_html->add( header( io_include_style = styles( ) ) ).
    ro_html->add( title( 'STAGE' ) ).

    ro_html->add( '
' ).
    ro_html->add( render_repo_top( mo_repo ) ).
    ro_html->add( render_menu( ) ).
    ro_html->add( render_list( ) ).
    ro_html->add( '
' ).

    ro_html->add( footer( scripts( ) ) ).

  ENDMETHOD.      "lif_gui_page~render

  METHOD render_menu.

    CREATE OBJECT ro_html.

    ro_html->add( '
' ).
    ro_html->add_anchor( iv_act   = 'commit();'
                         iv_typ   = gc_action_type-onclick
                         iv_id    = 'act_commit'
                         iv_style = 'display: none'
                         iv_txt   = 'Commit'
                         iv_opt   = gc_html_opt-emphas ) ##NO_TEXT.
    ro_html->add_anchor( iv_act   = |{ c_action-stage_all }|
                         iv_id    = 'act_commit_all'
                         iv_txt   = 'Add all and commit') ##NO_TEXT.
    ro_html->add( '
' ).

  ENDMETHOD.      "render_menu

  METHOD styles.

    CREATE OBJECT ro_html.

    _add '/* STAGE */'.
    _add '.stage_tab {'.
    _add '  border: 1px solid #DDD;'.
    _add '  background: #fff;'.
    _add '  margin-top: 0.2em;'.
    _add '}'.
    _add '.stage_tab td {'.
    _add '  border-top: 1px solid #eee;'.
    _add '  color: #333;'.
    _add '  vertical-align: middle;'.
    _add '  padding: 2px 0.5em;'.
    _add '}'.
    _add '.stage_tab th {'.
    _add '  color: #BBB;'.
    _add '  font-size: 10pt;'.
    _add '  text-align: left;'.
    _add '  font-weight: normal;'.
    _add '  background-color: #edf2f9;'.
    _add '  padding: 4px 0.5em;'.
    _add '}'.
    _add '.stage_tab td.status {'.
    _add '  width: 2em;'.
    _add '  text-align: center;'.
    _add '}'.
    _add '.stage_tab tbody tr:first-child td { padding-top: 0.5em; }'.
    _add '.stage_tab tbody tr:last-child td { padding-bottom: 0.5em; }'.
    _add '.stage_tab td.cmd a { padding: 0px 4px; }'.

  ENDMETHOD.    "styles

  METHOD scripts.

    CREATE OBJECT ro_html.

    " Hook global click listener on table, global action counter
    _add 'document.getElementById("stage_tab").addEventListener("click", onEvent);'.
    _add 'var gChoiceCount = 0;'.

    " Event handler, change status
    _add 'function onEvent(event) {'.
    _add '  if (event.target.tagName != "A") return;'.
    _add '  var td = event.target.parentNode;'.
    _add '  if (!td || td.tagName != "TD" || td.className != "cmd") return;'.
    _add '  var cmd     = event.target.innerText;'.
    _add '  var tr      = td.parentNode;'.
    _add '  var context = tr.parentNode.className;'.
    _add '  switch (cmd) {'.
    _add '    case "add":    cmd = "A"; gChoiceCount++; break;'.
    _add '    case "remove": cmd = "R"; gChoiceCount++; break;'.
    _add '    case "ignore": cmd = "I"; gChoiceCount++; break;'.
    _add '    case "reset":  cmd = "?"; gChoiceCount--; break;'.
    _add '  }'.
    _add '  formatTR(tr, cmd, context);'.
    _add '  updateMenu();'.
    _add '}'.

    " Re-format table line
    _add 'function formatTR(tr, cmd, context) {'.
    _add '  var cmdReset  = "reset"; '.
    _add '  var cmdLocal  = "add"; '.
    _add '  var cmdRemote = "ignoreremove";'.
    _add '  tr.cells[0].innerText   = cmd;'.
    _add '  tr.cells[0].style.color = (cmd == "?")?"#CCC":"";'.
    _add '  tr.cells[2].innerHTML   = (cmd != "?")?cmdReset'.
    _add '    :(context == "local")?cmdLocal:cmdRemote;'.
    _add '}'.

    " Update menu items visibility
    _add 'function updateMenu() {'.
    _add '  if (gChoiceCount > 0) {'.
    _add '    document.getElementById("act_commit").style.display     = "inline";'.
    _add '    document.getElementById("act_commit_all").style.display = "none";'.
    _add '  } else {'.
    _add '    document.getElementById("act_commit").style.display     = "none";'.
    _add '    document.getElementById("act_commit_all").style.display = "inline";'.
    _add '  }'.
    _add '}'.

    " Commit change to the server
    _add 'function commit() {'.
    _add '  var data = collectData();'.
    ro_html->add( |  submitForm(data, "{ c_action-stage_commit }");| ).
    _add '}'.

    " Extract data from the table
    _add 'function collectData() {'.
    _add '  var stage = document.getElementById("stage_tab");'.
    _add '  var data = {};'.
    _add '  for (var i = stage.rows.length - 1; i >= 0; i--) {'.
    _add '    var row = stage.rows[i];'.
    _add '    if (row.parentNode.tagName == "THEAD") continue;'.
    _add '    data[row.cells[1].innerText] = row.cells[0].innerText;'.
    _add '  }'.
    _add '  return data;      '.
    _add '}'.

  ENDMETHOD.  "scripts

ENDCLASS.

fix staging link on IE9(?), close #367

fix staging link on IE9(?), close #367


CLASS ltcl_get_t100_longtext DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.

  PUBLIC SECTION.
    INTERFACES if_t100_message.
    METHODS test01 FOR TESTING.

ENDCLASS.

CLASS ltcl_get_t100_longtext IMPLEMENTATION.

  METHOD test01.

    DATA lo_cut TYPE REF TO zcl_abapgit_message_helper.
    DATA lv_result TYPE string.

    if_t100_message~t100key-msgid = '00'.
    if_t100_message~t100key-msgno = '058'.
    if_t100_message~t100key-attr1 = 'ATTR'.

    CREATE OBJECT lo_cut
      EXPORTING
        ii_t100_message = me.

    lv_result = lo_cut->get_t100_longtext( ).
    cl_abap_unit_assert=>assert_not_initial( lv_result ).

  ENDMETHOD.

ENDCLASS.

CLASS ltcl_set_msg_vars_for_clike DEFINITION
  FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PUBLIC SECTION.
    METHODS:
      test_set_msg_b FOR TESTING,
      test_set_msg_c FOR TESTING,
      test_set_msg_d FOR TESTING,
      test_set_msg_e FOR TESTING,
      test_set_msg_z FOR TESTING.
  PROTECTED SECTION.
  PRIVATE SECTION.
    TYPES:
      BEGIN OF ty_msg,
        v1 TYPE sy-msgv1,
        v2 TYPE sy-msgv2,
        v3 TYPE sy-msgv3,
        v4 TYPE sy-msgv4,
      END OF ty_msg.
    CLASS-METHODS:
      test_set_msg_vars
        IMPORTING
          iv_text TYPE string
          is_msg  TYPE ty_msg.
ENDCLASS.

CLASS ltcl_set_msg_vars_for_clike IMPLEMENTATION.
  METHOD test_set_msg_b.
    CONSTANTS:
      lc_text_b TYPE string VALUE '0123456789012345678901234567890123456789012345678 0123456789',
      BEGIN OF lc_msg_b,
        v1 TYPE sy-msgv1 VALUE '0123456789012345678901234567890123456789012345678',
        v2 TYPE sy-msgv2 VALUE ' 0123456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_b.
    test_set_msg_vars( iv_text = lc_text_b
                       is_msg  = lc_msg_b ).
  ENDMETHOD.
  METHOD test_set_msg_c.
    CONSTANTS:
      lc_text_c TYPE string VALUE '01234567890123456789012345678901234567890123456789 123456789',
      BEGIN OF lc_msg_c,
        v1 TYPE sy-msgv1 VALUE '01234567890123456789012345678901234567890123456789',
        v2 TYPE sy-msgv2 VALUE ' 123456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_c.
    test_set_msg_vars( iv_text = lc_text_c
                       is_msg  = lc_msg_c ).
  ENDMETHOD.
  METHOD test_set_msg_d.
    CONSTANTS:
      lc_text_d TYPE string VALUE '012345678901234567890123456789012345678901234567890 23456789',
      BEGIN OF lc_msg_d,
        v1 TYPE sy-msgv1 VALUE '01234567890123456789012345678901234567890123456789',
        v2 TYPE sy-msgv2 VALUE '0 23456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_d.
    test_set_msg_vars( iv_text = lc_text_d
                       is_msg  = lc_msg_d ).
  ENDMETHOD.
  METHOD test_set_msg_e.
    CONSTANTS:
      lc_text_e TYPE string VALUE '012345678901234567890123456789012345678901234567890123456789',
      BEGIN OF lc_msg_e,
        v1 TYPE sy-msgv1 VALUE '01234567890123456789012345678901234567890123456789',
        v2 TYPE sy-msgv2 VALUE '0123456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_e.
    test_set_msg_vars( iv_text = lc_text_e
                       is_msg  = lc_msg_e ).
  ENDMETHOD.
  METHOD test_set_msg_z.
    CONSTANTS:
      lc_text_x TYPE string VALUE `Here is a very long text more than 200 characters and we have to invent `,
      lc_text_y TYPE string VALUE `a nice story about abapGit to fill this long message. abapGit is simply `,
      lc_text_z TYPE string VALUE `the greatest! #abapGit #awesome #community #opensource`,
      BEGIN OF lc_msg_z,
        v1 TYPE sy-msgv1 VALUE `Here is a very long text more than 200 characters`,
        v2 TYPE sy-msgv2 VALUE ` and we have to invent a nice story about abapGit`,
        v3 TYPE sy-msgv3 VALUE ` to fill this long message. abapGit is simply the`,
        v4 TYPE sy-msgv4 VALUE ` greatest! #abapGit #awesome #community`,
      END OF lc_msg_z.
    test_set_msg_vars( iv_text = lc_text_x && lc_text_y && lc_text_z
                       is_msg  = lc_msg_z ).
  ENDMETHOD.
  METHOD test_set_msg_vars.

    zcl_abapgit_message_helper=>set_msg_vars_for_clike( iv_text ).

    cl_abap_unit_assert=>assert_equals( act = sy-msgv1
                                        exp = is_msg-v1 ).
    cl_abap_unit_assert=>assert_equals( act = sy-msgv2
                                        exp = is_msg-v2 ).
    cl_abap_unit_assert=>assert_equals( act = sy-msgv3
                                        exp = is_msg-v3 ).
    cl_abap_unit_assert=>assert_equals( act = sy-msgv4
                                        exp = is_msg-v4 ).

  ENDMETHOD.
ENDCLASS.

CLASS ltcl_get_t100_longtext DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.

  PUBLIC SECTION.
    INTERFACES if_t100_message.
    METHODS test01 FOR TESTING.

ENDCLASS.

CLASS ltcl_get_t100_longtext IMPLEMENTATION.

  METHOD if_message~get_longtext.
    RETURN.
  ENDMETHOD.

  METHOD if_message~get_text.
    RETURN.
  ENDMETHOD.

  METHOD test01.

    DATA lo_cut TYPE REF TO zcl_abapgit_message_helper.
    DATA lv_result TYPE string.

    if_t100_message~t100key-msgid = '00'.
    if_t100_message~t100key-msgno = '058'.
    if_t100_message~t100key-attr1 = 'ATTR'.

    CREATE OBJECT lo_cut
      EXPORTING
        ii_t100_message = me.

    lv_result = lo_cut->get_t100_longtext( ).
    cl_abap_unit_assert=>assert_not_initial( lv_result ).

  ENDMETHOD.

ENDCLASS.

CLASS ltcl_set_msg_vars_for_clike DEFINITION
  FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PUBLIC SECTION.
    METHODS:
      test_set_msg_b FOR TESTING,
      test_set_msg_c FOR TESTING,
      test_set_msg_d FOR TESTING,
      test_set_msg_e FOR TESTING,
      test_set_msg_z FOR TESTING.
  PROTECTED SECTION.
  PRIVATE SECTION.
    TYPES:
      BEGIN OF ty_msg,
        v1 TYPE sy-msgv1,
        v2 TYPE sy-msgv2,
        v3 TYPE sy-msgv3,
        v4 TYPE sy-msgv4,
      END OF ty_msg.
    CLASS-METHODS:
      test_set_msg_vars
        IMPORTING
          iv_text TYPE string
          is_msg  TYPE ty_msg.
ENDCLASS.

CLASS ltcl_set_msg_vars_for_clike IMPLEMENTATION.
  METHOD test_set_msg_b.
    CONSTANTS:
      lc_text_b TYPE string VALUE '0123456789012345678901234567890123456789012345678 0123456789',
      BEGIN OF lc_msg_b,
        v1 TYPE sy-msgv1 VALUE '0123456789012345678901234567890123456789012345678',
        v2 TYPE sy-msgv2 VALUE ' 0123456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_b.
    test_set_msg_vars( iv_text = lc_text_b
                       is_msg  = lc_msg_b ).
  ENDMETHOD.
  METHOD test_set_msg_c.
    CONSTANTS:
      lc_text_c TYPE string VALUE '01234567890123456789012345678901234567890123456789 123456789',
      BEGIN OF lc_msg_c,
        v1 TYPE sy-msgv1 VALUE '01234567890123456789012345678901234567890123456789',
        v2 TYPE sy-msgv2 VALUE ' 123456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_c.
    test_set_msg_vars( iv_text = lc_text_c
                       is_msg  = lc_msg_c ).
  ENDMETHOD.
  METHOD test_set_msg_d.
    CONSTANTS:
      lc_text_d TYPE string VALUE '012345678901234567890123456789012345678901234567890 23456789',
      BEGIN OF lc_msg_d,
        v1 TYPE sy-msgv1 VALUE '01234567890123456789012345678901234567890123456789',
        v2 TYPE sy-msgv2 VALUE '0 23456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_d.
    test_set_msg_vars( iv_text = lc_text_d
                       is_msg  = lc_msg_d ).
  ENDMETHOD.
  METHOD test_set_msg_e.
    CONSTANTS:
      lc_text_e TYPE string VALUE '012345678901234567890123456789012345678901234567890123456789',
      BEGIN OF lc_msg_e,
        v1 TYPE sy-msgv1 VALUE '01234567890123456789012345678901234567890123456789',
        v2 TYPE sy-msgv2 VALUE '0123456789',
        v3 TYPE sy-msgv3 VALUE '',
        v4 TYPE sy-msgv4 VALUE '',
      END OF lc_msg_e.
    test_set_msg_vars( iv_text = lc_text_e
                       is_msg  = lc_msg_e ).
  ENDMETHOD.
  METHOD test_set_msg_z.
    CONSTANTS:
      lc_text_x TYPE string VALUE `Here is a very long text more than 200 characters and we have to invent `,
      lc_text_y TYPE string VALUE `a nice story about abapGit to fill this long message. abapGit is simply `,
      lc_text_z TYPE string VALUE `the greatest! #abapGit #awesome #community #opensource`,
      BEGIN OF lc_msg_z,
        v1 TYPE sy-msgv1 VALUE `Here is a very long text more than 200 characters`,
        v2 TYPE sy-msgv2 VALUE ` and we have to invent a nice story about abapGit`,
        v3 TYPE sy-msgv3 VALUE ` to fill this long message. abapGit is simply the`,
        v4 TYPE sy-msgv4 VALUE ` greatest! #abapGit #awesome #community`,
      END OF lc_msg_z.
    test_set_msg_vars( iv_text = lc_text_x && lc_text_y && lc_text_z
                       is_msg  = lc_msg_z ).
  ENDMETHOD.
  METHOD test_set_msg_vars.

    zcl_abapgit_message_helper=>set_msg_vars_for_clike( iv_text ).

    cl_abap_unit_assert=>assert_equals( act = sy-msgv1
                                        exp = is_msg-v1 ).
    cl_abap_unit_assert=>assert_equals( act = sy-msgv2
                                        exp = is_msg-v2 ).
    cl_abap_unit_assert=>assert_equals( act = sy-msgv3
                                        exp = is_msg-v3 ).
    cl_abap_unit_assert=>assert_equals( act = sy-msgv4
                                        exp = is_msg-v4 ).

  ENDMETHOD.
ENDCLASS.

fix syntax warning in ZCL_ABAPGIT_MESSAGE_HELPER (#3932)

closes #3921