"! Version constants for abap-log
CLASS zcl_alog_version DEFINITION
  PUBLIC
  FINAL
  CREATE PRIVATE.

  PUBLIC SECTION.
    CONSTANTS:
      "! Version of abap-log library in major.minor.revision format
      gc_version TYPE string VALUE '0.1.0-SNAPSHOT'.
    CLASS-METHODS:
      class_constructor,
      "! Factory method
      "! @parameter iv_version | Version string
      "! @parameter ro_version | Created instance
      "! @raising zcx_alog_illegal_argument | iv_version does not have the required format
      of IMPORTING iv_version        TYPE string
         RETURNING VALUE(ro_version) TYPE REF TO zcl_alog_version
         RAISING   zcx_alog_illegal_argument,
      "! Compare two version instances
      "! @parameter io_version_a | Version A
      "! @parameter io_version_b | Version B
      "! @parameter rv_result |

      "!
Less than 0 = version A is lower than version B

      "!
Greater than 0 = version A is higher than version B

      "!
Equal to 0 = versions are identical

      "!

      "! @raising zcx_alog_argument_null | io_version_a and io_version_b cannot be null
      compare IMPORTING io_version_a     TYPE REF TO zcl_alog_version
                        io_version_b     TYPE REF TO zcl_alog_version
              RETURNING VALUE(rv_result) TYPE i
              RAISING   zcx_alog_argument_null.
    METHODS:
      "! Compare this version to another one
      "! @parameter io_version | The version to compare this instance to
      "! @parameter rv_result | See compare
      "! @raising zcx_alog_argument_null | io_version cannot be null
      compare_to IMPORTING io_version       TYPE REF TO zcl_alog_version
                 RETURNING VALUE(rv_result) TYPE i
                 RAISING   zcx_alog_argument_null.
    CLASS-DATA:
      " These are for the currently installed version
      gv_major       TYPE i READ-ONLY,
      gv_minor       TYPE i READ-ONLY,
      gv_revision    TYPE i READ-ONLY,
      gv_is_snapshot TYPE abap_bool READ-ONLY,
      go_current     TYPE REF TO zcl_alog_version READ-ONLY.
    DATA:
      mv_version     TYPE string READ-ONLY,
      mv_major       TYPE i READ-ONLY,
      mv_minor       TYPE i READ-ONLY,
      mv_revision    TYPE i READ-ONLY,
      mv_is_snapshot TYPE abap_bool READ-ONLY.
  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      constructor IMPORTING iv_version TYPE string.
ENDCLASS.

CLASS zcl_alog_version IMPLEMENTATION.
  METHOD class_constructor.
    go_current = NEW #( gc_version ).
    gv_major = go_current->mv_major.
    gv_minor = go_current->mv_minor.
    gv_revision = go_current->mv_revision.
    gv_is_snapshot = go_current->mv_is_snapshot.
  ENDMETHOD.

  METHOD constructor.
    mv_version = iv_version.

    SPLIT mv_version AT '-' INTO TABLE DATA(lt_split1).

    IF lines( lt_split1 ) = 2.
      mv_is_snapshot = abap_true.
    ENDIF.

    SPLIT lt_split1[ 1 ] AT '.' INTO TABLE DATA(lt_split2).

    mv_major = lt_split2[ 1 ].
    mv_minor = lt_split2[ 2 ].
    mv_revision = lt_split2[ 3 ].
  ENDMETHOD.

  METHOD compare.
    DEFINE compare_attr.
      rv_result = io_version_a->&1 - io_version_b->&1.
    END-OF-DEFINITION.

    IF io_version_a IS NOT BOUND OR io_version_b IS NOT BOUND.
      RAISE EXCEPTION TYPE zcx_alog_argument_null
        EXPORTING
          iv_variable_name = 'IO_VERSION_A / IO_VERSION_B'.
    ENDIF.

    WHILE rv_result = 0.
      CASE sy-index.
        WHEN 1.
          compare_attr mv_major.
        WHEN 2.
          compare_attr mv_minor.
        WHEN 3.
          compare_attr mv_revision.
        WHEN 4.
          rv_result = COND #( WHEN io_version_a->mv_is_snapshot = io_version_b->mv_is_snapshot
                              THEN 0
                              WHEN io_version_a->mv_is_snapshot = abap_true THEN -1
                              WHEN io_version_b->mv_is_snapshot = abap_true THEN 1 ).
        WHEN OTHERS.
          EXIT.
      ENDCASE.
    ENDWHILE.
  ENDMETHOD.

  METHOD compare_to.
    rv_result = compare( io_version_a = me io_version_b = io_version ).
  ENDMETHOD.

  METHOD of.
    IF NOT matches( val = iv_version regex = `\d+\.\d+\.\d+(-.+)?` ).
      RAISE EXCEPTION TYPE zcx_alog_illegal_argument
        EXPORTING
          iv_reason = 'Version format invalid'
          iv_value  = iv_version ##NO_TEXT.
    ENDIF.

    ro_version = NEW #( iv_version ).
  ENDMETHOD.
ENDCLASS.

"! Version constants for abap-log
CLASS zcl_alog_version DEFINITION
  PUBLIC
  FINAL
  CREATE PRIVATE.

  PUBLIC SECTION.
    CONSTANTS:
      "! Version of abap-log library in major.minor.revision format
      gc_version TYPE string VALUE '0.1.0'.
    CLASS-METHODS:
      class_constructor,
      "! Factory method
      "! @parameter iv_version | Version string
      "! @parameter ro_version | Created instance
      "! @raising zcx_alog_illegal_argument | iv_version does not have the required format
      of IMPORTING iv_version        TYPE string
         RETURNING VALUE(ro_version) TYPE REF TO zcl_alog_version
         RAISING   zcx_alog_illegal_argument,
      "! Compare two version instances
      "! @parameter io_version_a | Version A
      "! @parameter io_version_b | Version B
      "! @parameter rv_result |

      "!
Less than 0 = version A is lower than version B

      "!
Greater than 0 = version A is higher than version B

      "!
Equal to 0 = versions are identical

      "!

      "! @raising zcx_alog_argument_null | io_version_a and io_version_b cannot be null
      compare IMPORTING io_version_a     TYPE REF TO zcl_alog_version
                        io_version_b     TYPE REF TO zcl_alog_version
              RETURNING VALUE(rv_result) TYPE i
              RAISING   zcx_alog_argument_null.
    METHODS:
      "! Compare this version to another one
      "! @parameter io_version | The version to compare this instance to
      "! @parameter rv_result | See compare
      "! @raising zcx_alog_argument_null | io_version cannot be null
      compare_to IMPORTING io_version       TYPE REF TO zcl_alog_version
                 RETURNING VALUE(rv_result) TYPE i
                 RAISING   zcx_alog_argument_null.
    CLASS-DATA:
      " These are for the currently installed version
      gv_major       TYPE i READ-ONLY,
      gv_minor       TYPE i READ-ONLY,
      gv_revision    TYPE i READ-ONLY,
      gv_is_snapshot TYPE abap_bool READ-ONLY,
      go_current     TYPE REF TO zcl_alog_version READ-ONLY.
    DATA:
      mv_version     TYPE string READ-ONLY,
      mv_major       TYPE i READ-ONLY,
      mv_minor       TYPE i READ-ONLY,
      mv_revision    TYPE i READ-ONLY,
      mv_is_snapshot TYPE abap_bool READ-ONLY.
  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      constructor IMPORTING iv_version TYPE string.
ENDCLASS.

CLASS zcl_alog_version IMPLEMENTATION.
  METHOD class_constructor.
    go_current = NEW #( gc_version ).
    gv_major = go_current->mv_major.
    gv_minor = go_current->mv_minor.
    gv_revision = go_current->mv_revision.
    gv_is_snapshot = go_current->mv_is_snapshot.
  ENDMETHOD.

  METHOD constructor.
    mv_version = iv_version.

    SPLIT mv_version AT '-' INTO TABLE DATA(lt_split1).

    IF lines( lt_split1 ) = 2.
      mv_is_snapshot = abap_true.
    ENDIF.

    SPLIT lt_split1[ 1 ] AT '.' INTO TABLE DATA(lt_split2).

    mv_major = lt_split2[ 1 ].
    mv_minor = lt_split2[ 2 ].
    mv_revision = lt_split2[ 3 ].
  ENDMETHOD.

  METHOD compare.
    DEFINE compare_attr.
      rv_result = io_version_a->&1 - io_version_b->&1.
    END-OF-DEFINITION.

    IF io_version_a IS NOT BOUND OR io_version_b IS NOT BOUND.
      RAISE EXCEPTION TYPE zcx_alog_argument_null
        EXPORTING
          iv_variable_name = 'IO_VERSION_A / IO_VERSION_B'.
    ENDIF.

    WHILE rv_result = 0.
      CASE sy-index.
        WHEN 1.
          compare_attr mv_major.
        WHEN 2.
          compare_attr mv_minor.
        WHEN 3.
          compare_attr mv_revision.
        WHEN 4.
          rv_result = COND #( WHEN io_version_a->mv_is_snapshot = io_version_b->mv_is_snapshot
                              THEN 0
                              WHEN io_version_a->mv_is_snapshot = abap_true THEN -1
                              WHEN io_version_b->mv_is_snapshot = abap_true THEN 1 ).
        WHEN OTHERS.
          EXIT.
      ENDCASE.
    ENDWHILE.
  ENDMETHOD.

  METHOD compare_to.
    rv_result = compare( io_version_a = me io_version_b = io_version ).
  ENDMETHOD.

  METHOD of.
    IF NOT matches( val = iv_version regex = `\d+\.\d+\.\d+(-.+)?` ).
      RAISE EXCEPTION TYPE zcx_alog_illegal_argument
        EXPORTING
          iv_reason = 'Version format invalid'
          iv_value  = iv_version ##NO_TEXT.
    ENDIF.

    ro_version = NEW #( iv_version ).
  ENDMETHOD.
ENDCLASS.

Prepare for v0.1.0

Prepare for v0.1.0


class ZCL_WABAP_SERVICE definition
  public
  create public .

public section.

  interfaces IF_HTTP_EXTENSION .

  constants GC_URL type STRING value '/SAP/zwabap' ##NO_TEXT.
