CLASS zcl_abapgit_gui_page_debuginfo DEFINITION PUBLIC INHERITING FROM zcl_abapgit_gui_component FINAL CREATE PRIVATE . PUBLIC SECTION. INTERFACES zif_abapgit_gui_event_handler . INTERFACES zif_abapgit_gui_renderable . CLASS-METHODS create RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_renderable RAISING zcx_abapgit_exception . PROTECTED SECTION. PRIVATE SECTION. CONSTANTS c_exit_standalone TYPE syrepid VALUE 'ZABAPGIT_USER_EXIT' ##NO_TEXT. CONSTANTS c_exit_class TYPE c LENGTH 30 VALUE 'ZCL_ABAPGIT_USER_EXIT' ##NO_TEXT. CONSTANTS c_exit_interface TYPE c LENGTH 30 VALUE 'ZIF_ABAPGIT_EXIT' ##NO_TEXT. CONSTANTS: BEGIN OF c_action, save TYPE string VALUE 'save', END OF c_action. DATA mv_html TYPE string . CLASS-METHODS build_toolbar RETURNING VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar. METHODS render_debug_info RETURNING VALUE(ri_html) TYPE REF TO zif_abapgit_html RAISING zcx_abapgit_exception . METHODS render_exit_info RETURNING VALUE(ri_html) TYPE REF TO zif_abapgit_html RAISING zcx_abapgit_exception . METHODS render_exit_info_methods IMPORTING !it_source TYPE string_table !iv_clsname TYPE seoclsname OPTIONAL RETURNING VALUE(ri_html) TYPE REF TO zif_abapgit_html RAISING zcx_abapgit_exception . METHODS render_supported_object_types RETURNING VALUE(rv_html) TYPE string . METHODS render_scripts RETURNING VALUE(ri_html) TYPE REF TO zif_abapgit_html RAISING zcx_abapgit_exception . METHODS get_jump_object IMPORTING !iv_obj_type TYPE csequence DEFAULT 'CLAS' !iv_obj_name TYPE csequence RETURNING VALUE(rv_html) TYPE string . ENDCLASS. CLASS zcl_abapgit_gui_page_debuginfo IMPLEMENTATION. METHOD build_toolbar. CREATE OBJECT ro_menu EXPORTING iv_id = 'toolbar-debug'. ro_menu->add( iv_txt = 'Save' iv_act = c_action-save ). ro_menu->add( iv_txt = 'Back' iv_act = zif_abapgit_definitions=>c_action-go_back ). ENDMETHOD. METHOD create. DATA lo_component TYPE REF TO zcl_abapgit_gui_page_debuginfo. CREATE OBJECT lo_component. ri_page = zcl_abapgit_gui_page_hoc=>create( iv_page_title = 'Debug Info' io_page_menu = build_toolbar( ) ii_child_component = lo_component ). ENDMETHOD. METHOD get_jump_object. DATA lv_encode TYPE string. DATA li_html TYPE REF TO zif_abapgit_html. CREATE OBJECT li_html TYPE zcl_abapgit_html. lv_encode = zcl_abapgit_html_action_utils=>jump_encode( iv_obj_type = |{ iv_obj_type }| iv_obj_name = |{ iv_obj_name }| ). rv_html = li_html->a( iv_txt = |{ iv_obj_name }| iv_act = |{ zif_abapgit_definitions=>c_action-jump }?{ lv_encode }| ). ENDMETHOD. METHOD render_debug_info. DATA: ls_release TYPE zif_abapgit_environment=>ty_release_sp, lv_gui_version TYPE string, lv_devclass TYPE devclass, lo_frontend_serv TYPE REF TO zif_abapgit_frontend_services. lo_frontend_serv = zcl_abapgit_ui_factory=>get_frontend_services( ). TRY. lo_frontend_serv->get_gui_version( IMPORTING ev_gui_version_string = lv_gui_version ). CATCH zcx_abapgit_exception ##NO_HANDLER. " Continue rendering even if this fails ENDTRY. CREATE OBJECT ri_html TYPE zcl_abapgit_html. IF zcl_abapgit_factory=>get_environment( )->is_merged( ) = abap_true. ri_html->add( '

