CLASS zcl_abapgit_object_tabl DEFINITION PUBLIC INHERITING FROM zcl_abapgit_objects_super FINAL. PUBLIC SECTION. INTERFACES zif_abapgit_object. ALIASES mo_files FOR zif_abapgit_object~mo_files. PROTECTED SECTION. TYPES: BEGIN OF ty_segment_definition, segmentheader TYPE edisegmhd, segmentdefinition TYPE edisegmdef, segmentstructures TYPE STANDARD TABLE OF edisegstru WITH DEFAULT KEY, END OF ty_segment_definition. TYPES: ty_segment_definitions TYPE STANDARD TABLE OF ty_segment_definition WITH DEFAULT KEY. "! Serialize IDoc Segment type/definition if exits "! @parameter io_xml | XML writer "! @raising zcx_abapgit_exception | Exceptions METHODS serialize_idoc_segment IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output RAISING zcx_abapgit_exception. "! Deserialize IDoc Segment type/definition if exits "! @parameter io_xml | XML writer "! @parameter iv_package | Target package "! @parameter rv_deserialized | It's a segment and was desserialized "! @raising zcx_abapgit_exception | Exceptions METHODS deserialize_idoc_segment IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input iv_package TYPE devclass RETURNING VALUE(rv_deserialized) TYPE abap_bool RAISING zcx_abapgit_exception. "! Delete the IDoc Segment type if exists "! @parameter rv_deleted | It's a segment and was deleted "! @raising zcx_abapgit_exception | Exceptions METHODS delete_idoc_segment RETURNING VALUE(rv_deleted) TYPE abap_bool RAISING zcx_abapgit_exception. PRIVATE SECTION. CONSTANTS c_extension_xml TYPE string VALUE 'xml' ##NO_TEXT. CONSTANTS c_longtext_id_tabl TYPE dokil-id VALUE 'TB' ##NO_TEXT. CONSTANTS: BEGIN OF c_s_dataname, segment_definition TYPE string VALUE 'SEGMENT_DEFINITION' ##NO_TEXT, END OF c_s_dataname. TYPES: ty_dd03p_tt TYPE STANDARD TABLE OF dd03p. METHODS clear_dd03p_fields CHANGING ct_dd03p TYPE ty_dd03p_tt. "! Check if structure is an IDoc segment "! @raising zcx_abapgit_exception | It's not an IDoc segment METHODS check_is_idoc_segment RAISING zcx_abapgit_exception. METHODS clear_dd03p_fields_common CHANGING cs_dd03p TYPE dd03p. METHODS clear_dd03p_fields_dataelement CHANGING cs_dd03p TYPE dd03p. ENDCLASS. CLASS ZCL_ABAPGIT_OBJECT_TABL IMPLEMENTATION. METHOD check_is_idoc_segment. DATA lv_segment_type TYPE edilsegtyp. lv_segment_type = ms_item-obj_name. SELECT SINGLE segtyp FROM edisegment INTO lv_segment_type WHERE segtyp = lv_segment_type. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'No IDoc segment' ). ENDIF. ENDMETHOD. METHOD clear_dd03p_fields. CONSTANTS lc_comptype_dataelement TYPE comptype VALUE 'E' ##NO_TEXT. DATA: lv_masklen TYPE c LENGTH 4. FIELD-SYMBOLS: TYPE dd03p. * remove nested structures DELETE ct_dd03p WHERE depth <> '00'. * remove fields from .INCLUDEs DELETE ct_dd03p WHERE adminfield <> '0'. LOOP AT ct_dd03p ASSIGNING WHERE NOT rollname IS INITIAL. clear_dd03p_fields_common( CHANGING cs_dd03p = ). lv_masklen = -masklen. IF lv_masklen = '' OR NOT lv_masklen CO '0123456789'. * make sure the field contains valid data, or the XML will dump CLEAR -masklen. ENDIF. IF -comptype = lc_comptype_dataelement. clear_dd03p_fields_dataelement( CHANGING cs_dd03p = ). ENDIF. IF -shlporigin = 'D'. * search help from domain CLEAR: -shlpfield, -shlpname. ENDIF. * XML output assumes correct field content IF -routputlen = ' '. CLEAR -routputlen. ENDIF. ENDLOOP. ENDMETHOD. METHOD clear_dd03p_fields_common. CLEAR: cs_dd03p-ddlanguage, cs_dd03p-dtelmaster, cs_dd03p-logflag, cs_dd03p-ddtext, cs_dd03p-reservedte, cs_dd03p-reptext, cs_dd03p-scrtext_s, cs_dd03p-scrtext_m, cs_dd03p-scrtext_l. ENDMETHOD. METHOD clear_dd03p_fields_dataelement. * type specified via data element CLEAR: cs_dd03p-domname, cs_dd03p-inttype, cs_dd03p-intlen, cs_dd03p-mask, cs_dd03p-memoryid, cs_dd03p-headlen, cs_dd03p-scrlen1, cs_dd03p-scrlen2, cs_dd03p-scrlen3, cs_dd03p-datatype, cs_dd03p-leng, cs_dd03p-outputlen, cs_dd03p-deffdname, cs_dd03p-convexit, cs_dd03p-entitytab, cs_dd03p-dommaster, cs_dd03p-domname3l, cs_dd03p-decimals, cs_dd03p-lowercase, cs_dd03p-signflag. ENDMETHOD. METHOD delete_idoc_segment. DATA lv_segment_type TYPE edilsegtyp. DATA lv_result LIKE sy-subrc. TRY. check_is_idoc_segment( ). CATCH zcx_abapgit_exception ##no_handler. rv_deleted = abap_false. RETURN. "previous XML version or no IDoc segment ENDTRY. rv_deleted = abap_true. lv_segment_type = ms_item-obj_name. CALL FUNCTION 'SEGMENT_DELETE' EXPORTING segmenttyp = lv_segment_type IMPORTING result = lv_result EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0 OR lv_result <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. ENDMETHOD. METHOD deserialize_idoc_segment. DATA lv_result LIKE sy-subrc. DATA lt_segment_definitions TYPE ty_segment_definitions. DATA lv_package TYPE devclass. DATA lv_uname TYPE sy-uname. FIELD-SYMBOLS TYPE ty_segment_definition. rv_deserialized = abap_false. TRY. io_xml->read( EXPORTING iv_name = c_s_dataname-segment_definition CHANGING cg_data = lt_segment_definitions ). CATCH zcx_abapgit_exception ##no_handler. RETURN. "previous XML version or no IDoc segment ENDTRY. IF lines( lt_segment_definitions ) = 0. RETURN. "no IDoc segment ENDIF. rv_deserialized = abap_true. lv_package = iv_package. LOOP AT lt_segment_definitions ASSIGNING . -segmentheader-presp = -segmentheader-pwork = cl_abap_syst=>get_user_name( ). CALL FUNCTION 'SEGMENT_READ' EXPORTING segmenttyp = -segmentheader-segtyp IMPORTING result = lv_result EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0 OR lv_result <> 0. CALL FUNCTION 'SEGMENT_CREATE' IMPORTING segmentdefinition = -segmentdefinition TABLES segmentstructure = -segmentstructures CHANGING segmentheader = -segmentheader devclass = lv_package EXCEPTIONS OTHERS = 1. ELSE. CALL FUNCTION 'SEGMENT_MODIFY' CHANGING segmentheader = -segmentheader devclass = lv_package EXCEPTIONS OTHERS = 1. IF sy-subrc = 0. CALL FUNCTION 'SEGMENTDEFINITION_MODIFY' TABLES segmentstructure = -segmentstructures CHANGING segmentdefinition = -segmentdefinition EXCEPTIONS OTHERS = 1. ENDIF. ENDIF. IF sy-subrc <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. ENDLOOP. lv_uname = cl_abap_syst=>get_user_name( ). CALL FUNCTION 'TR_TADIR_INTERFACE' EXPORTING wi_test_modus = abap_false wi_tadir_pgmid = 'R3TR' wi_tadir_object = ms_item-obj_type wi_tadir_obj_name = ms_item-obj_name wi_tadir_author = lv_uname wi_tadir_devclass = iv_package wi_tadir_masterlang = mv_language iv_set_edtflag = abap_true iv_delflag = abap_false EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'error from TR_TADIR_INTERFACE' ). ENDIF. ENDMETHOD. METHOD serialize_idoc_segment. DATA lv_segment_type TYPE edilsegtyp. DATA lv_result LIKE sy-subrc. DATA lv_devclass TYPE devclass. DATA lt_segmentdefinitions TYPE STANDARD TABLE OF edisegmdef. DATA ls_segment_definition TYPE ty_segment_definition. DATA lt_segment_definitions TYPE ty_segment_definitions. FIELD-SYMBOLS: TYPE edisegmdef. TRY. check_is_idoc_segment( ). lv_segment_type = ms_item-obj_name. CALL FUNCTION 'SEGMENT_READ' EXPORTING segmenttyp = lv_segment_type IMPORTING result = lv_result TABLES segmentdefinition = lt_segmentdefinitions EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0 OR lv_result <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. LOOP AT lt_segmentdefinitions ASSIGNING . CLEAR ls_segment_definition. CALL FUNCTION 'SEGMENTDEFINITION_READ' EXPORTING segmenttyp = -segtyp IMPORTING result = lv_result devclass = lv_devclass segmentheader = ls_segment_definition-segmentheader segmentdefinition = ls_segment_definition-segmentdefinition TABLES segmentstructure = ls_segment_definition-segmentstructures CHANGING version = -version EXCEPTIONS no_authority = 1 segment_not_existing = 2 OTHERS = 3. IF sy-subrc <> 0 OR lv_result <> 0. zcx_abapgit_exception=>raise_t100( ). ENDIF. zcl_abapgit_object_idoc=>clear_idoc_segement_fields( CHANGING cs_structure = ls_segment_definition-segmentdefinition ). zcl_abapgit_object_idoc=>clear_idoc_segement_fields( CHANGING cs_structure = ls_segment_definition-segmentheader ). APPEND ls_segment_definition TO lt_segment_definitions. ENDLOOP. io_xml->add( iv_name = c_s_dataname-segment_definition ig_data = lt_segment_definitions ). CATCH zcx_abapgit_exception ##no_handler. "ok, no Idoc segment ENDTRY. ENDMETHOD. METHOD zif_abapgit_object~changed_by. TYPES: BEGIN OF ty_data, as4user TYPE as4user, as4date TYPE as4date, as4time TYPE as4time, END OF ty_data. DATA: lt_data TYPE STANDARD TABLE OF ty_data WITH DEFAULT KEY, ls_data LIKE LINE OF lt_data. SELECT as4user as4date as4time FROM dd02l INTO TABLE lt_data WHERE tabname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. SELECT as4user as4date as4time APPENDING TABLE lt_data FROM dd09l WHERE tabname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. SELECT as4user as4date as4time APPENDING TABLE lt_data FROM dd12l WHERE sqltab = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. SORT lt_data BY as4date DESCENDING as4time DESCENDING. READ TABLE lt_data INDEX 1 INTO ls_data. IF sy-subrc = 0. rv_user = ls_data-as4user. ELSE. rv_user = c_user_unknown. ENDIF. ENDMETHOD. METHOD zif_abapgit_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname, lv_tabclass TYPE dd02l-tabclass, lv_no_ask TYPE abap_bool, lv_subrc TYPE sy-subrc, lr_data TYPE REF TO data. FIELD-SYMBOLS: TYPE any. IF zif_abapgit_object~exists( ) = abap_false. " Proxies e.g. delete on its own, nothing todo here then. RETURN. ENDIF. lv_objname = ms_item-obj_name. IF delete_idoc_segment( ) = abap_false. lv_no_ask = abap_true. SELECT SINGLE tabclass FROM dd02l INTO lv_tabclass WHERE tabname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. IF sy-subrc = 0 AND lv_tabclass = 'TRANSP'. * Avoid dump in dynamic SELECT in case the table does not exist on database CALL FUNCTION 'DB_EXISTS_TABLE' EXPORTING tabname = lv_objname IMPORTING subrc = lv_subrc. IF lv_subrc = 0. * it cannot delete table with table without asking CREATE DATA lr_data TYPE (lv_objname). ASSIGN lr_data->* TO . SELECT SINGLE * FROM (lv_objname) INTO . IF sy-subrc = 0. lv_no_ask = abap_false. ENDIF. ENDIF. ENDIF. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = lv_no_ask objname = lv_objname objtype = 'T' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, TABL,' && sy-subrc ). ENDIF. delete_longtexts( c_longtext_id_tabl ). ENDIF. ENDMETHOD. METHOD zif_abapgit_object~deserialize. DATA: lv_name TYPE ddobjname, lv_tname TYPE trobj_name, ls_dd02v TYPE dd02v, ls_dd09l TYPE dd09l, lt_dd03p TYPE TABLE OF dd03p, lt_dd05m TYPE TABLE OF dd05m, lt_dd08v TYPE TABLE OF dd08v, lt_dd12v TYPE dd12vtab, lt_dd17v TYPE dd17vtab, ls_dd17v LIKE LINE OF lt_dd17v, lt_secondary LIKE lt_dd17v, lt_dd35v TYPE TABLE OF dd35v, lt_dd36m TYPE dd36mttyp, ls_dd12v LIKE LINE OF lt_dd12v. IF deserialize_idoc_segment( io_xml = io_xml iv_package = iv_package ) = abap_false. io_xml->read( EXPORTING iv_name = 'DD02V' CHANGING cg_data = ls_dd02v ). io_xml->read( EXPORTING iv_name = 'DD09L' CHANGING cg_data = ls_dd09l ). io_xml->read( EXPORTING iv_name = 'DD03P_TABLE' CHANGING cg_data = lt_dd03p ). io_xml->read( EXPORTING iv_name = 'DD05M_TABLE' CHANGING cg_data = lt_dd05m ). io_xml->read( EXPORTING iv_name = 'DD08V_TABLE' CHANGING cg_data = lt_dd08v ). io_xml->read( EXPORTING iv_name = 'DD12V' CHANGING cg_data = lt_dd12v ). io_xml->read( EXPORTING iv_name = 'DD17V' CHANGING cg_data = lt_dd17v ). io_xml->read( EXPORTING iv_name = 'DD35V_TALE' CHANGING cg_data = lt_dd35v ). io_xml->read( EXPORTING iv_name = 'DD36M' CHANGING cg_data = lt_dd36m ). corr_insert( iv_package = iv_package iv_object_class = 'DICT' ). lv_name = ms_item-obj_name. " type conversion CALL FUNCTION 'DDIF_TABL_PUT' EXPORTING name = lv_name dd02v_wa = ls_dd02v dd09l_wa = ls_dd09l TABLES dd03p_tab = lt_dd03p dd05m_tab = lt_dd05m dd08v_tab = lt_dd08v dd35v_tab = lt_dd35v dd36m_tab = lt_dd36m EXCEPTIONS tabl_not_found = 1 name_inconsistent = 2 tabl_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'error from DDIF_TABL_PUT' ). ENDIF. zcl_abapgit_objects_activation=>add_item( ms_item ). * handle indexes LOOP AT lt_dd12v INTO ls_dd12v. * todo, call corr_insert? CLEAR lt_secondary. LOOP AT lt_dd17v INTO ls_dd17v WHERE sqltab = ls_dd12v-sqltab AND indexname = ls_dd12v-indexname. APPEND ls_dd17v TO lt_secondary. ENDLOOP. CALL FUNCTION 'DDIF_INDX_PUT' EXPORTING name = ls_dd12v-sqltab id = ls_dd12v-indexname dd12v_wa = ls_dd12v TABLES dd17v_tab = lt_secondary EXCEPTIONS indx_not_found = 1 name_inconsistent = 2 indx_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'error from DDIF_INDX_PUT' ). ENDIF. CALL FUNCTION 'DD_DD_TO_E071' EXPORTING type = 'INDX' name = ls_dd12v-sqltab id = ls_dd12v-indexname IMPORTING obj_name = lv_tname. zcl_abapgit_objects_activation=>add( iv_type = 'INDX' iv_name = lv_tname ). ENDLOOP. deserialize_longtexts( io_xml ). ENDIF. ENDMETHOD. METHOD zif_abapgit_object~exists. DATA: lv_tabname TYPE dd02l-tabname. SELECT SINGLE tabname FROM dd02l INTO lv_tabname WHERE tabname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD zif_abapgit_object~get_comparator. DATA: lo_local_version_output TYPE REF TO zcl_abapgit_xml_output, lo_local_version_input TYPE REF TO zcl_abapgit_xml_input. CREATE OBJECT lo_local_version_output. me->zif_abapgit_object~serialize( lo_local_version_output ). CREATE OBJECT lo_local_version_input EXPORTING iv_xml = lo_local_version_output->render( ). CREATE OBJECT ri_comparator TYPE zcl_abapgit_object_tabl_compar EXPORTING io_local = lo_local_version_input. ENDMETHOD. METHOD zif_abapgit_object~get_metadata. rs_metadata = get_metadata( ). rs_metadata-ddic = abap_true. 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 = 'ESDICT' iv_argument = |{ ms_item-obj_type }{ ms_item-obj_name }| ). ENDMETHOD. METHOD zif_abapgit_object~jump. jump_se11( iv_radio = 'RSRD1-DDTYPE' iv_field = 'RSRD1-DDTYPE_VAL' ). ENDMETHOD. METHOD zif_abapgit_object~serialize. DATA: lv_name TYPE ddobjname, ls_dd02v TYPE dd02v, ls_dd09l TYPE dd09l, lt_dd03p TYPE ty_dd03p_tt, lt_dd05m TYPE TABLE OF dd05m, lt_dd08v TYPE TABLE OF dd08v, lt_dd12v TYPE dd12vtab, lt_dd17v TYPE dd17vtab, lt_dd35v TYPE TABLE OF dd35v, lv_index LIKE sy-index, lt_dd36m TYPE dd36mttyp. FIELD-SYMBOLS: LIKE LINE OF lt_dd12v, LIKE LINE OF lt_dd05m, LIKE LINE OF lt_dd36m, TYPE any. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_TABL_GET' EXPORTING name = lv_name langu = mv_language IMPORTING dd02v_wa = ls_dd02v dd09l_wa = ls_dd09l TABLES dd03p_tab = lt_dd03p dd05m_tab = lt_dd05m dd08v_tab = lt_dd08v dd12v_tab = lt_dd12v dd17v_tab = lt_dd17v dd35v_tab = lt_dd35v dd36m_tab = lt_dd36m EXCEPTIONS illegal_input = 1 OTHERS = 2. IF sy-subrc <> 0. zcx_abapgit_exception=>raise( 'error from DDIF_TABL_GET' ). ENDIF. IF ls_dd02v IS INITIAL. RETURN. " object does not exits ENDIF. CLEAR: ls_dd02v-as4user, ls_dd02v-as4date, ls_dd02v-as4time. * reset numeric field, so XML does not crash IF ls_dd02v-prozpuff = ''. CLEAR ls_dd02v-prozpuff. ENDIF. IF ls_dd02v-datmin = ''. CLEAR ls_dd02v-datmin. ENDIF. IF ls_dd02v-datmax = ''. CLEAR ls_dd02v-datmax. ENDIF. IF ls_dd02v-datavg = ''. CLEAR ls_dd02v-datavg. ENDIF. CLEAR: ls_dd09l-as4user, ls_dd09l-as4date, ls_dd09l-as4time. ASSIGN COMPONENT 'ROWORCOLST' OF STRUCTURE ls_dd09l TO . IF sy-subrc = 0 AND = 'C'. CLEAR . "To avoid diff errors. This field doesn't exists in all releases ENDIF. LOOP AT lt_dd12v ASSIGNING . CLEAR: -as4user, -as4date, -as4time. ENDLOOP. clear_dd03p_fields( CHANGING ct_dd03p = lt_dd03p ). * remove foreign keys inherited from .INCLUDEs DELETE lt_dd08v WHERE noinherit = 'N'. LOOP AT lt_dd05m ASSIGNING . lv_index = sy-tabix. READ TABLE lt_dd08v WITH KEY fieldname = -fieldname TRANSPORTING NO FIELDS. IF sy-subrc <> 0. DELETE lt_dd05m INDEX lv_index. ENDIF. ENDLOOP. * remove inherited search helps DELETE lt_dd35v WHERE shlpinher = abap_true. LOOP AT lt_dd36m ASSIGNING . lv_index = sy-tabix. READ TABLE lt_dd35v WITH KEY fieldname = -fieldname TRANSPORTING NO FIELDS. IF sy-subrc <> 0. DELETE lt_dd36m INDEX lv_index. ENDIF. ENDLOOP. io_xml->add( iv_name = 'DD02V' ig_data = ls_dd02v ). IF NOT ls_dd09l IS INITIAL. io_xml->add( iv_name = 'DD09L' ig_data = ls_dd09l ). ENDIF. io_xml->add( ig_data = lt_dd03p iv_name = 'DD03P_TABLE' ). io_xml->add( ig_data = lt_dd05m iv_name = 'DD05M_TABLE' ). io_xml->add( ig_data = lt_dd08v iv_name = 'DD08V_TABLE' ). io_xml->add( iv_name = 'DD12V' ig_data = lt_dd12v ). io_xml->add( iv_name = 'DD17V' ig_data = lt_dd17v ). io_xml->add( ig_data = lt_dd35v iv_name = 'DD35V_TALE' ). io_xml->add( iv_name = 'DD36M' ig_data = lt_dd36m ). serialize_longtexts( io_xml = io_xml iv_longtext_id = c_longtext_id_tabl ). serialize_idoc_segment( io_xml ). ENDMETHOD. ENDCLASS.