protected section.

  types:
    BEGIN OF ty_tadir,
      pgmid      TYPE tadir-pgmid,
      object     TYPE tadir-object,
      obj_name   TYPE tadir-obj_name,
      srcsystem  TYPE tadir-srcsystem,
      author     TYPE tadir-author,
      devclass   TYPE tadir-devclass,
      masterlang TYPE tadir-masterlang,
      delflag    TYPE tadir-delflag,
    END OF ty_tadir .
  types:
    ty_tadir_tt TYPE STANDARD TABLE OF ty_tadir WITH DEFAULT KEY .
  types:
    BEGIN OF ty_report,
      progdir type PROGDIR,
      source TYPE STANDARD TABLE OF abaptxt255 WITH DEFAULT KEY,
    END OF ty_report .

  methods READ_REPORT
    importing
      !IV_NAME type PROGNAME
    returning
      value(RS_REPORT) type TY_REPORT .
  methods READ_TADIR
    returning
      value(RT_DATA) type TY_TADIR_TT .
  methods TO_JSON
    importing
      !IG_DATA type ANY
    returning
      value(RV_JSON) type XSTRING .
  methods READ_MIME
    importing
      !IV_FILE type STRING
    returning
      value(RV_DATA) type XSTRING .
private section.
ENDCLASS.

CLASS ZCL_WABAP_SERVICE IMPLEMENTATION.

METHOD if_http_extension~handle_request.

* root = main entry, serve bundle.js and index.html
*        also see comment in method READ_MIME

* /rest/ = rest services