abapGit - Standalone Version

' ). ri_html->add( '
To keep abapGit up-to-date (or also to contribute) you need to' ). ri_html->add( |install it as a repository ({ ri_html->a( iv_txt = 'Developer Version' iv_act = 'https://github.com/abapGit/abapGit' iv_typ = zif_abapgit_html=>c_action_type-url ) }).
| ). ELSE. lv_devclass = zcl_abapgit_factory=>get_tadir( )->get_object_package( iv_object = 'CLAS' iv_obj_name = 'ZCX_ABAPGIT_EXCEPTION' ). ri_html->add( '

abapGit - Developer Version

' ). ri_html->add( |
abapGit is installed in package { lv_devclass }
| ). ENDIF. ri_html->add( '
' ). ri_html->add_a( iv_txt = 'Contribution guidelines for abapGit' iv_act = |{ zif_abapgit_definitions=>c_action-url }?url=https://github.com/abapGit/abapGit/blob/main/CONTRIBUTING.md| iv_class = |url| ). ri_html->add( '
' ). ls_release = zcl_abapgit_factory=>get_environment( )->get_basis_release( ). ri_html->add( '

Environment

' ). ri_html->add( || ). ri_html->add( || ). ri_html->add( || ). ri_html->add( || ). ri_html->add( || ). ri_html->add( || ). ri_html->add( || ). ri_html->add( || ). ri_html->add( |
abapGit version:{ zif_abapgit_version=>c_abap_version }
XML version: { zif_abapgit_version=>c_xml_version }
GUI version: { lv_gui_version }
APACK version: { zcl_abapgit_apack_migration=>c_apack_interface_version }
LCL_TIME: { zcl_abapgit_git_time=>get_unix( ) }
SY time: { sy-datum } { sy-uzeit } { sy-tzone }
SY release: { ls_release-release } SP { ls_release-sp }
| ). ri_html->add( |
| ). ENDMETHOD. METHOD render_exit_info. DATA lt_source TYPE string_table. DATA ls_class_key TYPE seoclskey. DATA lo_oo_serializer TYPE REF TO zcl_abapgit_oo_serializer. DATA lo_class TYPE REF TO cl_oo_class. CREATE OBJECT ri_html TYPE zcl_abapgit_html. ri_html->add( '

User Exits

' ). IF zcl_abapgit_factory=>get_environment( )->is_merged( ) = abap_true. " Standalone version lt_source = zcl_abapgit_factory=>get_sap_report( )->read_report( c_exit_standalone ). IF sy-subrc = 0. ri_html->add( |
User exits are active (include { get_jump_object( iv_obj_type = 'PROG' iv_obj_name = c_exit_standalone ) } found)

| ). ri_html->add( render_exit_info_methods( lt_source ) ). ELSE. ri_html->add( |
No user exits implemented (include { c_exit_standalone } not found)

| ). ENDIF. ELSE. " Developer version TRY. ls_class_key-clsname = c_exit_class. DO. CREATE OBJECT lo_oo_serializer. lt_source = lo_oo_serializer->serialize_abap_clif_source( ls_class_key ). ri_html->add( '
' ). ri_html->add( |User exits are active (class { get_jump_object( ls_class_key-clsname ) } found)| ). ri_html->add( '

' ). ri_html->add( render_exit_info_methods( it_source = lt_source iv_clsname = ls_class_key-clsname ) ). " Is there a super class of exit? CREATE OBJECT lo_class EXPORTING clsname = ls_class_key-clsname. ls_class_key-clsname = lo_class->get_superclass( ). IF ls_class_key-clsname IS INITIAL. EXIT. ENDIF. ri_html->add( '
' ). ENDDO. CATCH cx_root. ri_html->add( |
No user exits implemented (class { c_exit_class } not found)

