CLASS zcl_abapgit_object_fugr DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_program CREATE PUBLIC . PUBLIC SECTION. INTERFACES zif_abapgit_object . PROTECTED SECTION. PRIVATE SECTION. CONSTANTS: c_longtext_id_prog TYPE dokil-id VALUE 'RE', c_longtext_id_func TYPE dokil-id VALUE 'FU', c_longtext_id_func_exc TYPE dokil-id VALUE 'FX'. TYPES: ty_rs38l_incl_tt TYPE STANDARD TABLE OF rs38l_incl WITH DEFAULT KEY . TYPES: BEGIN OF ty_function, funcname TYPE rs38l_fnam, global_flag TYPE rs38l-global, remote_call TYPE rs38l-remote, update_task TYPE rs38l-utask, short_text TYPE tftit-stext, remote_basxml TYPE rs38l-basxml_enabled, import TYPE STANDARD TABLE OF rsimp WITH DEFAULT KEY, changing TYPE STANDARD TABLE OF rscha WITH DEFAULT KEY, export TYPE STANDARD TABLE OF rsexp WITH DEFAULT KEY, tables TYPE STANDARD TABLE OF rstbl WITH DEFAULT KEY, exception TYPE STANDARD TABLE OF rsexc WITH DEFAULT KEY, documentation TYPE STANDARD TABLE OF rsfdo WITH DEFAULT KEY, exception_classes TYPE abap_bool, END OF ty_function . TYPES: ty_function_tt TYPE STANDARD TABLE OF ty_function WITH DEFAULT KEY . TYPES: ty_sobj_name_tt TYPE STANDARD TABLE OF sobj_name WITH DEFAULT KEY . TYPES: BEGIN OF ty_tpool_i18n, language TYPE langu, textpool TYPE zif_abapgit_definitions=>ty_tpool_tt, END OF ty_tpool_i18n . TYPES: ty_tpools_i18n TYPE STANDARD TABLE OF ty_tpool_i18n . DATA mt_includes_cache TYPE ty_sobj_name_tt . DATA mt_includes_all TYPE ty_sobj_name_tt . METHODS check_rfc_parameters IMPORTING !is_function TYPE ty_function RAISING zcx_abapgit_exception . METHODS update_where_used IMPORTING !it_includes TYPE ty_sobj_name_tt . METHODS main_name RETURNING VALUE(rv_program) TYPE program RAISING zcx_abapgit_exception . METHODS functions RETURNING VALUE(rt_functab) TYPE ty_rs38l_incl_tt RAISING zcx_abapgit_exception . METHODS includes RETURNING VALUE(rt_includes) TYPE ty_sobj_name_tt RAISING zcx_abapgit_exception . METHODS serialize_functions RETURNING VALUE(rt_functions) TYPE ty_function_tt RAISING zcx_abapgit_exception . METHODS deserialize_functions IMPORTING !it_functions TYPE ty_function_tt !ii_log TYPE REF TO zif_abapgit_log !iv_version TYPE uccheck !iv_package TYPE devclass !iv_transport TYPE trkorr RAISING zcx_abapgit_exception . METHODS serialize_function_docs IMPORTING !iv_prog_name TYPE syrepid !it_functions TYPE ty_function_tt !ii_xml TYPE REF TO zif_abapgit_xml_output RAISING zcx_abapgit_exception . METHODS deserialize_function_docs IMPORTING !iv_prog_name TYPE syrepid !it_functions TYPE ty_function_tt !ii_xml TYPE REF TO zif_abapgit_xml_input RAISING zcx_abapgit_exception . METHODS serialize_xml IMPORTING !ii_xml TYPE REF TO zif_abapgit_xml_output RAISING zcx_abapgit_exception . METHODS deserialize_xml IMPORTING !ii_xml TYPE REF TO zif_abapgit_xml_input !iv_version TYPE uccheck !iv_package TYPE devclass !iv_transport TYPE trkorr RAISING zcx_abapgit_exception . METHODS serialize_includes RAISING zcx_abapgit_exception . METHODS deserialize_includes IMPORTING !ii_xml TYPE REF TO zif_abapgit_xml_input !iv_package TYPE devclass !ii_log TYPE REF TO zif_abapgit_log RAISING zcx_abapgit_exception . METHODS is_function_group_locked RETURNING VALUE(rv_is_functions_group_locked) TYPE abap_bool RAISING zcx_abapgit_exception . METHODS is_any_include_locked RETURNING VALUE(rv_is_any_include_locked) TYPE abap_bool RAISING zcx_abapgit_exception . METHODS is_any_function_module_locked RETURNING VALUE(rv_any_function_module_locked) TYPE abap_bool RAISING zcx_abapgit_exception . METHODS get_abap_version IMPORTING !ii_xml TYPE REF TO zif_abapgit_xml_input RETURNING VALUE(rv_abap_version) TYPE progdir-uccheck RAISING zcx_abapgit_exception . METHODS update_func_group_short_text IMPORTING !iv_group TYPE rs38l-area !iv_short_text TYPE tftit-stext . METHODS serialize_texts IMPORTING !iv_prog_name TYPE syrepid !ii_xml TYPE REF TO zif_abapgit_xml_output RAISING zcx_abapgit_exception . METHODS deserialize_texts IMPORTING !iv_prog_name TYPE syrepid !ii_xml TYPE REF TO zif_abapgit_xml_input RAISING zcx_abapgit_exception . METHODS is_part_of_other_fugr IMPORTING !iv_include TYPE sobj_name RETURNING VALUE(rv_belongs_to_other_fugr) TYPE abap_bool. ENDCLASS. CLASS zcl_abapgit_object_fugr IMPLEMENTATION. METHOD check_rfc_parameters. * function module RS_FUNCTIONMODULE_INSERT does the same deep down, but the right error * message is not returned to the user, this is a workaround to give a proper error * message to the user DATA: ls_parameter TYPE rsfbpara, lt_fupa TYPE rsfb_param, ls_fupa LIKE LINE OF lt_fupa. IF is_function-remote_call = 'R'. cl_fb_parameter_conversion=>convert_parameter_old_to_fupa( EXPORTING functionname = is_function-funcname import = is_function-import export = is_function-export change = is_function-changing tables = is_function-tables except = is_function-exception IMPORTING fupararef = lt_fupa ). LOOP AT lt_fupa INTO ls_fupa WHERE paramtype = 'I' OR paramtype = 'E' OR paramtype = 'C' OR paramtype = 'T'. cl_fb_parameter_conversion=>convert_intern_to_extern( EXPORTING parameter_db = ls_fupa IMPORTING parameter_vis = ls_parameter ). CALL FUNCTION 'RS_FB_CHECK_PARAMETER_REMOTE' EXPORTING parameter = ls_parameter basxml_enabled = is_function-remote_basxml EXCEPTIONS not_remote_compatible = 1 OTHERS = 2. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. ENDLOOP. ENDIF. ENDMETHOD. METHOD deserialize_functions. DATA: lv_include TYPE rs38l-include, lv_area TYPE rs38l-area, lv_group TYPE rs38l-area, lv_namespace TYPE rs38l-namespace, lt_source TYPE TABLE OF abaptxt255, lv_msg TYPE string, lx_error TYPE REF TO zcx_abapgit_exception. FIELD-SYMBOLS: LIKE LINE OF it_functions. LOOP AT it_functions ASSIGNING . lt_source = mo_files->read_abap( iv_extra = -funcname ). lv_area = ms_item-obj_name. CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT' EXPORTING complete_area = lv_area IMPORTING namespace = lv_namespace group = lv_group EXCEPTIONS OTHERS = 12. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_msg. ii_log->add_error( iv_msg = |Function module { -funcname }: { lv_msg }| is_item = ms_item ). CONTINUE. "with next function module ENDIF. IF zcl_abapgit_factory=>get_function_module( )->function_exists( -funcname ) = abap_true. * delete the function module to make sure the parameters are updated * haven't found a nice way to update the parameters CALL FUNCTION 'FUNCTION_DELETE' EXPORTING funcname = -funcname suppress_success_message = abap_true EXCEPTIONS error_message = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_msg. ii_log->add_error( iv_msg = |Function module { -funcname }: { lv_msg }| is_item = ms_item ). CONTINUE. "with next function module ENDIF. ENDIF. TRY. check_rfc_parameters( ). CATCH zcx_abapgit_exception INTO lx_error. ii_log->add_error( iv_msg = |Function module { -funcname }: { lx_error->get_text( ) }| is_item = ms_item ). CONTINUE. "with next function module ENDTRY. CALL FUNCTION 'RS_FUNCTIONMODULE_INSERT' EXPORTING funcname = -funcname function_pool = lv_group interface_global = -global_flag remote_call = -remote_call short_text = -short_text update_task = -update_task exception_class = -exception_classes namespace = lv_namespace remote_basxml_supported = -remote_basxml corrnum = iv_transport IMPORTING function_include = lv_include TABLES import_parameter = -import export_parameter = -export tables_parameter = -tables changing_parameter = -changing exception_list = -exception parameter_docu = -documentation EXCEPTIONS double_task = 1 error_message = 2 function_already_exists = 3 invalid_function_pool = 4 invalid_name = 5 too_many_functions = 6 no_modify_permission = 7 no_show_permission = 8 enqueue_system_failure = 9 canceled_in_corr = 10 OTHERS = 11. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_msg. ii_log->add_error( iv_msg = |Function module { -funcname }: { lv_msg }| is_item = ms_item ). CONTINUE. "with next function module ENDIF. zcl_abapgit_factory=>get_sap_report( )->insert_report( iv_name = lv_include iv_package = iv_package iv_version = iv_version it_source = lt_source ). ii_log->add_success( iv_msg = |Function module { -funcname } imported| is_item = ms_item ). ENDLOOP. ENDMETHOD. METHOD deserialize_function_docs. FIELD-SYMBOLS LIKE LINE OF it_functions. zcl_abapgit_factory=>get_longtexts( )->deserialize( iv_longtext_id = c_longtext_id_prog iv_object_name = iv_prog_name ii_xml = ii_xml iv_main_language = mv_language ). LOOP AT it_functions ASSIGNING . zcl_abapgit_factory=>get_longtexts( )->deserialize( iv_longtext_name = |LONGTEXTS_{ -funcname }| iv_longtext_id = c_longtext_id_func iv_object_name = -funcname ii_xml = ii_xml iv_main_language = mv_language ). zcl_abapgit_factory=>get_longtexts( )->deserialize( iv_longtext_name = |LONGTEXTS_{ -funcname }___EXC| iv_longtext_id = c_longtext_id_func_exc iv_object_name = -funcname ii_xml = ii_xml iv_main_language = mv_language ). ENDLOOP. ENDMETHOD. METHOD deserialize_includes. DATA: lo_xml TYPE REF TO zif_abapgit_xml_input, ls_progdir TYPE zif_abapgit_sap_report=>ty_progdir, lt_includes TYPE ty_sobj_name_tt, lt_tpool TYPE textpool_table, lt_tpool_ext TYPE zif_abapgit_definitions=>ty_tpool_tt, lt_source TYPE TABLE OF abaptxt255, lx_exc TYPE REF TO zcx_abapgit_exception. FIELD-SYMBOLS: LIKE LINE OF lt_includes. tadir_insert( iv_package ). ii_xml->read( EXPORTING iv_name = 'INCLUDES' CHANGING cg_data = lt_includes ). LOOP AT lt_includes ASSIGNING . "ignore simple transformation includes (as long as they remain in existing repositories) IF strlen( ) = 33 AND +30(3) = 'XTI'. ii_log->add_warning( iv_msg = |Simple Transformation include { } ignored| is_item = ms_item ). CONTINUE. ENDIF. TRY. lt_source = mo_files->read_abap( iv_extra = ). lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'PROGDIR' CHANGING cg_data = ls_progdir ). set_abap_language_version( CHANGING cv_abap_language_version = ls_progdir-uccheck ). lo_xml->read( EXPORTING iv_name = 'TPOOL' CHANGING cg_data = lt_tpool_ext ). lt_tpool = read_tpool( lt_tpool_ext ). deserialize_program( is_progdir = ls_progdir it_source = lt_source it_tpool = lt_tpool iv_package = iv_package ). deserialize_textpool( iv_program = it_tpool = lt_tpool iv_is_include = abap_true ). ii_log->add_success( iv_msg = |Include { ls_progdir-name } imported| is_item = ms_item ). CATCH zcx_abapgit_exception INTO lx_exc. ii_log->add_exception( ix_exc = lx_exc is_item = ms_item ). CONTINUE. ENDTRY. ENDLOOP. ENDMETHOD. METHOD deserialize_texts. DATA: lt_tpool_i18n TYPE ty_tpools_i18n, lt_tpool TYPE textpool_table. FIELD-SYMBOLS LIKE LINE OF lt_tpool_i18n. ii_xml->read( EXPORTING iv_name = 'I18N_TPOOL' CHANGING cg_data = lt_tpool_i18n ). LOOP AT lt_tpool_i18n ASSIGNING . lt_tpool = read_tpool( -textpool ). deserialize_textpool( iv_program = iv_prog_name iv_language = -language it_tpool = lt_tpool ). ENDLOOP. ENDMETHOD. METHOD deserialize_xml. DATA: lv_complete TYPE rs38l-area, lv_namespace TYPE rs38l-namespace, lv_areat TYPE tlibt-areat, lv_stext TYPE tftit-stext, lv_group TYPE rs38l-area. lv_complete = ms_item-obj_name. CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT' EXPORTING complete_area = lv_complete IMPORTING namespace = lv_namespace group = lv_group EXCEPTIONS include_not_exists = 1 group_not_exists = 2 no_selections = 3 no_function_include = 4 no_function_pool = 5 delimiter_wrong_position = 6 no_customer_function_group = 7 no_customer_function_include = 8 reserved_name_customer = 9 namespace_too_long = 10 area_length_error = 11 OTHERS = 12. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. ii_xml->read( EXPORTING iv_name = 'AREAT' CHANGING cg_data = lv_areat ). lv_stext = lv_areat. CALL FUNCTION 'RS_FUNCTION_POOL_INSERT' EXPORTING function_pool = lv_group short_text = lv_stext namespace = lv_namespace devclass = iv_package unicode_checks = iv_version corrnum = iv_transport suppress_corr_check = abap_false EXCEPTIONS name_already_exists = 1 name_not_correct = 2 function_already_exists = 3 invalid_function_pool = 4 invalid_name = 5 too_many_functions = 6 no_modify_permission = 7 no_show_permission = 8 enqueue_system_failure = 9 canceled_in_corr = 10 undefined_error = 11 OTHERS = 12. CASE sy-subrc. WHEN 0. " Everything is ok WHEN 1 OR 3. " If the function group exists we need to manually update the short text update_func_group_short_text( iv_group = lv_group iv_short_text = lv_stext ). WHEN OTHERS. zcx_abapgit_exception=>raise_t100( ). ENDCASE. ENDMETHOD. METHOD functions. DATA: lv_area TYPE rs38l-area, lt_enlfdir TYPE STANDARD TABLE OF enlfdir. FIELD-SYMBOLS: TYPE LINE OF ty_rs38l_incl_tt, TYPE enlfdir. lv_area = ms_item-obj_name. CALL FUNCTION 'RS_FUNCTION_POOL_CONTENTS' EXPORTING function_pool = lv_area TABLES functab = rt_functab EXCEPTIONS function_pool_not_found = 1 OTHERS = 2. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. SELECT * FROM enlfdir INTO TABLE @lt_enlfdir WHERE area = @ms_item-obj_name AND active = @abap_true. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( |Function Group { ms_item-obj_name } not found in table ENLFDIR| ). ENDIF. LOOP AT lt_enlfdir ASSIGNING . TRANSLATE -funcname TO UPPER CASE. ENDLOOP. SORT lt_enlfdir BY funcname ASCENDING. LOOP AT rt_functab ASSIGNING . TRANSLATE TO UPPER CASE. READ TABLE lt_enlfdir WITH KEY funcname = -funcname TRANSPORTING NO FIELDS. IF sy-subrc <> 0. DELETE rt_functab INDEX sy-index. ENDIF. ENDLOOP. SORT rt_functab BY funcname ASCENDING. DELETE ADJACENT DUPLICATES FROM rt_functab COMPARING funcname. ENDMETHOD. METHOD get_abap_version. DATA: lt_includes TYPE ty_sobj_name_tt, ls_progdir TYPE zif_abapgit_sap_report=>ty_progdir, lo_xml TYPE REF TO zif_abapgit_xml_input. FIELD-SYMBOLS: LIKE LINE OF lt_includes. ii_xml->read( EXPORTING iv_name = 'INCLUDES' CHANGING cg_data = lt_includes ). LOOP AT lt_includes ASSIGNING . lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'PROGDIR' CHANGING cg_data = ls_progdir ). IF ls_progdir-uccheck IS INITIAL. CONTINUE. ELSEIF rv_abap_version IS INITIAL. rv_abap_version = ls_progdir-uccheck. CONTINUE. ELSEIF rv_abap_version <> ls_progdir-uccheck. *** All includes need to have the same ABAP language version zcx_abapgit_exception=>raise( 'different ABAP Language Versions' ). ENDIF. ENDLOOP. IF rv_abap_version IS INITIAL. set_abap_language_version( CHANGING cv_abap_language_version = rv_abap_version ). ENDIF. ENDMETHOD. METHOD includes. TYPES: BEGIN OF ty_reposrc, progname TYPE reposrc-progname, END OF ty_reposrc. DATA: lt_reposrc TYPE STANDARD TABLE OF ty_reposrc WITH DEFAULT KEY, ls_reposrc LIKE LINE OF lt_reposrc, lv_program TYPE program, lv_maintviewname LIKE LINE OF rt_includes, lv_offset_ns TYPE i, lv_tabix LIKE sy-tabix, lt_functab TYPE ty_rs38l_incl_tt, lt_tadir_includes TYPE HASHED TABLE OF objname WITH UNIQUE KEY table_line. FIELD-SYMBOLS: LIKE LINE OF rt_includes, LIKE LINE OF lt_functab. IF lines( mt_includes_cache ) > 0. rt_includes = mt_includes_cache. RETURN. ENDIF. lv_program = main_name( ). lt_functab = functions( ). CALL FUNCTION 'RS_GET_ALL_INCLUDES' EXPORTING program = lv_program TABLES includetab = rt_includes EXCEPTIONS not_existent = 1 no_program = 2 OTHERS = 3. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'Error from RS_GET_ALL_INCLUDES' ). ENDIF. LOOP AT lt_functab ASSIGNING . DELETE TABLE rt_includes FROM -include. ENDLOOP. * handle generated maintenance views IF ms_item-obj_name(1) <> '/'. "FGroup name does not contain a namespace lv_maintviewname = |L{ ms_item-obj_name }T00|. ELSE. "FGroup name contains a namespace lv_offset_ns = find( val = ms_item-obj_name+1 sub = '/' ). lv_offset_ns = lv_offset_ns + 2. lv_maintviewname = |{ ms_item-obj_name(lv_offset_ns) }L{ ms_item-obj_name+lv_offset_ns }T00|. ENDIF. READ TABLE rt_includes WITH KEY table_line = lv_maintviewname TRANSPORTING NO FIELDS. IF sy-subrc <> 0. APPEND lv_maintviewname TO rt_includes. ENDIF. SORT rt_includes. IF lines( rt_includes ) > 0. " check which includes have their own tadir entry " these includes might reside in a different package or might be shared between multiple function groups " or other programs and are hence no part of the to serialized FUGR object " they will be handled as individual objects when serializing their package " in addition, referenced XTI includes referencing (simple) transformations must be ignored SELECT obj_name INTO TABLE lt_tadir_includes FROM tadir FOR ALL ENTRIES IN rt_includes WHERE pgmid = 'R3TR' AND object = 'PROG' AND obj_name = rt_includes-table_line. LOOP AT rt_includes ASSIGNING . " skip autogenerated includes from Table Maintenance Generator IF CP 'LSVIM*'. DELETE rt_includes INDEX sy-tabix. CONTINUE. ENDIF. READ TABLE lt_tadir_includes WITH KEY table_line = TRANSPORTING NO FIELDS. IF sy-subrc = 0. DELETE rt_includes. CONTINUE. ENDIF. IF strlen( ) = 33 AND +30(3) = 'XTI'. "ignore referenced (simple) transformation includes DELETE rt_includes. CONTINUE. ENDIF. ENDLOOP. IF lines( rt_includes ) > 0. SELECT progname FROM reposrc INTO TABLE lt_reposrc FOR ALL ENTRIES IN rt_includes WHERE progname = rt_includes-table_line AND r3state = 'A'. ENDIF. SORT lt_reposrc BY progname ASCENDING. ENDIF. LOOP AT rt_includes ASSIGNING . lv_tabix = sy-tabix. * make sure the include exists READ TABLE lt_reposrc INTO ls_reposrc WITH KEY progname = BINARY SEARCH. IF sy-subrc <> 0. DELETE rt_includes INDEX lv_tabix. CONTINUE. ENDIF. "Make sure that the include does not belong to another function group IF is_part_of_other_fugr( ) = abap_true. DELETE rt_includes. ENDIF. ENDLOOP. APPEND lv_program TO rt_includes. SORT rt_includes. mt_includes_cache = rt_includes. ENDMETHOD. METHOD is_any_function_module_locked. DATA: lt_functions TYPE ty_rs38l_incl_tt. FIELD-SYMBOLS: TYPE rs38l_incl. TRY. lt_functions = functions( ). CATCH zcx_abapgit_exception. RETURN. ENDTRY. LOOP AT lt_functions ASSIGNING . IF exists_a_lock_entry_for( iv_lock_object = 'ESFUNCTION' iv_argument = |{ -funcname }| ) = abap_true. rv_any_function_module_locked = abap_true. EXIT. ENDIF. ENDLOOP. ENDMETHOD. METHOD is_any_include_locked. DATA: lt_includes TYPE ty_sobj_name_tt. FIELD-SYMBOLS: TYPE sobj_name. TRY. lt_includes = includes( ). CATCH zcx_abapgit_exception. RETURN. ENDTRY. LOOP AT lt_includes ASSIGNING . IF exists_a_lock_entry_for( iv_lock_object = 'ESRDIRE' iv_argument = |{ }| ) = abap_true. rv_is_any_include_locked = abap_true. EXIT. ENDIF. ENDLOOP. ENDMETHOD. METHOD is_function_group_locked. rv_is_functions_group_locked = exists_a_lock_entry_for( iv_lock_object = 'EEUDB' iv_argument = ms_item-obj_name iv_prefix = 'FG' ). ENDMETHOD. METHOD is_part_of_other_fugr. " make sure that the include belongs to the function group " like in LSEAPFAP Form TADIR_MAINTENANCE DATA ls_tadir TYPE tadir. DATA lv_namespace TYPE rs38l-namespace. DATA lv_function_group TYPE rs38l-area. DATA lv_include TYPE rs38l-include. DATA ls_item_key TYPE zif_abapgit_definitions=>ty_item. rv_belongs_to_other_fugr = abap_false. IF iv_include(1) = 'L' OR iv_include+1 CS '/L'. lv_include = iv_include. ls_tadir-object = 'FUGR'. CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT' IMPORTING namespace = lv_namespace group = lv_function_group CHANGING include = lv_include EXCEPTIONS OTHERS = 1 ##FM_SUBRC_OK. IF lv_function_group(1) = 'X'. " "EXIT"-function-module ls_tadir-object = 'FUGS'. ENDIF. IF sy-subrc = 0. CONCATENATE lv_namespace lv_function_group INTO ls_tadir-obj_name. ls_item_key-obj_type = ls_tadir-object. ls_item_key-obj_name = ls_tadir-obj_name. " compare complete tadir key to distinguish between regular and exit function groups IF ( ls_tadir-obj_name <> ms_item-obj_name OR ls_tadir-object <> ms_item-obj_type ) AND zcl_abapgit_objects=>exists( ls_item_key ) = abap_true. rv_belongs_to_other_fugr = abap_true. ENDIF. ENDIF. ENDIF. ENDMETHOD. METHOD main_name. DATA: lv_area TYPE rs38l-area, lv_namespace TYPE rs38l-namespace, lv_group TYPE rs38l-area. lv_area = ms_item-obj_name. CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT' EXPORTING complete_area = lv_area IMPORTING namespace = lv_namespace group = lv_group EXCEPTIONS include_not_exists = 1 group_not_exists = 2 no_selections = 3 no_function_include = 4 no_function_pool = 5 delimiter_wrong_position = 6 no_customer_function_group = 7 no_customer_function_include = 8 reserved_name_customer = 9 namespace_too_long = 10 area_length_error = 11 OTHERS = 12. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. CONCATENATE lv_namespace 'SAPL' lv_group INTO rv_program. ENDMETHOD. METHOD serialize_functions. DATA: lt_source TYPE TABLE OF rssource, lt_functab TYPE ty_rs38l_incl_tt, lt_new_source TYPE rsfb_source, ls_function LIKE LINE OF rt_functions. FIELD-SYMBOLS: LIKE LINE OF lt_functab, TYPE LINE OF ty_function-documentation. lt_functab = functions( ). LOOP AT lt_functab ASSIGNING . * fm RPY_FUNCTIONMODULE_READ does not support source code * lines longer than 72 characters CLEAR ls_function. MOVE-CORRESPONDING TO ls_function. CLEAR lt_new_source. CLEAR lt_source. CALL FUNCTION 'RPY_FUNCTIONMODULE_READ_NEW' EXPORTING functionname = -funcname IMPORTING global_flag = ls_function-global_flag remote_call = ls_function-remote_call update_task = ls_function-update_task short_text = ls_function-short_text remote_basxml_supported = ls_function-remote_basxml TABLES import_parameter = ls_function-import changing_parameter = ls_function-changing export_parameter = ls_function-export tables_parameter = ls_function-tables exception_list = ls_function-exception documentation = ls_function-documentation source = lt_source CHANGING new_source = lt_new_source EXCEPTIONS error_message = 1 function_not_found = 2 invalid_name = 3 OTHERS = 4. IF sy-subrc = 2. CONTINUE. ELSEIF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'Error from RPY_FUNCTIONMODULE_READ_NEW' ). ENDIF. LOOP AT ls_function-documentation ASSIGNING . CLEAR -index. ENDLOOP. SELECT SINGLE exten3 INTO ls_function-exception_classes FROM enlfdir WHERE funcname = -funcname. "#EC CI_SUBRC APPEND ls_function TO rt_functions. IF NOT lt_new_source IS INITIAL. strip_generation_comments( CHANGING ct_source = lt_new_source ). mo_files->add_abap( iv_extra = -funcname it_abap = lt_new_source ). ELSE. strip_generation_comments( CHANGING ct_source = lt_source ). mo_files->add_abap( iv_extra = -funcname it_abap = lt_source ). ENDIF. ENDLOOP. ENDMETHOD. METHOD serialize_function_docs. FIELD-SYMBOLS LIKE LINE OF it_functions. zcl_abapgit_factory=>get_longtexts( )->serialize( iv_longtext_id = c_longtext_id_prog iv_object_name = iv_prog_name io_i18n_params = mo_i18n_params ii_xml = ii_xml ). LOOP AT it_functions ASSIGNING . zcl_abapgit_factory=>get_longtexts( )->serialize( iv_longtext_name = |LONGTEXTS_{ -funcname }| iv_longtext_id = c_longtext_id_func iv_object_name = -funcname io_i18n_params = mo_i18n_params ii_xml = ii_xml ). zcl_abapgit_factory=>get_longtexts( )->serialize( iv_longtext_name = |LONGTEXTS_{ -funcname }___EXC| iv_longtext_id = c_longtext_id_func_exc iv_object_name = -funcname io_i18n_params = mo_i18n_params ii_xml = ii_xml ). ENDLOOP. ENDMETHOD. METHOD serialize_includes. DATA: lt_includes TYPE ty_sobj_name_tt. FIELD-SYMBOLS: LIKE LINE OF lt_includes. lt_includes = includes( ). LOOP AT lt_includes ASSIGNING . * todo, filename is not correct, a include can be used in several programs serialize_program( is_item = ms_item io_files = mo_files iv_program = iv_extra = ). ENDLOOP. ENDMETHOD. METHOD serialize_texts. DATA: lt_tpool_i18n TYPE ty_tpools_i18n, lt_tpool TYPE textpool_table. FIELD-SYMBOLS LIKE LINE OF lt_tpool_i18n. IF mo_i18n_params->ms_params-main_language_only = abap_true. RETURN. ENDIF. " Table d010tinf stores info. on languages in which program is maintained " Select all active translations of program texts " Skip main language - it was already serialized SELECT DISTINCT language INTO CORRESPONDING FIELDS OF TABLE lt_tpool_i18n FROM d010tinf WHERE r3state = 'A' AND prog = iv_prog_name AND language <> mv_language ORDER BY language ##TOO_MANY_ITAB_FIELDS. mo_i18n_params->trim_saplang_keyed_table( EXPORTING iv_lang_field_name = 'LANGUAGE' CHANGING ct_tab = lt_tpool_i18n ). SORT lt_tpool_i18n BY language ASCENDING. LOOP AT lt_tpool_i18n ASSIGNING . READ TEXTPOOL iv_prog_name LANGUAGE -language INTO lt_tpool. -textpool = add_tpool( lt_tpool ). ENDLOOP. IF lines( lt_tpool_i18n ) > 0. ii_xml->add( iv_name = 'I18N_TPOOL' ig_data = lt_tpool_i18n ). ENDIF. ENDMETHOD. METHOD serialize_xml. DATA: lt_includes TYPE ty_sobj_name_tt, lv_areat TYPE tlibt-areat. SELECT SINGLE areat INTO lv_areat FROM tlibt WHERE spras = mv_language AND area = ms_item-obj_name. "#EC CI_GENBUFF "#EC CI_SUBRC lt_includes = includes( ). ii_xml->add( iv_name = 'AREAT' ig_data = lv_areat ). ii_xml->add( iv_name = 'INCLUDES' ig_data = lt_includes ). ENDMETHOD. METHOD update_func_group_short_text. " We update the short text directly. " SE80 does the same in " Program SAPLSEUF / LSEUFF07 " FORM GROUP_CHANGE UPDATE tlibt SET areat = iv_short_text WHERE spras = mv_language AND area = iv_group. ENDMETHOD. METHOD update_where_used. * make extra sure the where-used list is updated after deletion * Experienced some problems with the T00 include * this method just tries to update everything DATA: lv_include LIKE LINE OF it_includes, lo_cross TYPE REF TO cl_wb_crossreference. LOOP AT it_includes INTO lv_include. CREATE OBJECT lo_cross EXPORTING p_name = lv_include p_include = lv_include. lo_cross->index_actualize( ). ENDLOOP. ENDMETHOD. METHOD zif_abapgit_object~changed_by. TYPES: BEGIN OF ty_stamps, user TYPE syuname, date TYPE d, time TYPE t, END OF ty_stamps. DATA: lt_stamps TYPE STANDARD TABLE OF ty_stamps WITH DEFAULT KEY, lv_program TYPE program, lv_found TYPE abap_bool, lt_functions TYPE ty_rs38l_incl_tt. FIELD-SYMBOLS: LIKE LINE OF lt_functions, LIKE LINE OF mt_includes_all, LIKE LINE OF lt_stamps. lv_program = main_name( ). IF mt_includes_all IS INITIAL. CALL FUNCTION 'RS_GET_ALL_INCLUDES' EXPORTING program = lv_program TABLES includetab = mt_includes_all EXCEPTIONS not_existent = 1 no_program = 2 OTHERS = 3. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'Error from RS_GET_ALL_INCLUDES' ). ENDIF. ENDIF. " Check if changed_by for include object was requested LOOP AT mt_includes_all ASSIGNING WHERE table_line = to_upper( iv_extra ). lv_program = . lv_found = abap_true. EXIT. ENDLOOP. " Check if changed_by for function module was requested lt_functions = functions( ). LOOP AT lt_functions ASSIGNING WHERE funcname = to_upper( iv_extra ). lv_program = -include. lv_found = abap_true. EXIT. ENDLOOP. SELECT unam AS user udat AS date utime AS time FROM reposrc APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps WHERE progname = lv_program AND r3state = 'A' ORDER BY PRIMARY KEY. "#EC CI_SUBRC IF mt_includes_all IS NOT INITIAL AND lv_found = abap_false. SELECT unam AS user udat AS date utime AS time FROM reposrc APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps FOR ALL ENTRIES IN mt_includes_all WHERE progname = mt_includes_all-table_line AND r3state = 'A'. "#EC CI_SUBRC ENDIF. SELECT unam AS user udat AS date utime AS time FROM repotext " Program text pool APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps WHERE progname = lv_program AND r3state = 'A' ORDER BY PRIMARY KEY. "#EC CI_SUBRC SELECT vautor AS user vdatum AS date vzeit AS time FROM eudb " GUI APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps WHERE relid = 'CU' AND name = lv_program AND srtf2 = 0 ORDER BY PRIMARY KEY ##TOO_MANY_ITAB_FIELDS. * Screens: username not stored in D020S database table SORT lt_stamps BY date DESCENDING time DESCENDING. READ TABLE lt_stamps INDEX 1 ASSIGNING . IF sy-subrc = 0. rv_user = -user. ELSE. rv_user = c_user_unknown. ENDIF. ENDMETHOD. METHOD zif_abapgit_object~delete. DATA: lv_area TYPE rs38l-area, lt_includes TYPE ty_sobj_name_tt. " FUGR related to change documents will be deleted by CHDO SELECT SINGLE fgrp FROM tcdrps INTO lv_area WHERE fgrp = ms_item-obj_name. IF sy-subrc = 0. RETURN. ENDIF. lt_includes = includes( ). lv_area = ms_item-obj_name. CALL FUNCTION 'RS_FUNCTION_POOL_DELETE' EXPORTING area = lv_area suppress_popups = abap_true skip_progress_ind = abap_true corrnum = iv_transport EXCEPTIONS canceled_in_corr = 1 enqueue_system_failure = 2 function_exist = 3 not_executed = 4 no_modify_permission = 5 no_show_permission = 6 permission_failure = 7 pool_not_exist = 8 cancelled = 9 OTHERS = 10. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. update_where_used( lt_includes ). ENDMETHOD. METHOD zif_abapgit_object~deserialize. DATA: lv_program_name TYPE syrepid, lv_abap_version TYPE trdir-uccheck, lt_functions TYPE ty_function_tt, lt_dynpros TYPE ty_dynpro_tt, ls_cua TYPE ty_cua. lv_abap_version = get_abap_version( io_xml ). deserialize_xml( ii_xml = io_xml iv_version = lv_abap_version iv_package = iv_package iv_transport = iv_transport ). io_xml->read( EXPORTING iv_name = 'FUNCTIONS' CHANGING cg_data = lt_functions ). deserialize_functions( it_functions = lt_functions ii_log = ii_log iv_version = lv_abap_version iv_package = iv_package iv_transport = iv_transport ). deserialize_includes( ii_xml = io_xml iv_package = iv_package ii_log = ii_log ). lv_program_name = main_name( ). IF mo_i18n_params->is_lxe_applicable( ) = abap_false. deserialize_texts( iv_prog_name = lv_program_name ii_xml = io_xml ). ENDIF. io_xml->read( EXPORTING iv_name = 'DYNPROS' CHANGING cg_data = lt_dynpros ). deserialize_dynpros( lt_dynpros ). io_xml->read( EXPORTING iv_name = 'CUA' CHANGING cg_data = ls_cua ). deserialize_cua( iv_program_name = lv_program_name is_cua = ls_cua ). deserialize_function_docs( iv_prog_name = lv_program_name it_functions = lt_functions ii_xml = io_xml ). ENDMETHOD. METHOD zif_abapgit_object~exists. DATA: lv_pool TYPE tlibg-area. lv_pool = ms_item-obj_name. CALL FUNCTION 'RS_FUNCTION_POOL_EXISTS' EXPORTING function_pool = lv_pool EXCEPTIONS pool_not_exists = 1. rv_bool = boolc( sy-subrc <> 1 ). " Skip FUGR generated by CHDO IF rv_bool = abap_true. SELECT SINGLE fgrp FROM tcdrp INTO lv_pool WHERE fgrp = lv_pool. IF sy-subrc = 0. rv_bool = abap_false. ENDIF. ENDIF. ENDMETHOD. METHOD zif_abapgit_object~get_comparator. RETURN. ENDMETHOD. METHOD zif_abapgit_object~get_deserialize_order. 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. DATA: lv_program TYPE program. lv_program = main_name( ). IF is_function_group_locked( ) = abap_true OR is_any_include_locked( ) = abap_true OR is_any_function_module_locked( ) = abap_true OR is_any_dynpro_locked( lv_program ) = abap_true OR is_cua_locked( lv_program ) = abap_true OR is_text_locked( lv_program ) = abap_true. rv_is_locked = abap_true. ENDIF. ENDMETHOD. METHOD zif_abapgit_object~jump. DATA: ls_item TYPE zif_abapgit_definitions=>ty_item, lt_functions TYPE ty_rs38l_incl_tt, lt_includes TYPE ty_sobj_name_tt. FIELD-SYMBOLS: LIKE LINE OF lt_functions, LIKE LINE OF lt_includes. ls_item-obj_type = 'PROG'. ls_item-obj_name = to_upper( iv_extra ). lt_functions = functions( ). LOOP AT lt_functions ASSIGNING WHERE funcname = ls_item-obj_name. ls_item-obj_name = -include. rv_exit = zcl_abapgit_objects_factory=>get_gui_jumper( )->jump( ls_item ). IF rv_exit = abap_true. RETURN. ENDIF. ENDLOOP. lt_includes = includes( ). LOOP AT lt_includes ASSIGNING WHERE table_line = ls_item-obj_name. rv_exit = zcl_abapgit_objects_factory=>get_gui_jumper( )->jump( ls_item ). IF rv_exit = abap_true. RETURN. ENDIF. ENDLOOP. " Otherwise covered by ZCL_ABAPGIT_OBJECTS=>JUMP ENDMETHOD. METHOD zif_abapgit_object~map_filename_to_object. RETURN. ENDMETHOD. METHOD zif_abapgit_object~map_object_to_filename. RETURN. ENDMETHOD. METHOD zif_abapgit_object~serialize. * function group SEUF * function group SIFP * function group SUNI DATA: lt_functions TYPE ty_function_tt, ls_progdir TYPE zif_abapgit_sap_report=>ty_progdir, lv_program_name TYPE syrepid, lt_dynpros TYPE ty_dynpro_tt, ls_cua TYPE ty_cua. IF zif_abapgit_object~exists( ) = abap_false. RETURN. ENDIF. serialize_xml( io_xml ). lt_functions = serialize_functions( ). io_xml->add( iv_name = 'FUNCTIONS' ig_data = lt_functions ). serialize_includes( ). lv_program_name = main_name( ). ls_progdir = zcl_abapgit_factory=>get_sap_report( )->read_progdir( lv_program_name ). IF mo_i18n_params->is_lxe_applicable( ) = abap_false. serialize_texts( iv_prog_name = lv_program_name ii_xml = io_xml ). ENDIF. IF ls_progdir-subc = 'F'. lt_dynpros = serialize_dynpros( lv_program_name ). io_xml->add( iv_name = 'DYNPROS' ig_data = lt_dynpros ). ls_cua = serialize_cua( lv_program_name ). io_xml->add( iv_name = 'CUA' ig_data = ls_cua ). ENDIF. serialize_function_docs( iv_prog_name = lv_program_name it_functions = lt_functions ii_xml = io_xml ). ENDMETHOD. ENDCLASS.