*    DATA: lt_fields TYPE tihttpnvp,
*          lv_html   TYPE string.
*    FIELD-SYMBOLS: <ls_fields> LIKE LINE OF lt_fields.
*    server->request->get_header_fields( CHANGING fields = lt_fields ).
*    LOOP AT lt_fields ASSIGNING <ls_fields>.
*      lv_html = lv_html && <ls_fields>-name && '=' && <ls_fields>-value && '<br>'.
*    ENDLOOP.
*    server->response->set_cdata( lv_html ).

  DATA: lv_reason TYPE string,
        lv_path   TYPE string.

  lv_path = server->request->get_header_field( '~path_info' ).

  IF lv_path CP '/rest/tadir*'.
    DATA(lt_tadir) = read_tadir( ).
    server->response->set_data( to_json( lt_tadir ) ).
  ELSEIF lv_path CP '/rest/reports/*'.
    DATA(ls_report) = read_report( CONV #( lv_path+14 ) ).
    server->response->set_data( to_json( ls_report ) ).
  ELSEIF lv_path = '' OR lv_path = '/'.
    server->response->set_data( read_mime( '/index.html' ) ).
  ELSE.
    server->response->set_data( read_mime( lv_path ) ).
  ENDIF.

  server->response->set_status( code = 200
                                reason = lv_reason ).

ENDMETHOD.

METHOD read_mime.

* todo, does this work with browser caching?
* or use something more standard instead?

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

  lv_url = gc_url && iv_file.

  li_api = cl_mime_repository_api=>if_mr_api~get_api( ).

  li_api->get(
    EXPORTING
      i_url = lv_url
    IMPORTING
      e_content = rv_data ).

ENDMETHOD.

METHOD read_report.

* todo, security? escape some stuff?

  DATA(lv_program) = CONV progname( to_upper( iv_name ) ).

  CALL FUNCTION 'RPY_PROGRAM_READ'
    EXPORTING
      program_name     = lv_program
      with_lowercase   = abap_true
    TABLES
      source_extended  = rs_report-source
    EXCEPTIONS
      cancelled        = 1
      not_found        = 2
      permission_error = 3
      OTHERS           = 4.
  ASSERT sy-subrc = 0. " todo, error handling

  CALL FUNCTION 'READ_PROGDIR'
    EXPORTING
      i_progname = lv_program
      i_state    = 'A'   " todo, possibility to handle inactive state
    IMPORTING
      e_progdir  = rs_report-progdir.

ENDMETHOD.

METHOD read_tadir.

  SELECT * FROM tadir
    INTO CORRESPONDING FIELDS OF TABLE rt_data
    WHERE devclass = '$TMP'
    AND author <> 'SAP'
    AND author <> 'DDIC'
    AND obj_name LIKE 'Z%'
    ORDER BY PRIMARY KEY.

ENDMETHOD.

METHOD to_json.

  DATA: lo_writer TYPE REF TO cl_sxml_string_writer.

  lo_writer = cl_sxml_string_writer=>create( if_sxml=>co_xt_json ).
  CALL TRANSFORMATION id
    SOURCE data = ig_data
    RESULT XML lo_writer.
  rv_json = lo_writer->get_output( ).

ENDMETHOD.
ENDCLASS.

CLASS zcl_wabap_service DEFINITION
  PUBLIC
  CREATE PUBLIC.

  PUBLIC SECTION.

    INTERFACES if_http_extension.

    CONSTANTS cv_url TYPE string VALUE '/SAP/zwabap' ##NO_TEXT.

  PROTECTED SECTION.

    TYPES:
      BEGIN OF ty_tadir,
        pgmid      TYPE tadir-pgmid,
        object     TYPE tadir-object,
        obj_name   TYPE tadir-obj_name,
        srcsystem  TYPE tadir-srcsystem,
        author     TYPE tadir-author,
        devclass   TYPE tadir-devclass,
        masterlang TYPE tadir-masterlang,
        delflag    TYPE tadir-delflag,
      END OF ty_tadir.
    TYPES:
      ty_tadir_tt TYPE STANDARD TABLE OF ty_tadir WITH DEFAULT KEY.

    TYPES:
      BEGIN OF ty_report,
        progdir TYPE progdir,
        source  TYPE STANDARD TABLE OF abaptxt255 WITH DEFAULT KEY,
      END OF ty_report.

    METHODS read_report
      IMPORTING
        !iv_name         TYPE progname
      RETURNING
        VALUE(rs_report) TYPE ty_report.
    METHODS read_tadir
      RETURNING
        VALUE(rt_data) TYPE ty_tadir_tt.
    METHODS to_json
      IMPORTING
        !ig_data       TYPE any
      RETURNING
        VALUE(rv_json) TYPE xstring.
    METHODS read_mime
      IMPORTING
        !iv_file       TYPE string
      RETURNING
        VALUE(rv_data) TYPE xstring.

ENDCLASS.

CLASS ZCL_WABAP_SERVICE IMPLEMENTATION.

  METHOD if_http_extension~handle_request.

* root = main entry, serve bundle.js and index.html
*        also see comment in method READ_MIME

* /rest/ = rest services

*    DATA: lt_fields TYPE tihttpnvp,
*          lv_html   TYPE string.
*    FIELD-SYMBOLS: <ls_fields> LIKE LINE OF lt_fields.
*    server->request->get_header_fields( CHANGING fields = lt_fields ).
*    LOOP AT lt_fields ASSIGNING <ls_fields>.
*      lv_html = lv_html && <ls_fields>-name && '=' && <ls_fields>-value && '<br>'.
*    ENDLOOP.
*    server->response->set_cdata( lv_html ).

    DATA: lv_reason TYPE string,
          lv_path   TYPE string.

    lv_path = server->request->get_header_field( '~path_info' ).

    IF lv_path CP '/rest/tadir*'.
      DATA(lt_tadir) = read_tadir( ).
      server->response->set_data( to_json( lt_tadir ) ).
    ELSEIF lv_path CP '/rest/reports/*'.
      DATA(ls_report) = read_report( CONV #( lv_path+14 ) ).
      server->response->set_data( to_json( ls_report ) ).
    ELSEIF lv_path = '' OR lv_path = '/'.
      server->response->set_data( read_mime( '/index.html' ) ).
    ELSE.
      server->response->set_data( read_mime( lv_path ) ).
    ENDIF.

    server->response->set_status( code = 200
                                  reason = lv_reason ).

  ENDMETHOD.

  METHOD read_mime.

* todo, does this work with browser caching?
* or use something more standard instead?

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

    lv_url = cv_url && iv_file.

    li_api = cl_mime_repository_api=>if_mr_api~get_api( ).

    li_api->get(
      EXPORTING
        i_url = lv_url
      IMPORTING
        e_content = rv_data ).

  ENDMETHOD.

  METHOD read_report.

* todo, security? escape some stuff?

    DATA(lv_program) = CONV progname( to_upper( iv_name ) ).

    CALL FUNCTION 'RPY_PROGRAM_READ'
      EXPORTING
        program_name     = lv_program
        with_lowercase   = abap_true
      TABLES
        source_extended  = rs_report-source
      EXCEPTIONS
        cancelled        = 1
        not_found        = 2
        permission_error = 3
        OTHERS           = 4.
    ASSERT sy-subrc = 0. " todo, error handling

    CALL FUNCTION 'READ_PROGDIR'
      EXPORTING
        i_progname = lv_program
        i_state    = 'A'   " todo, possibility to handle inactive state
      IMPORTING
        e_progdir  = rs_report-progdir.

  ENDMETHOD.

  METHOD read_tadir.

    SELECT * FROM tadir
      INTO CORRESPONDING FIELDS OF TABLE rt_data
      WHERE devclass = '$TMP'
      AND author <> 'SAP'
      AND author <> 'DDIC'
      AND obj_name LIKE 'Z%'
      ORDER BY PRIMARY KEY.                             "#EC CI_GENBUFF

  ENDMETHOD.

  METHOD to_json.

    DATA: lo_writer TYPE REF TO cl_sxml_string_writer.

    lo_writer = cl_sxml_string_writer=>create( if_sxml=>co_xt_json ).
    CALL TRANSFORMATION id
      SOURCE data = ig_data
      RESULT XML lo_writer.
    rv_json = lo_writer->get_output( ).

  ENDMETHOD.
ENDCLASS.

clean up

clean up


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.
    TRY.
        CREATE OBJECT mo_cut.
      CATCH zcx_abapgit_exception.
        cl_abap_unit_assert=>fail( 'Error creating serializer' ).
    ENDTRY.
  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.
    TRY.
        CREATE OBJECT mo_cut.
      CATCH zcx_abapgit_exception.
        cl_abap_unit_assert=>fail( 'Error creating serializer' ).
    ENDTRY.
  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.

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

  PRIVATE SECTION.
    DATA:
      mo_dot_abapgit TYPE REF TO zcl_abapgit_dot_abapgit,
      mo_cut         TYPE REF TO zcl_abapgit_serialize.

    METHODS:
      setup,
      test FOR TESTING RAISING zcx_abapgit_exception.

ENDCLASS.

CLASS ltcl_i18n IMPLEMENTATION.

  METHOD setup.
    DATA ls_data TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit.

    " Main language: English, Translations: German
    ls_data-master_language = 'E'.
    INSERT 'DE' INTO TABLE ls_data-i18n_languages.

    TRY.
        CREATE OBJECT mo_dot_abapgit
          EXPORTING
            is_data = ls_data.

        CREATE OBJECT mo_cut
          EXPORTING
            io_dot_abapgit = mo_dot_abapgit.
      CATCH zcx_abapgit_exception.
        cl_abap_unit_assert=>fail( 'Error creating serializer' ).
    ENDTRY.
  ENDMETHOD.

  METHOD test.

    DATA: lt_tadir      TYPE zif_abapgit_definitions=>ty_tadir_tt,
          lt_result     TYPE zif_abapgit_definitions=>ty_files_item_tt,
          lv_xml        TYPE string,
          lo_input      TYPE REF TO zcl_abapgit_xml_input,
          ls_dd02v      TYPE dd02v,
          lt_i18n_langs TYPE TABLE OF langu.

    FIELD-SYMBOLS: <ls_tadir>      LIKE LINE OF lt_tadir,
                   <ls_result>     LIKE LINE OF lt_result,
                   <ls_i18n_langs> LIKE LINE OF lt_i18n_langs.

    " Assumption: Table T100 has English and German description
    APPEND INITIAL LINE TO lt_tadir ASSIGNING <ls_tadir>.
    <ls_tadir>-object   = 'TABL'.
    <ls_tadir>-obj_name = 'T100'.
    <ls_tadir>-devclass = 'PACKAGE'.
    <ls_tadir>-path     = 'foobar'.

    lt_result = mo_cut->serialize( lt_tadir ).

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

    READ TABLE lt_result ASSIGNING <ls_result> INDEX 1.
    ASSERT sy-subrc = 0.

    lv_xml = zcl_abapgit_convert=>xstring_to_string_utf8( <ls_result>-file-data ).

    CREATE OBJECT lo_input
      EXPORTING
        iv_xml = lv_xml.

    lo_input->zif_abapgit_xml_input~read( EXPORTING iv_name = 'DD02V'
                                          CHANGING  cg_data = ls_dd02v ).

    cl_abap_unit_assert=>assert_equals(
      act = ls_dd02v-ddlanguage
      exp = 'E' ).

    lo_input->zif_abapgit_xml_input~read( EXPORTING iv_name = 'I18N_LANGS'
                                          CHANGING  cg_data = lt_i18n_langs ).

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

    READ TABLE lt_i18n_langs ASSIGNING <ls_i18n_langs> INDEX 1.
    ASSERT sy-subrc = 0.

    cl_abap_unit_assert=>assert_equals(
      act = <ls_i18n_langs>
      exp = 'D' ).

  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.
    TRY.
        CREATE OBJECT mo_cut.
      CATCH zcx_abapgit_exception.
        cl_abap_unit_assert=>fail( 'Error creating serializer' ).
    ENDTRY.
  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.
    TRY.
        CREATE OBJECT mo_cut.
      CATCH zcx_abapgit_exception.
        cl_abap_unit_assert=>fail( 'Error creating serializer' ).
    ENDTRY.
  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,
          ls_msg   TYPE zif_abapgit_log=>ty_log_out,
          lt_msg   TYPE zif_abapgit_log=>ty_log_outs,
          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 ).

    lt_msg = li_log1->get_messages( ).
    READ TABLE lt_msg INTO ls_msg INDEX 1.
    cl_abap_unit_assert=>assert_subrc( ).

    cl_abap_unit_assert=>assert_char_cp(
      act = ls_msg-text
      exp = '*Object type ABCD not supported*' ).

    lt_msg = li_log2->get_messages( ).
    READ TABLE lt_msg INTO ls_msg INDEX 1.
    cl_abap_unit_assert=>assert_subrc( ).

    cl_abap_unit_assert=>assert_char_cp(
      act = ls_msg-text
      exp = '*Object type ABCD not supported*' ).

  ENDMETHOD.

ENDCLASS.

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

  PRIVATE SECTION.
    DATA:
      mo_dot_abapgit TYPE REF TO zcl_abapgit_dot_abapgit,
      mo_cut         TYPE REF TO zcl_abapgit_serialize.

    METHODS:
      setup,
      test FOR TESTING RAISING zcx_abapgit_exception.

ENDCLASS.

CLASS ltcl_i18n IMPLEMENTATION.

  METHOD setup.
    DATA ls_data TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit.

    " Main language: English, Translations: German
    ls_data-master_language = 'E'.
    INSERT 'DE' INTO TABLE ls_data-i18n_languages.

    TRY.
        CREATE OBJECT mo_dot_abapgit
          EXPORTING
            is_data = ls_data.

        CREATE OBJECT mo_cut
          EXPORTING
            io_dot_abapgit = mo_dot_abapgit.
      CATCH zcx_abapgit_exception.
        cl_abap_unit_assert=>fail( 'Error creating serializer' ).
    ENDTRY.
  ENDMETHOD.

  METHOD test.

    DATA: lt_tadir      TYPE zif_abapgit_definitions=>ty_tadir_tt,
          lt_result     TYPE zif_abapgit_definitions=>ty_files_item_tt,
          lv_xml        TYPE string,
          lo_input      TYPE REF TO zcl_abapgit_xml_input,
          ls_dd02v      TYPE dd02v,
          lt_i18n_langs TYPE TABLE OF langu.

    FIELD-SYMBOLS: <ls_tadir>      LIKE LINE OF lt_tadir,
                   <ls_result>     LIKE LINE OF lt_result,
                   <ls_i18n_langs> LIKE LINE OF lt_i18n_langs.

    " Assumption: Table T100 has English and German description
    APPEND INITIAL LINE TO lt_tadir ASSIGNING <ls_tadir>.
    <ls_tadir>-object   = 'TABL'.
    <ls_tadir>-obj_name = 'T100'.
    <ls_tadir>-devclass = 'PACKAGE'.
    <ls_tadir>-path     = 'foobar'.

    lt_result = mo_cut->serialize( lt_tadir ).

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

    READ TABLE lt_result ASSIGNING <ls_result> INDEX 1.
    ASSERT sy-subrc = 0.

    lv_xml = zcl_abapgit_convert=>xstring_to_string_utf8( <ls_result>-file-data ).

    CREATE OBJECT lo_input
      EXPORTING
        iv_xml = lv_xml.

    lo_input->zif_abapgit_xml_input~read( EXPORTING iv_name = 'DD02V'
                                          CHANGING  cg_data = ls_dd02v ).

    cl_abap_unit_assert=>assert_equals(
      act = ls_dd02v-ddlanguage
      exp = 'E' ).

    lo_input->zif_abapgit_xml_input~read( EXPORTING iv_name = 'I18N_LANGS'
                                          CHANGING  cg_data = lt_i18n_langs ).

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

    READ TABLE lt_i18n_langs ASSIGNING <ls_i18n_langs> INDEX 1.
    ASSERT sy-subrc = 0.

    cl_abap_unit_assert=>assert_equals(
      act = <ls_i18n_langs>
      exp = 'D' ).

  ENDMETHOD.
ENDCLASS.

Remove UI dependency from test (#5298)

Remove UI dependency from test (#5298)


*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_OBJECT_SERIALIZATION
*&---------------------------------------------------------------------*

* All object serializing classes

INCLUDE zabapgit_object_acid.
INCLUDE zabapgit_object_auth.
INCLUDE zabapgit_object_oo_functions.
INCLUDE zabapgit_object_clas.
INCLUDE zabapgit_object_ddls.
INCLUDE zabapgit_object_doct.
INCLUDE zabapgit_object_docv.
INCLUDE zabapgit_object_doma.
INCLUDE zabapgit_object_dtel.
INCLUDE zabapgit_object_enho.
INCLUDE zabapgit_object_enhs.
INCLUDE zabapgit_object_enqu.
INCLUDE zabapgit_object_ensc.
INCLUDE zabapgit_object_fugr.
INCLUDE zabapgit_object_iarp.
INCLUDE zabapgit_object_iasp.
INCLUDE zabapgit_object_iatu.
INCLUDE zabapgit_object_intf.
INCLUDE zabapgit_object_msag.
INCLUDE zabapgit_object_nrob.
INCLUDE zabapgit_object_para.
INCLUDE zabapgit_object_pinf.
INCLUDE zabapgit_object_prog.
INCLUDE zabapgit_object_samc.
INCLUDE zabapgit_object_sapc.
INCLUDE zabapgit_object_sfbf.
INCLUDE zabapgit_object_sfbs.
INCLUDE zabapgit_object_sfpf.
INCLUDE zabapgit_object_sfpi.
INCLUDE zabapgit_object_sfsw.
INCLUDE zabapgit_object_shi3.
INCLUDE zabapgit_object_shlp.
INCLUDE zabapgit_object_sicf.
INCLUDE zabapgit_object_smim.
INCLUDE zabapgit_object_splo.
INCLUDE zabapgit_object_ssfo.
INCLUDE zabapgit_object_ssst.
INCLUDE zabapgit_object_susc.
INCLUDE zabapgit_object_suso.
INCLUDE zabapgit_object_tabl_valid.
INCLUDE zabapgit_object_tabl.
INCLUDE zabapgit_object_tobj.
INCLUDE zabapgit_object_tran.
INCLUDE zabapgit_object_ttyp.
INCLUDE zabapgit_object_type.
INCLUDE zabapgit_object_vcls.
INCLUDE zabapgit_object_view.
INCLUDE zabapgit_object_w3xx.
INCLUDE zabapgit_object_wapa.
INCLUDE zabapgit_object_wdya.
INCLUDE zabapgit_object_wdyn.
INCLUDE zabapgit_object_webi.
INCLUDE zabapgit_object_xslt.
INCLUDE zabapgit_object_oo_factory.

*&---------------------------------------------------------------------*
*&  Include           ZABAPGIT_OBJECT_SERIALIZATION
*&---------------------------------------------------------------------*

* All object serializing classes

INCLUDE zabapgit_object_acid.
INCLUDE zabapgit_object_auth.
INCLUDE zabapgit_object_oo_functions.
INCLUDE zabapgit_object_clas.
INCLUDE zabapgit_object_ddls.
INCLUDE zabapgit_object_doct.
INCLUDE zabapgit_object_docv.
INCLUDE zabapgit_object_doma.
INCLUDE zabapgit_object_dtel.
INCLUDE zabapgit_object_enho.
INCLUDE zabapgit_object_enhs.
INCLUDE zabapgit_object_enqu.
INCLUDE zabapgit_object_ensc.
INCLUDE zabapgit_object_fugr.
INCLUDE zabapgit_object_iarp.
INCLUDE zabapgit_object_iasp.
INCLUDE zabapgit_object_iatu.
INCLUDE zabapgit_object_intf.
INCLUDE zabapgit_object_msag.
INCLUDE zabapgit_object_nrob.
INCLUDE zabapgit_object_para.
INCLUDE zabapgit_object_pinf.
INCLUDE zabapgit_object_prog.
INCLUDE zabapgit_object_sfbf.
INCLUDE zabapgit_object_sfbs.
INCLUDE zabapgit_object_sfpf.
INCLUDE zabapgit_object_sfpi.
INCLUDE zabapgit_object_sfsw.
INCLUDE zabapgit_object_shi3.
INCLUDE zabapgit_object_shlp.
INCLUDE zabapgit_object_sicf.
INCLUDE zabapgit_object_smim.
INCLUDE zabapgit_object_splo.
INCLUDE zabapgit_object_ssfo.
INCLUDE zabapgit_object_ssst.
INCLUDE zabapgit_object_susc.
INCLUDE zabapgit_object_suso.
INCLUDE zabapgit_object_tabl_valid.
INCLUDE zabapgit_object_tabl.
INCLUDE zabapgit_object_tobj.
INCLUDE zabapgit_object_tran.
INCLUDE zabapgit_object_ttyp.
INCLUDE zabapgit_object_type.
INCLUDE zabapgit_object_vcls.
INCLUDE zabapgit_object_view.
INCLUDE zabapgit_object_w3xx.
INCLUDE zabapgit_object_wapa.
INCLUDE zabapgit_object_wdya.
INCLUDE zabapgit_object_wdyn.
INCLUDE zabapgit_object_webi.
INCLUDE zabapgit_object_xslt.
INCLUDE zabapgit_object_oo_factory.

undo some changes

undo some changes


"! Logger base class
class ZCL_ALOG_LOGGER_BASE definition
  public
  abstract
  create public .

public section.

  interfaces ZIF_ALOG_LOGGER
      abstract methods ENTRY .

  aliases DEBUG
    for ZIF_ALOG_LOGGER~DEBUG .
  aliases ENTRY
    for ZIF_ALOG_LOGGER~ENTRY .
  aliases ERROR
    for ZIF_ALOG_LOGGER~ERROR .
  aliases EXCEPTION
    for ZIF_ALOG_LOGGER~EXCEPTION .
  aliases INFO
    for ZIF_ALOG_LOGGER~INFO .
  aliases WARNING
    for ZIF_ALOG_LOGGER~WARNING .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS ZCL_ALOG_LOGGER_BASE IMPLEMENTATION.

  METHOD zif_alog_logger~debug.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_debug ).
  ENDMETHOD.

  METHOD zif_alog_logger~error.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_error ).
  ENDMETHOD.

  METHOD zif_alog_logger~exception.
    entry( iv_text = ix_ex->get_text( ) io_type = zcl_alog_entry_type=>go_debug ).
  ENDMETHOD.

  METHOD zif_alog_logger~info.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_info ).
  ENDMETHOD.

  METHOD zif_alog_logger~warning.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_warning ).
  ENDMETHOD.