| ). ENDTRY. ENDIF. ENDMETHOD. METHOD render_exit_info_methods. DATA: lo_scanner TYPE REF TO cl_oo_source_scanner_class, lx_exc TYPE REF TO cx_root, lt_methods TYPE cl_oo_source_scanner_class=>type_method_implementations, lv_method LIKE LINE OF lt_methods, lt_source TYPE seop_source_string, lv_count TYPE i, lv_source TYPE string, lv_rest TYPE string. CREATE OBJECT ri_html TYPE zcl_abapgit_html. ri_html->add( '' ). ri_html->add( '' ). ri_html->add( '' ). TRY. lo_scanner = cl_oo_source_scanner_class=>create_class_scanner( clif_name = iv_clsname source = it_source ). lo_scanner->scan( ). lt_methods = lo_scanner->get_method_implementations( ). LOOP AT lt_methods INTO lv_method WHERE table_line CS c_exit_interface. lt_source = lo_scanner->get_method_impl_source( lv_method ). DELETE lt_source INDEX 1. DELETE lt_source INDEX lines( lt_source ). CONCATENATE LINES OF lt_source INTO lv_source. lv_source = to_upper( condense( val = lv_source del = ` ` ) ). SPLIT lv_method AT '~' INTO lv_rest lv_method. ri_html->add( || ). lv_count = lv_count + 1. ENDLOOP. IF lv_count = 0. ri_html->add( || ). ENDIF. CATCH cx_root INTO lx_exc. ri_html->add( || ). ENDTRY. ri_html->add( '
ExitImplemented?
{ lv_method }| ). IF lv_source IS INITIAL OR lv_source = 'RETURN.' OR lv_source = 'EXIT.'. ri_html->add( 'No' ). ELSE. ri_html->add( 'Yes' ). ENDIF. ri_html->add( |
No exit methods implemented
{ lx_exc->get_text( ) }
' ). ENDMETHOD. METHOD render_scripts. CREATE OBJECT ri_html TYPE zcl_abapgit_html. ri_html->set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ). ri_html->add( 'debugOutput("
Browser:" + navigator.userAgent + ' && '"
Frontend time:" + new Date() + "
", "debug_info");' ). ENDMETHOD. METHOD render_supported_object_types. DATA: lv_list TYPE string, li_html TYPE REF TO zif_abapgit_html, lt_types TYPE zcl_abapgit_objects=>ty_types_tt, lv_type LIKE LINE OF lt_types, lt_obj TYPE STANDARD TABLE OF ko100 WITH DEFAULT KEY, lv_class TYPE seoclsname, li_object TYPE REF TO zif_abapgit_object, ls_item TYPE zif_abapgit_definitions=>ty_item, ls_metadata TYPE zif_abapgit_definitions=>ty_metadata, lv_step TYPE zif_abapgit_definitions=>ty_deserialization_step, lt_steps TYPE zif_abapgit_definitions=>ty_deserialization_step_tt. FIELD-SYMBOLS: TYPE ko100. CALL FUNCTION 'TR_OBJECT_TABLE' TABLES wt_object_text = lt_obj. lt_types = zcl_abapgit_objects=>supported_list( ). CREATE OBJECT li_html TYPE zcl_abapgit_html. rv_html = '

Object Types

'. rv_html = rv_html && li_html->a( iv_txt = 'Complete list of object types supported by abapGit' iv_act = |{ zif_abapgit_definitions=>c_action-url }?url=https://docs.abapgit.org/ref-supported.html| iv_class = |url| ). rv_html = rv_html && |

Supported object types in this system:

|. rv_html = rv_html && ||. rv_html = rv_html && ||. rv_html = rv_html && ||. rv_html = rv_html && ||. LOOP AT lt_types INTO lv_type. lv_class = 'ZCL_ABAPGIT_OBJECT_' && lv_type. rv_html = rv_html && ||. rv_html = rv_html && ||. READ TABLE lt_obj ASSIGNING WITH KEY pgmid = 'R3TR' object = lv_type. IF sy-subrc = 0. rv_html = rv_html && ||. ELSE. rv_html = rv_html && ||. ENDIF. TRY. ls_item-obj_type = lv_type. ls_item-obj_name = 'TEST'. CREATE OBJECT li_object TYPE (lv_class) EXPORTING is_item = ls_item iv_language = sy-langu. rv_html = rv_html && ||. CATCH cx_sy_create_object_error zcx_abapgit_exception. TRY. " 2nd step, try looking for plugins CREATE OBJECT li_object TYPE zcl_abapgit_objects_bridge EXPORTING is_item = ls_item. CATCH cx_sy_create_object_error zcx_abapgit_exception. rv_html = rv_html && ||. CONTINUE. ENDTRY. rv_html = rv_html && ||. ENDTRY. ls_metadata = li_object->get_metadata( ). rv_html = rv_html && ||. lt_steps = li_object->get_deserialize_steps( ). CLEAR lv_list. LOOP AT lt_steps INTO lv_step. CASE lv_step. WHEN zif_abapgit_object=>gc_step_id-early. lv_step = |{ lv_step } (1)|. WHEN zif_abapgit_object=>gc_step_id-ddic. lv_step = |{ lv_step } (2)|. WHEN zif_abapgit_object=>gc_step_id-abap. lv_step = |{ lv_step } (3)|. WHEN zif_abapgit_object=>gc_step_id-late. lv_step = |{ lv_step } (4)|. WHEN OTHERS. ASSERT 1 = 2. ENDCASE. IF lv_list IS INITIAL. lv_list = lv_step. ELSE. lv_list = lv_list && `, ` && lv_step. ENDIF. ENDLOOP. rv_html = rv_html && ||. rv_html = rv_html && ||. ENDLOOP. rv_html = rv_html && |
ObjectDescriptionClassVersionSteps
{ lv_type }{ -text }No description{ get_jump_object( lv_class ) }{ lv_class } - error instantiating class{ get_jump_object( lv_class ) } (Plug-in){ ls_metadata-version }{ lv_list }
|. rv_html = rv_html && |
|. ENDMETHOD. METHOD zif_abapgit_gui_event_handler~on_event. DATA: lv_path TYPE string, lv_filename TYPE string, li_fe_serv TYPE REF TO zif_abapgit_frontend_services. CASE ii_event->mv_action. WHEN c_action-save. CONCATENATE 'abapGit_Debug_Info_' sy-datlo '_' sy-timlo '.html' INTO lv_filename. li_fe_serv = zcl_abapgit_ui_factory=>get_frontend_services( ). lv_path = li_fe_serv->show_file_save_dialog( iv_title = 'abapGit - Debug Info' iv_extension = 'html' iv_default_filename = lv_filename ). li_fe_serv->file_download( iv_path = lv_path iv_xstr = zcl_abapgit_convert=>string_to_xstring_utf8( mv_html ) ). MESSAGE 'abapGit Debug Info successfully saved' TYPE 'S'. rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. WHEN OTHERS. ASSERT 1 = 1. ENDCASE. ENDMETHOD. METHOD zif_abapgit_gui_renderable~render. register_handlers( ). CREATE OBJECT ri_html TYPE zcl_abapgit_html. ri_html->add( '
' ). ri_html->add( render_debug_info( ) ). ri_html->add( '
' ). ri_html->add( '
' ). ri_html->add( render_exit_info( ) ). ri_html->add( '
' ). ri_html->add( '
' ). ri_html->add( render_supported_object_types( ) ). ri_html->add( '
' ). mv_html = 'abapGit Debug Info'. mv_html = |{ ri_html->render( ) }|. register_deferred_script( render_scripts( ) ). ENDMETHOD. ENDCLASS.