abapGit/src/objects/zcl_abapgit_object_otgr.clas.abap
Marc Bernard 73576ee60e
Improve error messages (#4472)
* Improve error messages

Pass T100 messages to UI/log

* T100 errors

* APACK

* OO

* DEVC

* DRUL

* DTDC

* SRVB

* OBJS

* Program

Co-authored-by: Lars Hvam <larshp@hotmail.com>
2021-02-03 16:31:55 +01:00

367 lines
12 KiB
ABAP

CLASS zcl_abapgit_object_otgr DEFINITION
PUBLIC
INHERITING FROM zcl_abapgit_objects_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_object .
PROTECTED SECTION.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_otgr,
cls_type_group TYPE cls_type_group,
texts TYPE STANDARD TABLE OF cls_type_groupt WITH DEFAULT KEY,
elements TYPE STANDARD TABLE OF cls_tygr_element WITH DEFAULT KEY,
END OF ty_otgr .
METHODS instantiate_and_lock_otgr
RETURNING
VALUE(ro_otgr) TYPE REF TO cl_cls_object_type_group
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_object_otgr IMPLEMENTATION.
METHOD instantiate_and_lock_otgr.
DATA: lv_new TYPE abap_bool,
lv_name TYPE cls_attribute_name.
SELECT SINGLE name FROM cls_type_group INTO lv_name WHERE name = ms_item-obj_name.
lv_new = boolc( sy-subrc <> 0 ).
lv_name = ms_item-obj_name.
TRY.
CREATE OBJECT ro_otgr
EXPORTING
im_name = lv_name
im_new = lv_new.
CATCH cx_pak_invalid_data
cx_pak_not_authorized
cx_pak_invalid_state
cx_pak_wb_object_locked.
zcx_abapgit_exception=>raise( |OTGR { lv_name }: error while instantiating CL_CLS_OBJECT_TYPE_GROUP| ).
ENDTRY.
IF lv_new = abap_false.
TRY.
ro_otgr->if_pak_wb_object~lock_and_refresh( ).
CATCH cx_pak_invalid_data
cx_pak_not_authorized
cx_pak_invalid_state
cx_pak_wb_object_locked.
zcx_abapgit_exception=>raise( |OTGR { lv_name }: could not aquire lock| ).
ENDTRY.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE changed_by FROM cls_type_group INTO rv_user
WHERE name = ms_item-obj_name
AND activation_state = cl_pak_wb_domains=>co_activation_state-active.
IF rv_user IS INITIAL.
SELECT SINGLE created_by FROM cls_type_group INTO rv_user
WHERE name = ms_item-obj_name
AND activation_state = cl_pak_wb_domains=>co_activation_state-active.
ENDIF.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_otgr TYPE REF TO cl_cls_object_type_group,
lx_pak_error TYPE REF TO cx_root,
lv_text TYPE string.
lo_otgr = instantiate_and_lock_otgr( ).
TRY.
lo_otgr->if_pak_wb_object~delete( ).
lo_otgr->if_pak_wb_object~save( ).
lo_otgr->unlock( ).
CATCH cx_pak_invalid_state cx_pak_invalid_data cx_pak_not_authorized INTO lx_pak_error.
lo_otgr->unlock( ).
lv_text = lx_pak_error->get_text( ).
zcx_abapgit_exception=>raise( |OTGR { ms_item-obj_name }: delete: { lv_text }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_otgr TYPE ty_otgr,
lo_otgr TYPE REF TO cl_cls_object_type_group,
lx_pak_error TYPE REF TO cx_root,
lv_text TYPE string,
lv_main_lang TYPE sy-langu,
lo_parents TYPE REF TO data.
FIELD-SYMBOLS: <ls_groupt> LIKE LINE OF ls_otgr-texts,
<ls_element> LIKE LINE OF ls_otgr-elements,
<lv_field> TYPE any,
<ls_parent> TYPE any,
<lt_parents> TYPE ANY TABLE.
io_xml->read( EXPORTING iv_name = 'OTGR'
CHANGING cg_data = ls_otgr ).
LOOP AT ls_otgr-texts ASSIGNING <ls_groupt>.
<ls_groupt>-activation_state = cl_pak_wb_domains=>co_activation_state-inactive.
" Removed in the method serialize.
<ls_groupt>-name = ms_item-obj_name.
ENDLOOP.
" Parents (cls_tygr_parent) does not exist in lower releases
TRY.
CREATE DATA lo_parents TYPE TABLE OF ('CLS_TYGR_PARENT').
ASSIGN lo_parents->* TO <lt_parents>.
CATCH cx_sy_create_data_error.
ENDTRY.
IF <lt_parents> IS ASSIGNED.
io_xml->read( EXPORTING iv_name = 'PARENTS'
CHANGING cg_data = <lt_parents> ).
LOOP AT <lt_parents> ASSIGNING <ls_parent>.
ASSIGN COMPONENT 'ACTIVATION_STATE' OF STRUCTURE <ls_parent> TO <lv_field>.
IF sy-subrc = 0.
<lv_field> = cl_pak_wb_domains=>co_activation_state-inactive.
ENDIF.
ASSIGN COMPONENT 'OBJ_TYPE_GROUP' OF STRUCTURE <ls_parent> TO <lv_field>.
IF sy-subrc = 0.
" Removed in the method serialize.
<lv_field> = ms_item-obj_name.
ENDIF.
ENDLOOP.
ENDIF.
LOOP AT ls_otgr-elements ASSIGNING <ls_element>.
<ls_element>-activation_state = cl_pak_wb_domains=>co_activation_state-inactive.
" Removed in the method serialize.
<ls_element>-obj_type_group = ms_item-obj_name.
ENDLOOP.
tadir_insert( iv_package ).
lo_otgr = instantiate_and_lock_otgr( ).
TRY.
lo_otgr->if_cls_object_type_group~set_proxy_filter( ls_otgr-cls_type_group-proxy_flag ).
lo_otgr->if_cls_object_type_group~set_elements( ls_otgr-elements ).
IF <lt_parents> IS ASSIGNED.
CALL METHOD lo_otgr->('IF_CLS_OBJECT_TYPE_GROUP~SET_PARENT_GROUPS')
EXPORTING
im_parent_groups = <lt_parents>.
ENDIF.
lv_main_lang = lo_otgr->if_pak_wb_object~get_master_language( ).
READ TABLE ls_otgr-texts WITH KEY langu = lv_main_lang ASSIGNING <ls_groupt>.
IF sy-subrc = 0.
lo_otgr->set_description( <ls_groupt>-text ).
" ELSE.
" Do we want to clear the main language description if not present in the XML conent?
" Main language is non-deterministic - it depends on sy-langu, so rather don't touch
" description if the main language is not present
" Perhaps, we can display some sort of a message but how?
ENDIF.
set_default_package( iv_package ).
lo_otgr->if_pak_wb_object~save( ).
lo_otgr->if_pak_wb_object~activate( ).
lo_otgr->unlock( ).
CATCH cx_pak_invalid_state cx_pak_invalid_data cx_pak_not_authorized INTO lx_pak_error.
lo_otgr->unlock( ).
lv_text = lx_pak_error->get_text( ).
zcx_abapgit_exception=>raise( |OTGR { ms_item-obj_name }: deserialize: { lv_text }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
rv_bool = cl_cls_object_type_group=>exists_object_type_group( ms_item-obj_name ).
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 = exists_a_lock_entry_for( iv_lock_object = 'ECLS_ATTRIBUTE'
iv_argument = |{ ms_item-obj_name }*| ).
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
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_text TYPE string,
ls_otgr TYPE ty_otgr,
lo_otgr TYPE REF TO cl_cls_object_type_group,
lx_pak_error TYPE REF TO cx_root,
lo_parents TYPE REF TO data.
FIELD-SYMBOLS: <ls_groupt> LIKE LINE OF ls_otgr-texts,
<ls_element> LIKE LINE OF ls_otgr-elements,
<lv_field> TYPE any,
<ls_parent> TYPE any,
<lt_parents> TYPE ANY TABLE.
lo_otgr = instantiate_and_lock_otgr( ).
* Description part 1:
* Dealing with Description of OTGR objects is problematic.
* The API supports setting of main language only and
* if we want to save also translations we would have to implement
* our own logic for merging and activation. To keep it simple stupid
* the current version focuses on the main language only.
* If anybody ever runs into the need to version also translation,
* ask the maintainers of CL_CLS_OBJECT_TYPE_GROUP to add a method for it.
*
* However, the XML content will pretend we support also translations,
* so if someone adds support for them in future, there will be no format change.
APPEND INITIAL LINE TO ls_otgr-texts ASSIGNING <ls_groupt>.
" Parents (cls_tygr_parent) does not exist in lower releases
TRY.
CREATE DATA lo_parents TYPE TABLE OF ('CLS_TYGR_PARENT').
ASSIGN lo_parents->* TO <lt_parents>.
CATCH cx_sy_create_data_error.
ENDTRY.
TRY.
ls_otgr-cls_type_group-name = lo_otgr->if_cls_object_type_group~get_name( ).
ls_otgr-cls_type_group-proxy_flag = lo_otgr->if_cls_object_type_group~get_proxy_filter( ).
lo_otgr->get_elements( IMPORTING ex_elements = ls_otgr-elements ).
IF <lt_parents> IS ASSIGNED.
CALL METHOD lo_otgr->('IF_CLS_OBJECT_TYPE_GROUP~GET_PARENT_GROUPS')
EXPORTING
im_explicit_parents_only = abap_true
IMPORTING
ex_parent_groups = <lt_parents>.
ENDIF.
" Beware: the following method returns the main language description only if the object is locked!
<ls_groupt>-text = lo_otgr->if_cls_object_type_group~get_description( ).
<ls_groupt>-langu = lo_otgr->if_pak_wb_object~get_master_language( ).
lo_otgr->unlock( ).
CATCH cx_pak_invalid_state cx_pak_invalid_data cx_pak_not_authorized INTO lx_pak_error.
lo_otgr->unlock( ).
lv_text = lx_pak_error->get_text( ).
zcx_abapgit_exception=>raise( |OTGR { ms_item-obj_name }: serialize: { lv_text }| ).
ENDTRY.
CLEAR: ls_otgr-cls_type_group-created_by,
ls_otgr-cls_type_group-created_on,
ls_otgr-cls_type_group-changed_by,
ls_otgr-cls_type_group-changed_on.
* Description part 2:
*
* lt_lang_sel TYPE RANGE OF langu,
* ls_lang_sel LIKE LINE OF lt_lang_sel,
*
* IF io_xml->i18n_params( )-main_language_only = abap_true.
* ls_lang_sel-low = mv_language.
* ls_lang_sel-sign = 'I'.
* ls_lang_sel-option = 'EQ'.
* ENDIF.
*
* SELECT * FROM cls_type_groupt INTO TABLE ls_otgr-texts
* WHERE name = ms_item-obj_name
* AND activation_state = 'A'
* AND langu in lt_lang_sel.
*
* Description ideas end
LOOP AT ls_otgr-texts ASSIGNING <ls_groupt>.
" Not necessary as we serialize only Active
CLEAR <ls_groupt>-activation_state.
" Not necessary as we have it in the root XML node
CLEAR <ls_groupt>-name.
ENDLOOP.
LOOP AT ls_otgr-elements ASSIGNING <ls_element>.
" Not necessary as we serialize only Active
CLEAR <ls_element>-activation_state.
" Not necessary as we have it in the root XML node
CLEAR <ls_element>-obj_type_group.
ENDLOOP.
io_xml->add( iv_name = 'OTGR'
ig_data = ls_otgr ).
IF <lt_parents> IS ASSIGNED.
LOOP AT <lt_parents> ASSIGNING <ls_parent>.
ASSIGN COMPONENT 'ACTIVATION_STATE' OF STRUCTURE <ls_parent> TO <lv_field>.
IF sy-subrc = 0.
" Not necessary as we serialize only Active
CLEAR <lv_field>.
ENDIF.
ASSIGN COMPONENT 'OBJ_TYPE_GROUP' OF STRUCTURE <ls_parent> TO <lv_field>.
IF sy-subrc = 0.
" Not necessary as we have it in the root XML node
CLEAR <lv_field>.
ENDIF.
ENDLOOP.
io_xml->add( iv_name = 'PARENTS'
ig_data = <lt_parents> ).
ENDIF.
ENDMETHOD.
ENDCLASS.