ENDCLASS.

"! Logger base class
CLASS zcl_alog_logger_base DEFINITION
  PUBLIC
  ABSTRACT
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES:
      zif_alog_logger ABSTRACT METHODS entry.
    ALIASES:
      debug FOR zif_alog_logger~debug,
      entry FOR zif_alog_logger~entry,
      error FOR zif_alog_logger~error,
      exception FOR zif_alog_logger~exception,
      info FOR zif_alog_logger~info,
      warning FOR zif_alog_logger~warning.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_alog_logger_base IMPLEMENTATION.
  METHOD zif_alog_logger~debug.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_debug ).
  ENDMETHOD.

  METHOD zif_alog_logger~error.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_error ).
  ENDMETHOD.

  METHOD zif_alog_logger~exception.
    entry( iv_text = ix_ex->get_text( ) io_type = zcl_alog_entry_type=>go_debug ).
  ENDMETHOD.

  METHOD zif_alog_logger~info.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_info ).
  ENDMETHOD.

  METHOD zif_alog_logger~warning.
    entry( iv_text = iv_text io_type = zcl_alog_entry_type=>go_warning ).
  ENDMETHOD.
ENDCLASS.

Fix class builder generated formatting

Fix class builder generated formatting


CLASS zcl_abapgit_object_chdo DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_objects_super
  FINAL
  CREATE PUBLIC .

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

    METHODS constructor
      IMPORTING
        is_item     TYPE zif_abapgit_definitions=>ty_item
        iv_language TYPE spras.

  PROTECTED SECTION.

    METHODS after_import
      RAISING
        zcx_abapgit_exception .
    METHODS delete_tadir_cdnames
      IMPORTING
        !is_cdnames TYPE cdnames
      RAISING
        zcx_abapgit_exception .
    METHODS delete_tadir_tabl
      IMPORTING
        !is_tcdrs TYPE tcdrs
      RAISING
        zcx_abapgit_exception .
  PRIVATE SECTION.
    TYPES: BEGIN OF ty_change_document,
             reports_generated TYPE SORTED TABLE OF tcdrps WITH UNIQUE KEY object reportname,
             objects           TYPE SORTED TABLE OF tcdobs WITH UNIQUE KEY object tabname,
             objects_text      TYPE SORTED TABLE OF tcdobts WITH UNIQUE KEY spras object,
           END OF ty_change_document.

    DATA: mv_object TYPE cdobjectcl.

ENDCLASS.

CLASS zcl_abapgit_object_chdo IMPLEMENTATION.

  METHOD after_import.

    DATA: lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY,
          ls_cts_object_entry LIKE LINE OF lt_cts_object_entry,
          lt_errormsg         TYPE STANDARD TABLE OF sprot_u WITH DEFAULT KEY.

    ls_cts_object_entry-pgmid    = seok_pgmid_r3tr.
    ls_cts_object_entry-object   = ms_item-obj_type.
    ls_cts_object_entry-obj_name = ms_item-obj_name.
    INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry.

    CALL FUNCTION 'AFTER_IMP_CHDO'
      EXPORTING
        iv_tarclient  = sy-mandt
        iv_is_upgrade = abap_false
      TABLES
        tt_e071       = lt_cts_object_entry
        tt_errormsg   = lt_errormsg.

    LOOP AT lt_errormsg TRANSPORTING NO FIELDS WHERE severity = 'E' OR severity = 'A'.
      EXIT.
    ENDLOOP.

    IF sy-subrc = 0.
      zcx_abapgit_exception=>raise( 'Error from AFTER_IMP_CHDO' ).
    ENDIF.

  ENDMETHOD.

  METHOD constructor.

    super->constructor( is_item     = is_item
                        iv_language = iv_language ).

    mv_object = is_item-obj_name.

  ENDMETHOD.

  METHOD delete_tadir_cdnames.

    DATA: lv_obj_name TYPE sobj_name.

    IF is_cdnames-repnamec IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamec.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-repnamet IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamet.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-repnamefix IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamefix.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-repnamevar IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamevar.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-fgrp IS NOT INITIAL.
      lv_obj_name = is_cdnames-fgrp.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'FUGR'
          wi_tadir_obj_name        = lv_obj_name
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

  ENDMETHOD.

  METHOD delete_tadir_tabl.

    DATA: lv_obj_name TYPE sobj_name.

    IF is_tcdrs-tabname IS NOT INITIAL.
      lv_obj_name = is_tcdrs-tabname.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'FUGR'
          wi_tadir_obj_name        = lv_obj_name
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise( |Error from TR_TADIR_INTERFACE (subrc={ sy-subrc } ).| ).
      ENDIF.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    SELECT SINGLE updname INTO rv_user
      FROM tcdrp
      WHERE object = mv_object.
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lt_cdnames TYPE STANDARD TABLE OF cdnames,
          ls_cdnames TYPE cdnames,
          lt_tcdrs   TYPE STANDARD TABLE OF tcdrs,
          ls_tcdrs   TYPE tcdrs,
          lv_msg     TYPE symsgv.

    CALL FUNCTION 'CDNAMES_GET'
      EXPORTING
        iv_object        = mv_object
      TABLES
        it_tcdrs         = lt_tcdrs
        it_names         = lt_cdnames
      EXCEPTIONS
        object_space     = 1
        object_not_found = 2
        OTHERS           = 3.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    CALL FUNCTION 'CHDO_DELETE'
      EXPORTING
        iv_object        = mv_object
        iv_with_tadir    = abap_true
      EXCEPTIONS
        object_is_space  = 1
        object_not_found = 2
        other_error      = 3
        OTHERS           = 4.
    IF sy-subrc <> 0.
      lv_msg = mv_object.
      zcx_abapgit_exception=>raise_t100( iv_msgid = 'CD'
                                         iv_msgno = '869'
                                         iv_msgv1 = lv_msg ).
    ENDIF.

    LOOP AT lt_cdnames INTO ls_cdnames.
      delete_tadir_cdnames( ls_cdnames ).
    ENDLOOP.

    LOOP AT lt_tcdrs INTO ls_tcdrs.
      delete_tadir_tabl( ls_tcdrs ).
    ENDLOOP.

    corr_insert( iv_package ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: ls_change_object TYPE ty_change_document.
    FIELD-SYMBOLS: <ls_report_generated> LIKE LINE OF ls_change_object-reports_generated.

    io_xml->read( EXPORTING iv_name = 'CHDO'
                  CHANGING  cg_data = ls_change_object ).

    DELETE FROM tcdobs  WHERE object = mv_object.
    DELETE FROM tcdobts WHERE object = mv_object.
    DELETE FROM tcdrps  WHERE object = mv_object.

    LOOP AT ls_change_object-reports_generated ASSIGNING <ls_report_generated>.
      <ls_report_generated>-devclass = iv_package.
    ENDLOOP.

    INSERT tcdobs  FROM TABLE ls_change_object-objects.
    INSERT tcdobts FROM TABLE ls_change_object-objects_text.
    INSERT tcdrps  FROM TABLE ls_change_object-reports_generated.

    tadir_insert( iv_package ).

    after_import( ).

    corr_insert( iv_package ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    SELECT COUNT(*)
      FROM tcdrp
      WHERE object = mv_object.

    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    RETURN.
  ENDMETHOD.

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

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

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

  METHOD zif_abapgit_object~is_locked.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    DATA: lt_bdcdata TYPE STANDARD TABLE OF bdcdata,
          ls_bdcdata LIKE LINE OF lt_bdcdata.

    CLEAR: ls_bdcdata.
    ls_bdcdata-program  = 'SAPMSCDO_NEW'.
    ls_bdcdata-dynpro   = '0100'.
    ls_bdcdata-dynbegin = abap_true.
    APPEND ls_bdcdata TO lt_bdcdata.

    CLEAR: ls_bdcdata.
    ls_bdcdata-fnam = 'TCDOB-OBJECT'.
    ls_bdcdata-fval = mv_object.
    APPEND ls_bdcdata TO lt_bdcdata.

    CLEAR: ls_bdcdata.
    ls_bdcdata-fnam = 'BDC_OKCODE'.
    ls_bdcdata-fval = '=DISP'.
    APPEND ls_bdcdata TO lt_bdcdata.

    zcl_abapgit_ui_factory=>get_gui_jumper( )->jump_batch_input(
      iv_tcode   = 'SCDO'
      it_bdcdata = lt_bdcdata ).

    rv_exit = abap_true.

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: ls_change_object TYPE ty_change_document,
          lt_tcdrp         TYPE STANDARD TABLE OF tcdrp,
          lt_tcdob         TYPE STANDARD TABLE OF tcdob,
          lt_tcdobt        TYPE STANDARD TABLE OF tcdobt,
          BEGIN OF ls_nulldatetime, " hack ro reset fields when they exist without syntax errors when they don't
            udate TYPE sy-datum,
            utime TYPE sy-uzeit,
          END OF ls_nulldatetime.

    FIELD-SYMBOLS: <ls_reports_generated> LIKE LINE OF ls_change_object-reports_generated,
                   <ls_objects>           LIKE LINE OF ls_change_object-objects,
                   <ls_objects_text>      LIKE LINE OF ls_change_object-objects_text.

    CALL FUNCTION 'CDNAMES_GET'
      EXPORTING
        iv_object        = mv_object
      TABLES
        it_tcdrp         = lt_tcdrp
        it_tcdob         = lt_tcdob
        it_tcdobt        = lt_tcdobt
      EXCEPTIONS
        object_space     = 1
        object_not_found = 2
        OTHERS           = 3.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    ls_change_object-reports_generated = lt_tcdrp.
    ls_change_object-objects           = lt_tcdob.
    ls_change_object-objects_text      = lt_tcdobt.

    " At import, when CHDO is generated date & time change, so always detects changes for this fields
    LOOP AT ls_change_object-reports_generated ASSIGNING <ls_reports_generated>.
      CLEAR: <ls_reports_generated>-datum, <ls_reports_generated>-uzeit,
             <ls_reports_generated>-author, <ls_reports_generated>-updname,
             <ls_reports_generated>-devclass.
    ENDLOOP.

    LOOP AT ls_change_object-objects ASSIGNING <ls_objects>.
      MOVE-CORRESPONDING ls_nulldatetime TO <ls_objects>. " reset date and time
    ENDLOOP.

    LOOP AT ls_change_object-objects_text ASSIGNING <ls_objects_text>.
      MOVE-CORRESPONDING ls_nulldatetime TO <ls_objects_text>. " reset date and time
    ENDLOOP.

    io_xml->add( iv_name = 'CHDO'
                 ig_data = ls_change_object ).

  ENDMETHOD.
ENDCLASS.

CLASS zcl_abapgit_object_chdo DEFINITION
  PUBLIC
  INHERITING FROM zcl_abapgit_objects_super
  FINAL
  CREATE PUBLIC .

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

    METHODS constructor
      IMPORTING
        is_item     TYPE zif_abapgit_definitions=>ty_item
        iv_language TYPE spras.

  PROTECTED SECTION.

    METHODS after_import
      RAISING
        zcx_abapgit_exception .
    METHODS delete_tadir_cdnames
      IMPORTING
        !is_cdnames TYPE cdnames
      RAISING
        zcx_abapgit_exception .
    METHODS delete_tadir_tabl
      IMPORTING
        !is_tcdrs TYPE tcdrs
      RAISING
        zcx_abapgit_exception .
  PRIVATE SECTION.
    TYPES: BEGIN OF ty_change_document,
             reports_generated TYPE SORTED TABLE OF tcdrps WITH UNIQUE KEY object reportname,
             objects           TYPE SORTED TABLE OF tcdobs WITH UNIQUE KEY object tabname,
             objects_text      TYPE SORTED TABLE OF tcdobts WITH UNIQUE KEY spras object,
           END OF ty_change_document.

    DATA: mv_object TYPE cdobjectcl.

ENDCLASS.

CLASS zcl_abapgit_object_chdo IMPLEMENTATION.

  METHOD after_import.

    DATA: lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY,
          ls_cts_object_entry LIKE LINE OF lt_cts_object_entry,
          lt_errormsg         TYPE STANDARD TABLE OF sprot_u WITH DEFAULT KEY.

    ls_cts_object_entry-pgmid    = seok_pgmid_r3tr.
    ls_cts_object_entry-object   = ms_item-obj_type.
    ls_cts_object_entry-obj_name = ms_item-obj_name.
    INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry.

    CALL FUNCTION 'AFTER_IMP_CHDO'
      EXPORTING
        iv_tarclient  = sy-mandt
        iv_is_upgrade = abap_false
      TABLES
        tt_e071       = lt_cts_object_entry
        tt_errormsg   = lt_errormsg.

    LOOP AT lt_errormsg TRANSPORTING NO FIELDS WHERE severity = 'E' OR severity = 'A'.
      EXIT.
    ENDLOOP.

    IF sy-subrc = 0.
      zcx_abapgit_exception=>raise( 'Error from AFTER_IMP_CHDO' ).
    ENDIF.

  ENDMETHOD.

  METHOD constructor.

    super->constructor( is_item     = is_item
                        iv_language = iv_language ).

    mv_object = is_item-obj_name.

  ENDMETHOD.

  METHOD delete_tadir_cdnames.

    DATA: lv_obj_name TYPE sobj_name.

    IF is_cdnames-repnamec IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamec.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
          wi_test_modus            = abap_false
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-repnamet IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamet.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
          wi_test_modus            = abap_false
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-repnamefix IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamefix.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
          wi_test_modus            = abap_false
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-repnamevar IS NOT INITIAL.
      lv_obj_name = is_cdnames-repnamevar.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'PROG'
          wi_tadir_obj_name        = lv_obj_name
          wi_test_modus            = abap_false
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

    IF is_cdnames-fgrp IS NOT INITIAL.
      lv_obj_name = is_cdnames-fgrp.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'FUGR'
          wi_tadir_obj_name        = lv_obj_name
          wi_test_modus            = abap_false
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise_t100( ).
      ENDIF.
    ENDIF.

  ENDMETHOD.

  METHOD delete_tadir_tabl.

    DATA: lv_obj_name TYPE sobj_name.

    IF is_tcdrs-tabname IS NOT INITIAL.
      lv_obj_name = is_tcdrs-tabname.
      CALL FUNCTION 'TR_TADIR_INTERFACE'
        EXPORTING
          wi_delete_tadir_entry    = abap_true
          wi_tadir_pgmid           = 'R3TR'
          wi_tadir_object          = 'TABL'
          wi_tadir_obj_name        = lv_obj_name
          wi_test_modus            = abap_false
        EXCEPTIONS
          tadir_entry_not_existing = 1
          OTHERS                   = 2.
      IF sy-subrc > 1.
        zcx_abapgit_exception=>raise( |Error from TR_TADIR_INTERFACE (subrc={ sy-subrc } ).| ).
      ENDIF.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    SELECT SINGLE updname INTO rv_user
      FROM tcdrp
      WHERE object = mv_object.
    IF sy-subrc <> 0.
      rv_user = c_user_unknown.
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~delete.

    DATA: lt_cdnames TYPE STANDARD TABLE OF cdnames,
          ls_cdnames TYPE cdnames,
          lt_tcdrs   TYPE STANDARD TABLE OF tcdrs,
          ls_tcdrs   TYPE tcdrs,
          lv_msg     TYPE symsgv.

    CALL FUNCTION 'CDNAMES_GET'
      EXPORTING
        iv_object        = mv_object
      TABLES
        it_tcdrs         = lt_tcdrs
        it_names         = lt_cdnames
      EXCEPTIONS
        object_space     = 1
        object_not_found = 2
        OTHERS           = 3.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    CALL FUNCTION 'CHDO_DELETE'
      EXPORTING
        iv_object        = mv_object
        iv_with_tadir    = abap_true
      EXCEPTIONS
        object_is_space  = 1
        object_not_found = 2
        other_error      = 3
        OTHERS           = 4.
    IF sy-subrc <> 0.
      lv_msg = mv_object.
      zcx_abapgit_exception=>raise_t100( iv_msgid = 'CD'
                                         iv_msgno = '869'
                                         iv_msgv1 = lv_msg ).
    ENDIF.

    LOOP AT lt_cdnames INTO ls_cdnames.
      delete_tadir_cdnames( ls_cdnames ).
    ENDLOOP.

    LOOP AT lt_tcdrs INTO ls_tcdrs.
      delete_tadir_tabl( ls_tcdrs ).
    ENDLOOP.

    corr_insert( iv_package ).

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: ls_change_object TYPE ty_change_document.
    FIELD-SYMBOLS: <ls_report_generated> LIKE LINE OF ls_change_object-reports_generated.

    io_xml->read( EXPORTING iv_name = 'CHDO'
                  CHANGING  cg_data = ls_change_object ).

    DELETE FROM tcdobs  WHERE object = mv_object.
    DELETE FROM tcdobts WHERE object = mv_object.
    DELETE FROM tcdrps  WHERE object = mv_object.

    LOOP AT ls_change_object-reports_generated ASSIGNING <ls_report_generated>.
      <ls_report_generated>-devclass = iv_package.
    ENDLOOP.

    INSERT tcdobs  FROM TABLE ls_change_object-objects.
    INSERT tcdobts FROM TABLE ls_change_object-objects_text.
    INSERT tcdrps  FROM TABLE ls_change_object-reports_generated.

    tadir_insert( iv_package ).

    after_import( ).

    corr_insert( iv_package ).

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    SELECT COUNT(*)
      FROM tcdrp
      WHERE object = mv_object.

    rv_bool = boolc( sy-subrc = 0 ).

  ENDMETHOD.

  METHOD zif_abapgit_object~get_comparator.
    RETURN.
  ENDMETHOD.

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

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

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

  METHOD zif_abapgit_object~is_locked.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

    DATA: lt_bdcdata TYPE STANDARD TABLE OF bdcdata,
          ls_bdcdata LIKE LINE OF lt_bdcdata.

    CLEAR: ls_bdcdata.
    ls_bdcdata-program  = 'SAPMSCDO_NEW'.
    ls_bdcdata-dynpro   = '0100'.
    ls_bdcdata-dynbegin = abap_true.
    APPEND ls_bdcdata TO lt_bdcdata.

    CLEAR: ls_bdcdata.
    ls_bdcdata-fnam = 'TCDOB-OBJECT'.
    ls_bdcdata-fval = mv_object.
    APPEND ls_bdcdata TO lt_bdcdata.

    CLEAR: ls_bdcdata.
    ls_bdcdata-fnam = 'BDC_OKCODE'.
    ls_bdcdata-fval = '=DISP'.
    APPEND ls_bdcdata TO lt_bdcdata.

    zcl_abapgit_ui_factory=>get_gui_jumper( )->jump_batch_input(
      iv_tcode   = 'SCDO'
      it_bdcdata = lt_bdcdata ).

    rv_exit = abap_true.

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA: ls_change_object TYPE ty_change_document,
          lt_tcdrp         TYPE STANDARD TABLE OF tcdrp,
          lt_tcdob         TYPE STANDARD TABLE OF tcdob,
          lt_tcdobt        TYPE STANDARD TABLE OF tcdobt,
          BEGIN OF ls_nulldatetime, " hack ro reset fields when they exist without syntax errors when they don't
            udate TYPE sy-datum,
            utime TYPE sy-uzeit,
          END OF ls_nulldatetime.

    FIELD-SYMBOLS: <ls_reports_generated> LIKE LINE OF ls_change_object-reports_generated,
                   <ls_objects>           LIKE LINE OF ls_change_object-objects,
                   <ls_objects_text>      LIKE LINE OF ls_change_object-objects_text.

    CALL FUNCTION 'CDNAMES_GET'
      EXPORTING
        iv_object        = mv_object
      TABLES
        it_tcdrp         = lt_tcdrp
        it_tcdob         = lt_tcdob
        it_tcdobt        = lt_tcdobt
      EXCEPTIONS
        object_space     = 1
        object_not_found = 2
        OTHERS           = 3.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise_t100( ).
    ENDIF.

    ls_change_object-reports_generated = lt_tcdrp.
    ls_change_object-objects           = lt_tcdob.
    ls_change_object-objects_text      = lt_tcdobt.

    " At import, when CHDO is generated date & time change, so always detects changes for this fields
    LOOP AT ls_change_object-reports_generated ASSIGNING <ls_reports_generated>.
      CLEAR: <ls_reports_generated>-datum, <ls_reports_generated>-uzeit,
             <ls_reports_generated>-author, <ls_reports_generated>-updname,
             <ls_reports_generated>-devclass.
    ENDLOOP.

    LOOP AT ls_change_object-objects ASSIGNING <ls_objects>.
      MOVE-CORRESPONDING ls_nulldatetime TO <ls_objects>. " reset date and time
    ENDLOOP.

    LOOP AT ls_change_object-objects_text ASSIGNING <ls_objects_text>.
      MOVE-CORRESPONDING ls_nulldatetime TO <ls_objects_text>. " reset date and time
    ENDLOOP.

    io_xml->add( iv_name = 'CHDO'
                 ig_data = ls_change_object ).

  ENDMETHOD.
ENDCLASS.

Fix deletion of TADIR entries (#5555)

CHDO: Fix deletion of TADIR entries (#5555)

Test mode needs to be set explicitly to false.


CLASS zcl_abapgit_object_sprx DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES:
      zif_abapgit_object.

    METHODS:
      constructor
        IMPORTING
          is_item     TYPE zif_abapgit_definitions=>ty_item
          iv_language TYPE spras
        RAISING
          zcx_abapgit_exception.

  PRIVATE SECTION.
    CONSTANTS:
      BEGIN OF c_proxy,
        data   TYPE string VALUE 'PROXY_DATA' ##NO_TEXT,
        header TYPE string VALUE 'PROXY_HEADER' ##NO_TEXT,
      END OF c_proxy.

    METHODS:
      get_object_and_name
        EXPORTING
          ev_object   TYPE sproxhdr-object
          ev_obj_name TYPE sproxhdr-obj_name,

      activate_classes
        IMPORTING
          it_sproxdat_new TYPE sprx_dat_t
        RAISING
          zcx_abapgit_exception,

      generate_service_definition
        IMPORTING
          it_sproxdat_new TYPE sprx_dat_t
        RAISING
          zcx_abapgit_exception,

      delta_handling
        IMPORTING
          io_xml          TYPE REF TO zcl_abapgit_xml_input
        EXPORTING
          et_sproxhdr_new TYPE sprx_hdr_t
          et_sproxdat_new TYPE sprx_dat_t
        RAISING
          zcx_abapgit_exception,

      check_sprx_tadir
        RAISING
          zcx_abapgit_exception,

      dequeue_proxy
        RAISING
          zcx_abapgit_exception,

      save
        IMPORTING
          it_sproxhdr_new TYPE sprx_hdr_t
          it_sproxdat_new TYPE sprx_dat_t.

    DATA:
      mv_object   TYPE sproxhdr-object,
      mv_obj_name TYPE sproxhdr-obj_name.

ENDCLASS.

CLASS zcl_abapgit_object_sprx IMPLEMENTATION.

  METHOD activate_classes.

    DATA: lt_objects TYPE STANDARD TABLE OF dwinactiv,
          ls_object  LIKE LINE OF lt_objects.

    FIELD-SYMBOLS: <ls_sproxdat_new> TYPE sprx_dat.

    " Somehow the classes aren't activated by the proxy framework.
    " This seems weird and it's almost certain a result of wrong API calls.
    " So as a quick fix we activate them ourselves. This surely has to
    " be improved in the future. ZCL_ABAPGIT_OBJECTS_ACTIVATION cannot
    " be used as it doesn't activate classes.

    LOOP AT it_sproxdat_new ASSIGNING <ls_sproxdat_new>
                            WHERE object1 = 'CLAS'.

      ls_object-object   = <ls_sproxdat_new>-object1.
      ls_object-obj_name = <ls_sproxdat_new>-obj_name1.
      INSERT ls_object INTO TABLE lt_objects.

    ENDLOOP.

    CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
      EXPORTING
        activate_ddic_objects  = abap_false
        with_popup             = abap_false
      TABLES
        objects                = lt_objects
      EXCEPTIONS
        excecution_error       = 1
        cancelled              = 2
        insert_into_corr_error = 3
        OTHERS                 = 4.

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

  ENDMETHOD.

  METHOD constructor.

    super->constructor( is_item     = is_item
                        iv_language = iv_language ).

    get_object_and_name(
      IMPORTING
        ev_object   = mv_object
        ev_obj_name = mv_obj_name ).

  ENDMETHOD.

  METHOD delta_handling.

    DATA: lo_proxy   TYPE REF TO cl_proxy,
          lt_delta   TYPE sprx_t_delta,
          ls_db_data TYPE sprx_db_data.

    "add Delta-Handling to avoid that single objects created without the dependent objects.
    "Thereby the dependent objects will be deleted
    TRY.
        lo_proxy = cl_proxy_fact=>load_by_abap_name(
                       object   = mv_object
                       obj_name = mv_obj_name ).

        lt_delta = lo_proxy->get_delta_all( ).

        ls_db_data = cl_proxy_db=>serialize(
                         proxy    = lo_proxy
                         inactive = abap_false
                         delta    = lt_delta ).

        et_sproxhdr_new = ls_db_data-sproxhdr.
        et_sproxdat_new = ls_db_data-sproxdat.

      CATCH cx_proxy_gen_error.
        "No delta for this object -> create

        io_xml->read(
          EXPORTING
            iv_name = c_proxy-header
          CHANGING
            cg_data = et_sproxhdr_new ).

        IF et_sproxhdr_new IS INITIAL.
          zcx_abapgit_exception=>raise( |SPRX - error deserialize: { ms_item-obj_name }| ).
        ENDIF.

        io_xml->read(
          EXPORTING
            iv_name = c_proxy-data
          CHANGING
            cg_data = et_sproxdat_new ).

    ENDTRY.

  ENDMETHOD.

  METHOD generate_service_definition.

    DATA: lv_transport    TYPE e070use-ordernum,
          lo_proxy_object TYPE REF TO cl_proxy_object,
          lx_proxy_fault  TYPE REF TO cx_proxy_fault.

    lv_transport = zcl_abapgit_default_transport=>get_instance(
                                               )->get( )-ordernum.

    TRY.
        lo_proxy_object = cl_pxn_factory=>create(
                              application  = 'PROXY_UI'
                              display_only = abap_false
                              saveable     = abap_true
                          )->load_by_abap_name_int(
                              object   = mv_object
                              obj_name = mv_obj_name
                          )->proxy.

        lo_proxy_object->activate(
          EXPORTING
            activate_all     = abap_true
          CHANGING
            transport_number = lv_transport ).

        lo_proxy_object->dequeue( ).

      CATCH cx_proxy_fault INTO lx_proxy_fault.
        zcx_abapgit_exception=>raise( iv_text     = |{ lx_proxy_fault->get_text( ) }|
                                      ix_previous = lx_proxy_fault ).
    ENDTRY.

    activate_classes( it_sproxdat_new ).

  ENDMETHOD.

  METHOD get_object_and_name.

    ev_object   = ms_item-obj_name(4).
    ev_obj_name = ms_item-obj_name+4.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    DATA lv_changed_by TYPE sproxhdr-changed_by.

    rv_user = c_user_unknown.

    SELECT SINGLE changed_by
           FROM sproxhdr
           INTO lv_changed_by
           WHERE object     = mv_object
           AND   obj_name   = mv_obj_name
           AND   inactive   = abap_false.

    IF  sy-subrc = 0
    AND lv_changed_by IS NOT INITIAL.
      rv_user = lv_changed_by.
    ENDIF.

  ENDMETHOD.

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

  METHOD zif_abapgit_object~delete.

    DATA:
      lv_object      TYPE sproxhdr-object,
      lv_obj_name    TYPE sproxhdr-obj_name,
      lv_return_code TYPE i,
      lt_log         TYPE sprx_log_t.

    get_object_and_name(
      IMPORTING
        ev_object   = lv_object
        ev_obj_name = lv_obj_name ).

    cl_proxy_data=>delete_single_proxy(
       EXPORTING
         object           = lv_object
         obj_name         = lv_obj_name
       CHANGING
         c_return_code    = lv_return_code
         ct_log           = lt_log ).
    IF lv_return_code <> 0.
      zcx_abapgit_exception=>raise( 'SPRX: Error from DELETE_SINGLE_PROXY' ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: lt_sproxhdr_new TYPE sprx_hdr_t,
          lt_sproxdat_new TYPE sprx_dat_t.

    tadir_insert( iv_package ).

    delta_handling(
      EXPORTING
        io_xml = io_xml
      IMPORTING
        et_sproxhdr_new = lt_sproxhdr_new
        et_sproxdat_new = lt_sproxdat_new ).

    save(
      it_sproxhdr_new = lt_sproxhdr_new
      it_sproxdat_new = lt_sproxdat_new ).

    check_sprx_tadir( ).

    dequeue_proxy( ).

    IF mv_object = 'INTF'.
      generate_service_definition( lt_sproxdat_new ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA:
      lv_status      TYPE prx_status,
      lv_status_text TYPE prx_status_t.

    cl_proxy_data=>db_get_status(
      EXPORTING
        object      = mv_object
        obj_name    = mv_obj_name
      IMPORTING
        status      = lv_status
        status_text = lv_status_text ).

    IF lv_status = if_proxy=>c_state_active.
      rv_bool = abap_true.
    ELSE.
      rv_bool = abap_false.
    ENDIF.

  ENDMETHOD.

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

  METHOD zif_abapgit_object~has_changed_since.
    rv_changed = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~is_active.
    rv_active = abap_true. "dummy implementation
  ENDMETHOD.

  METHOD zif_abapgit_object~is_locked.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

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

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA:
      lo_proxy        TYPE REF TO cl_proxy,
      ls_sprx_db_data TYPE sprx_db_data,
      lt_delta        TYPE sprx_t_delta.

    FIELD-SYMBOLS:
      <ls_sproxheader> LIKE LINE OF ls_sprx_db_data-sproxhdr,
      <ls_sproxdat>    TYPE sprx_dat.

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

    TRY.
        lo_proxy = cl_proxy_fact=>load_by_abap_name(
                      object   = mv_object
                      obj_name = mv_obj_name ).

        lt_delta = lo_proxy->get_delta_all( ).

        ls_sprx_db_data = cl_proxy_db=>serialize(
                              proxy     = lo_proxy
                              inactive  = abap_false
                              delta     = lt_delta ).

        LOOP AT ls_sprx_db_data-sproxhdr ASSIGNING <ls_sproxheader>.

          CLEAR:
            <ls_sproxheader>-created_by,
            <ls_sproxheader>-created_on,
            <ls_sproxheader>-changed_by,
            <ls_sproxheader>-changed_on.

        ENDLOOP.

        LOOP AT ls_sprx_db_data-sproxdat ASSIGNING <ls_sproxdat>.

          CLEAR <ls_sproxdat>-warnings.

        ENDLOOP.

        io_xml->add(
            iv_name = c_proxy-header
            ig_data = ls_sprx_db_data-sproxhdr ).

        io_xml->add(
            iv_name = c_proxy-data
            ig_data = ls_sprx_db_data-sproxdat ).

      CATCH cx_proxy_gen_error.
        zcx_abapgit_exception=>raise( |SPRX - error load proxy { mv_obj_name }| ).
    ENDTRY.

  ENDMETHOD.

  METHOD check_sprx_tadir.

    DATA: lt_abap_keys TYPE prx_abapobjects,
          ls_abap_key  LIKE LINE OF lt_abap_keys,
          lx_error     TYPE REF TO cx_proxy_gen_error.

    ls_abap_key-object   = mv_object.
    ls_abap_key-obj_name = mv_obj_name.
    APPEND ls_abap_key TO lt_abap_keys.

    TRY.
        cl_proxy_utils=>check_sprx_tadir(
            objects = lt_abap_keys
            repair  = abap_true ).

      CATCH cx_proxy_gen_error INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = |{ lx_error->get_text( ) }|
                                      ix_previous = lx_error ).
    ENDTRY.

  ENDMETHOD.

  METHOD dequeue_proxy.

    DATA: lo_proxy TYPE REF TO cl_proxy,
          lx_error TYPE REF TO cx_proxy_gen_error.

    TRY.
        lo_proxy = cl_proxy_fact=>load_by_abap_name(
                       object   = mv_object
                       obj_name = mv_obj_name ).

        lo_proxy->dequeue( ).

      CATCH cx_proxy_gen_error INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = |{ lx_error->get_text( ) }|
                                      ix_previous = lx_error ).
    ENDTRY.

  ENDMETHOD.

  METHOD save.

    DATA:
      lt_sproxhdr_old  TYPE sprx_hdr_t,
      lt_sproxdat_old  TYPE sprx_dat_t,
      lt_sproxsvar_old TYPE sprx_svar_t,
      lt_sproxintf_old TYPE sprx_matchintf_t,
      lt_sproxsvar_new TYPE sprx_svar_t,
      lt_sproxintf_new TYPE sprx_matchintf_t.

    cl_proxy_data=>db_save(
        sproxhdr_old  = lt_sproxhdr_old
        sproxdat_old  = lt_sproxdat_old
        sproxsvar_old = lt_sproxsvar_old
        sproxintf_old = lt_sproxintf_old
        sproxhdr_new  = it_sproxhdr_new
        sproxdat_new  = it_sproxdat_new
        sproxsvar_new = lt_sproxsvar_new
        sproxintf_new = lt_sproxintf_new ).

  ENDMETHOD.

ENDCLASS.

CLASS zcl_abapgit_object_sprx DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL.

  PUBLIC SECTION.
    INTERFACES:
      zif_abapgit_object.

    METHODS:
      constructor
        IMPORTING
          is_item     TYPE zif_abapgit_definitions=>ty_item
          iv_language TYPE spras
        RAISING
          zcx_abapgit_exception.

  PRIVATE SECTION.
    CONSTANTS:
      BEGIN OF c_proxy,
        data   TYPE string VALUE 'PROXY_DATA' ##NO_TEXT,
        header TYPE string VALUE 'PROXY_HEADER' ##NO_TEXT,
      END OF c_proxy.

    METHODS:
      get_object_and_name
        EXPORTING
          ev_object   TYPE sproxhdr-object
          ev_obj_name TYPE sproxhdr-obj_name,

      activate_classes
        IMPORTING
          it_sproxdat_new TYPE sprx_dat_t
        RAISING
          zcx_abapgit_exception,

      generate_service_definition
        IMPORTING
          it_sproxdat_new TYPE sprx_dat_t
        RAISING
          zcx_abapgit_exception,

      delta_handling
        IMPORTING
          io_xml          TYPE REF TO zcl_abapgit_xml_input
        EXPORTING
          et_sproxhdr_new TYPE sprx_hdr_t
          et_sproxdat_new TYPE sprx_dat_t
        RAISING
          zcx_abapgit_exception,

      check_sprx_tadir
        RAISING
          zcx_abapgit_exception,

      dequeue_proxy
        RAISING
          zcx_abapgit_exception,

      save
        IMPORTING
          it_sproxhdr_new TYPE sprx_hdr_t
          it_sproxdat_new TYPE sprx_dat_t.

    DATA:
      mv_object   TYPE sproxhdr-object,
      mv_obj_name TYPE sproxhdr-obj_name.

ENDCLASS.

CLASS zcl_abapgit_object_sprx IMPLEMENTATION.

  METHOD activate_classes.

    DATA: lt_objects TYPE STANDARD TABLE OF dwinactiv,
          ls_object  LIKE LINE OF lt_objects.

    FIELD-SYMBOLS: <ls_sproxdat_new> TYPE sprx_dat.

    " Somehow the classes aren't activated by the proxy framework.
    " This seems weird and it's almost certain a result of wrong API calls.
    " So as a quick fix we activate them ourselves. This surely has to
    " be improved in the future. ZCL_ABAPGIT_OBJECTS_ACTIVATION cannot
    " be used as it doesn't activate classes.

    LOOP AT it_sproxdat_new ASSIGNING <ls_sproxdat_new>
                            WHERE object1 = 'CLAS'.

      ls_object-object   = <ls_sproxdat_new>-object1.
      ls_object-obj_name = <ls_sproxdat_new>-obj_name1.
      INSERT ls_object INTO TABLE lt_objects.

    ENDLOOP.

    CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
      EXPORTING
        activate_ddic_objects  = abap_false
        with_popup             = abap_false
      TABLES
        objects                = lt_objects
      EXCEPTIONS
        excecution_error       = 1
        cancelled              = 2
        insert_into_corr_error = 3
        OTHERS                 = 4.

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

  ENDMETHOD.

  METHOD constructor.

    super->constructor( is_item     = is_item
                        iv_language = iv_language ).

    get_object_and_name(
      IMPORTING
        ev_object   = mv_object
        ev_obj_name = mv_obj_name ).

  ENDMETHOD.

  METHOD delta_handling.

    DATA: lo_proxy   TYPE REF TO cl_proxy,
          lt_delta   TYPE sprx_t_delta,
          ls_db_data TYPE sprx_db_data.

    "add Delta-Handling to avoid that single objects created without the dependent objects.
    "Thereby the dependent objects will be deleted
    TRY.
        lo_proxy = cl_proxy_fact=>load_by_abap_name(
                       object   = mv_object
                       obj_name = mv_obj_name ).

        lt_delta = lo_proxy->get_delta_all( ).

        ls_db_data = cl_proxy_db=>serialize(
                         proxy    = lo_proxy
                         inactive = abap_false
                         delta    = lt_delta ).

        et_sproxhdr_new = ls_db_data-sproxhdr.
        et_sproxdat_new = ls_db_data-sproxdat.

      CATCH cx_proxy_gen_error.
        "No delta for this object -> create

        io_xml->read(
          EXPORTING
            iv_name = c_proxy-header
          CHANGING
            cg_data = et_sproxhdr_new ).

        IF et_sproxhdr_new IS INITIAL.
          zcx_abapgit_exception=>raise( |SPRX - error deserialize: { ms_item-obj_name }| ).
        ENDIF.

        io_xml->read(
          EXPORTING
            iv_name = c_proxy-data
          CHANGING
            cg_data = et_sproxdat_new ).

    ENDTRY.

  ENDMETHOD.

  METHOD generate_service_definition.

    DATA: lv_transport    TYPE e070use-ordernum,
          lo_proxy_object TYPE REF TO cl_proxy_object,
          lx_proxy_fault  TYPE REF TO cx_proxy_fault.

    lv_transport = zcl_abapgit_default_transport=>get_instance(
                                               )->get( )-ordernum.

    TRY.
        lo_proxy_object = cl_pxn_factory=>create(
                              application  = 'PROXY_UI'
                              display_only = abap_false
                              saveable     = abap_true
                          )->load_by_abap_name_int(
                              object   = mv_object
                              obj_name = mv_obj_name
                          )->proxy.

        lo_proxy_object->activate(
          EXPORTING
            activate_all     = abap_true
          CHANGING
            transport_number = lv_transport ).

        lo_proxy_object->dequeue( ).

      CATCH cx_proxy_fault INTO lx_proxy_fault.
        zcx_abapgit_exception=>raise( iv_text     = |{ lx_proxy_fault->get_text( ) }|
                                      ix_previous = lx_proxy_fault ).
    ENDTRY.

    activate_classes( it_sproxdat_new ).

  ENDMETHOD.

  METHOD get_object_and_name.

    ev_object   = ms_item-obj_name(4).
    ev_obj_name = ms_item-obj_name+4.

  ENDMETHOD.

  METHOD zif_abapgit_object~changed_by.

    DATA lv_changed_by TYPE sproxhdr-changed_by.

    rv_user = c_user_unknown.

    SELECT SINGLE changed_by
           FROM sproxhdr
           INTO lv_changed_by
           WHERE object     = mv_object
           AND   obj_name   = mv_obj_name
           AND   inactive   = abap_false.

    IF  sy-subrc = 0
    AND lv_changed_by IS NOT INITIAL.
      rv_user = lv_changed_by.
    ENDIF.

  ENDMETHOD.

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

  METHOD zif_abapgit_object~delete.

    DATA:
      lv_object      TYPE sproxhdr-object,
      lv_obj_name    TYPE sproxhdr-obj_name,
      lv_return_code TYPE i,
      lt_log         TYPE sprx_log_t.

    get_object_and_name(
      IMPORTING
        ev_object   = lv_object
        ev_obj_name = lv_obj_name ).

    cl_proxy_data=>delete_single_proxy(
       EXPORTING
         object           = lv_object
         obj_name         = lv_obj_name
       CHANGING
         c_return_code    = lv_return_code
         ct_log           = lt_log ).
    IF lv_return_code <> 0.
      zcx_abapgit_exception=>raise( 'SPRX: Error from DELETE_SINGLE_PROXY' ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~deserialize.

    DATA: lt_sproxhdr_new TYPE sprx_hdr_t,
          lt_sproxdat_new TYPE sprx_dat_t.

    tadir_insert( iv_package ).

    delta_handling(
      EXPORTING
        io_xml = io_xml
      IMPORTING
        et_sproxhdr_new = lt_sproxhdr_new
        et_sproxdat_new = lt_sproxdat_new ).

    save(
      it_sproxhdr_new = lt_sproxhdr_new
      it_sproxdat_new = lt_sproxdat_new ).

    check_sprx_tadir( ).

    dequeue_proxy( ).

    IF mv_object = 'INTF'.
      generate_service_definition( lt_sproxdat_new ).
    ENDIF.

  ENDMETHOD.

  METHOD zif_abapgit_object~exists.

    DATA:
      lv_status      TYPE prx_status,
      lv_status_text TYPE prx_status_t.

    cl_proxy_data=>db_get_status(
      EXPORTING
        object      = mv_object
        obj_name    = mv_obj_name
      IMPORTING
        status      = lv_status
        status_text = lv_status_text ).

    IF lv_status = if_proxy=>c_state_active.
      rv_bool = abap_true.
    ELSE.
      rv_bool = abap_false.
    ENDIF.

  ENDMETHOD.

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

  METHOD zif_abapgit_object~has_changed_since.
    rv_changed = abap_true.
  ENDMETHOD.

  METHOD zif_abapgit_object~is_active.
    rv_active = abap_true. "dummy implementation
  ENDMETHOD.

  METHOD zif_abapgit_object~is_locked.
    rv_is_locked = abap_false.
  ENDMETHOD.

  METHOD zif_abapgit_object~jump.

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

  ENDMETHOD.

  METHOD zif_abapgit_object~serialize.

    DATA:
      lo_proxy           TYPE REF TO cl_proxy,
      ls_sprx_db_data    TYPE sprx_db_data,
      lt_delta           TYPE sprx_t_delta,
      lx_proxy_gen_error TYPE REF TO cx_proxy_gen_error.

    FIELD-SYMBOLS:
      <ls_sproxheader> LIKE LINE OF ls_sprx_db_data-sproxhdr,
      <ls_sproxdat>    TYPE sprx_dat.

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

    TRY.
        lo_proxy = cl_proxy_fact=>load_by_abap_name(
                       object   = mv_object
                       obj_name = mv_obj_name ).

        lt_delta = lo_proxy->get_delta_all( ).

        ls_sprx_db_data = cl_proxy_db=>serialize(
                              proxy     = lo_proxy
                              inactive  = abap_false
                              delta     = lt_delta ).

      CATCH cx_proxy_gen_error INTO lx_proxy_gen_error.
        zcx_abapgit_exception=>raise( iv_text     = lx_proxy_gen_error->get_text( )
                                      ix_previous = lx_proxy_gen_error ).
    ENDTRY.

    LOOP AT ls_sprx_db_data-sproxhdr ASSIGNING <ls_sproxheader>.

      CLEAR:
        <ls_sproxheader>-created_by,
        <ls_sproxheader>-created_on,
        <ls_sproxheader>-changed_by,
        <ls_sproxheader>-changed_on.

    ENDLOOP.

    LOOP AT ls_sprx_db_data-sproxdat ASSIGNING <ls_sproxdat>.

      CLEAR <ls_sproxdat>-warnings.

    ENDLOOP.

    io_xml->add(
        iv_name = c_proxy-header
        ig_data = ls_sprx_db_data-sproxhdr ).

    io_xml->add(
        iv_name = c_proxy-data
        ig_data = ls_sprx_db_data-sproxdat ).

  ENDMETHOD.

  METHOD check_sprx_tadir.

    DATA: lt_abap_keys TYPE prx_abapobjects,
          ls_abap_key  LIKE LINE OF lt_abap_keys,
          lx_error     TYPE REF TO cx_proxy_gen_error.

    ls_abap_key-object   = mv_object.
    ls_abap_key-obj_name = mv_obj_name.
    APPEND ls_abap_key TO lt_abap_keys.

    TRY.
        cl_proxy_utils=>check_sprx_tadir(
            objects = lt_abap_keys
            repair  = abap_true ).

      CATCH cx_proxy_gen_error INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = |{ lx_error->get_text( ) }|
                                      ix_previous = lx_error ).
    ENDTRY.

  ENDMETHOD.

  METHOD dequeue_proxy.

    DATA: lo_proxy TYPE REF TO cl_proxy,
          lx_error TYPE REF TO cx_proxy_gen_error.

    TRY.
        lo_proxy = cl_proxy_fact=>load_by_abap_name(
                       object   = mv_object
                       obj_name = mv_obj_name ).

        lo_proxy->dequeue( ).

      CATCH cx_proxy_gen_error INTO lx_error.
        zcx_abapgit_exception=>raise( iv_text     = |{ lx_error->get_text( ) }|
                                      ix_previous = lx_error ).
    ENDTRY.

  ENDMETHOD.

  METHOD save.

    DATA:
      lt_sproxhdr_old  TYPE sprx_hdr_t,
      lt_sproxdat_old  TYPE sprx_dat_t,
      lt_sproxsvar_old TYPE sprx_svar_t,
      lt_sproxintf_old TYPE sprx_matchintf_t,
      lt_sproxsvar_new TYPE sprx_svar_t,
      lt_sproxintf_new TYPE sprx_matchintf_t.

    cl_proxy_data=>db_save(
        sproxhdr_old  = lt_sproxhdr_old
        sproxdat_old  = lt_sproxdat_old
        sproxsvar_old = lt_sproxsvar_old
        sproxintf_old = lt_sproxintf_old
        sproxhdr_new  = it_sproxhdr_new
        sproxdat_new  = it_sproxdat_new
        sproxsvar_new = lt_sproxsvar_new
        sproxintf_new = lt_sproxintf_new ).

  ENDMETHOD.

ENDCLASS.

improve exception handling

SPRX: improve exception handling