├── .abapgit.xml ├── LICENSE ├── README.md ├── abaplint.jsonc └── src ├── package.devc.xml ├── zcl_abapgitp_object.clas.abap ├── zcl_abapgitp_object.clas.xml ├── zcl_abapgitp_object_by_sobj.clas.abap ├── zcl_abapgitp_object_by_sobj.clas.locals_def.abap ├── zcl_abapgitp_object_by_sobj.clas.locals_imp.abap ├── zcl_abapgitp_object_by_sobj.clas.testclasses.abap ├── zcl_abapgitp_object_by_sobj.clas.xml ├── zcl_abapgitp_xml_factory.clas.abap ├── zcl_abapgitp_xml_factory.clas.locals_imp.abap ├── zcl_abapgitp_xml_factory.clas.testclasses.abap ├── zcl_abapgitp_xml_factory.clas.xml ├── zcx_abapgitp_object.clas.abap ├── zcx_abapgitp_object.clas.xml ├── zif_abapgitp_plugin.intf.abap ├── zif_abapgitp_plugin.intf.xml ├── zif_abapgitp_xml_input.intf.abap ├── zif_abapgitp_xml_input.intf.xml ├── zif_abapgitp_xml_output.intf.abap └── zif_abapgitp_xml_output.intf.xml /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | /src/ 7 | PREFIX 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Lars Hvam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED 2 | 3 | These plugins will sometime become obsolete, see https://github.com/larshp/abapGit/issues/1449 and https://github.com/larshp/abapGit/pull/1590 4 | 5 | # abapGit-Plugins 6 | This repository contains plugins for abapGit to support other objecttypes. 7 | By inheriting from `zcl_abapgitp_object`and implementing `zif_abapgitp_plugin` you can create plugins for objecttypes which are not natively supported by ABAPGit yet. 8 | However, please be aware that the format used by ABAPGit may change, so please check back frequently to make sure your plugin stays up-to-date. 9 | 10 | # SOBJ-based generic plugin 11 | One plugin already contained in this repository is a generic plugin supporting multiple object types. Similar to the SAP transport management system, it transports table content. As this is quite a dangerous operation (particularly when operating across systems with potentially different releases), you should check your systems technical components and the one from which you import the repository. 12 | -------------------------------------------------------------------------------- /abaplint.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "files": "/src/**/*.*" 4 | }, 5 | "dependencies": [ 6 | { 7 | "url": "https://github.com/abaplint/deps", 8 | "folder": "/deps1", 9 | "files": "/src/**/*.*" 10 | }, 11 | { 12 | "url": "https://github.com/abapGit/abapGit", 13 | "folder": "/deps2", 14 | "files": "/src/**/*.*" 15 | } 16 | ], 17 | "syntax": { 18 | "version": "v702", 19 | "errorNamespace": "^(Z|Y|LCL_|TY_|LIF_)", 20 | "globalConstants": ["rs_c_pgmid_r3tr", "rs_c_true"] 21 | }, 22 | "rules": { 23 | "begin_end_names": true, 24 | "check_ddic": true, 25 | "check_include": true, 26 | "check_syntax": true, 27 | "global_class": true, 28 | "implement_methods": true, 29 | "method_implemented_twice": true, 30 | "parser_error": true, 31 | "parser_missing_space": true, 32 | "superclass_final": true, 33 | "unknown_types": true, 34 | "xml_consistency": true 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $ABAPGIT_PLUGINS 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_object.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_abapgitp_object DEFINITION 2 | PUBLIC 3 | ABSTRACT 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | TYPES: 9 | BEGIN OF ty_metadata, 10 | class TYPE string, 11 | version TYPE string, 12 | END OF ty_metadata . 13 | 14 | METHODS set_item 15 | IMPORTING 16 | !iv_obj_type TYPE tadir-object 17 | !iv_obj_name TYPE tadir-obj_name . 18 | METHODS get_supported_obj_types 19 | ABSTRACT 20 | RETURNING 21 | VALUE(rt_obj_type) TYPE objtyptable . 22 | METHODS wrap_serialize 23 | IMPORTING 24 | !io_xml TYPE REF TO object . 25 | METHODS wrap_deserialize 26 | IMPORTING 27 | !io_xml TYPE REF TO object 28 | !iv_package TYPE devclass 29 | RAISING 30 | zcx_abapgitp_object . 31 | PROTECTED SECTION. 32 | CLASS-DATA gv_serializer_classname TYPE string. 33 | CLASS-DATA gv_serializer_version TYPE string. 34 | 35 | DATA mv_obj_type TYPE tadir-object. 36 | DATA mv_obj_name TYPE tadir-obj_name . 37 | 38 | METHODS create_tadir_entry 39 | IMPORTING 40 | iv_package TYPE devclass 41 | RAISING 42 | zcx_abapgitp_object. 43 | 44 | METHODS get_metadata 45 | RETURNING VALUE(rs_metadata) TYPE zif_abapgitp_plugin=>ty_metadata. 46 | PRIVATE SECTION. 47 | 48 | METHODS change_object_directory_entry 49 | IMPORTING 50 | iv_delete TYPE abap_bool 51 | iv_package TYPE devclass 52 | RAISING 53 | zcx_abapgitp_object. 54 | ENDCLASS. 55 | 56 | 57 | 58 | CLASS ZCL_ABAPGITP_OBJECT IMPLEMENTATION. 59 | 60 | 61 | METHOD change_object_directory_entry. 62 | 63 | DATA: lv_tadir_object TYPE trobjtype, 64 | lv_exception_text TYPE string. 65 | 66 | 67 | lv_tadir_object = mv_obj_type. 68 | 69 | CALL FUNCTION 'TR_TADIR_INTERFACE' 70 | EXPORTING 71 | wi_test_modus = abap_false 72 | wi_delete_tadir_entry = iv_delete " X - delete object directory entry 73 | wi_tadir_pgmid = 'R3TR' " Input for TADIR field PGMID 74 | wi_tadir_object = lv_tadir_object " Input for TADIR field OBJECT 75 | wi_tadir_obj_name = mv_obj_name " Input for TADIR field OBJ_NAME 76 | wi_tadir_devclass = iv_package 77 | iv_delflag = abap_false 78 | EXCEPTIONS 79 | tadir_entry_not_existing = 1 80 | tadir_entry_ill_type = 2 81 | no_systemname = 3 82 | no_systemtype = 4 83 | original_system_conflict = 5 84 | object_reserved_for_devclass = 6 85 | object_exists_global = 7 86 | object_exists_local = 8 87 | object_is_distributed = 9 88 | obj_specification_not_unique = 10 89 | no_authorization_to_delete = 11 90 | devclass_not_existing = 12 91 | simultanious_set_remove_repair = 13 92 | order_missing = 14 93 | no_modification_of_head_syst = 15 94 | pgmid_object_not_allowed = 16 95 | masterlanguage_not_specified = 17 96 | devclass_not_specified = 18 97 | specify_owner_unique = 19 98 | loc_priv_objs_no_repair = 20 99 | gtadir_not_reached = 21 100 | object_locked_for_order = 22 101 | change_of_class_not_allowed = 23 102 | no_change_from_sap_to_tmp = 24 103 | OTHERS = 25. 104 | IF sy-subrc <> 0. 105 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno 106 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_exception_text. 107 | RAISE EXCEPTION TYPE zcx_abapgitp_object 108 | EXPORTING 109 | text = lv_exception_text. 110 | ENDIF. 111 | ENDMETHOD. 112 | 113 | 114 | METHOD CREATE_TADIR_ENTRY. 115 | me->change_object_directory_entry( iv_package = iv_package 116 | iv_delete = abap_false ). 117 | ENDMETHOD. 118 | 119 | 120 | METHOD GET_METADATA. 121 | ASSERT gv_serializer_classname IS NOT INITIAL. "needs to be provided in class-constructor of the inheriting class 122 | rs_metadata-class = gv_serializer_classname. 123 | rs_metadata-version = gv_serializer_version. "optional 124 | ENDMETHOD. 125 | 126 | 127 | METHOD SET_ITEM. 128 | 129 | mv_obj_type = iv_obj_type. 130 | mv_obj_name = iv_obj_name. 131 | 132 | ENDMETHOD. 133 | 134 | 135 | METHOD wrap_deserialize. 136 | CALL METHOD me->('ZIF_ABAPGITP_PLUGIN~DESERIALIZE') 137 | EXPORTING 138 | io_xml = zcl_abapgitp_xml_factory=>wrap_xml_input( io_xml ) 139 | iv_package = iv_package. 140 | ENDMETHOD. 141 | 142 | 143 | METHOD wrap_serialize. 144 | * This method wraps the interface method in order to have a typed signature at the plugin-interface 145 | * while at the same time keeping the de-coupling of the ABAPGit Report and the plugins 146 | CALL METHOD me->('ZIF_ABAPGITP_PLUGIN~SERIALIZE') 147 | EXPORTING 148 | io_xml = zcl_abapgitp_xml_factory=>wrap_xml_output( io_xml ). 149 | ENDMETHOD. 150 | ENDCLASS. 151 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_object.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAPGITP_OBJECT 7 | E 8 | Object, Abstract 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_object_by_sobj.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_abapgitp_object_by_sobj DEFINITION 2 | PUBLIC 3 | INHERITING FROM zcl_abapgitp_object 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | INTERFACES zif_abapgitp_plugin . 9 | 10 | CLASS-METHODS class_constructor . 11 | 12 | METHODS get_supported_obj_types 13 | REDEFINITION . 14 | PROTECTED SECTION. 15 | PRIVATE SECTION. 16 | 17 | METHODS get_tlogo_bridge 18 | RETURNING VALUE(ro_tlogo_bridge) TYPE REF TO lcl_tlogo_bridge 19 | RAISING zcx_abapgitp_object. 20 | 21 | DATA mo_tlogo_bridge TYPE REF TO lcl_tlogo_bridge. 22 | 23 | CLASS-DATA gt_supported_obj_types TYPE objtyptable. 24 | ENDCLASS. 25 | 26 | 27 | 28 | CLASS zcl_abapgitp_object_by_sobj IMPLEMENTATION. 29 | 30 | 31 | METHOD class_constructor. 32 | 33 | DATA: lt_all_objectname TYPE STANDARD TABLE OF objh-objectname WITH DEFAULT KEY, 34 | lv_objectname LIKE LINE OF lt_all_objectname, 35 | lv_obj_type LIKE LINE OF gt_supported_obj_types. 36 | 37 | 38 | gv_serializer_classname = 'ZCL_ABAPGIT_OBJECT_BY_SOBJ'. 39 | gv_serializer_version = '1.0'. 40 | 41 | SELECT objectname FROM objh 42 | INTO TABLE lt_all_objectname 43 | WHERE objecttype = 'L'. "#EC CI_GENBUFF 44 | 45 | LOOP AT lt_all_objectname INTO lv_objectname. 46 | IF strlen( lv_objectname ) <= 4. 47 | lv_obj_type = lv_objectname. 48 | INSERT lv_obj_type INTO TABLE gt_supported_obj_types. 49 | ENDIF. 50 | ENDLOOP. 51 | 52 | " WDCL is not supported since it has two '*' in OBJSL-TOBJKEY 53 | DELETE gt_supported_obj_types WHERE table_line = 'WDCL'. 54 | 55 | ENDMETHOD. 56 | 57 | 58 | METHOD get_supported_obj_types. 59 | rt_obj_type = gt_supported_obj_types. 60 | ENDMETHOD. 61 | 62 | 63 | METHOD get_tlogo_bridge. 64 | IF mo_tlogo_bridge IS INITIAL. 65 | 66 | TRY. 67 | DATA lx_bridge_creation TYPE REF TO lcx_obj_exception. 68 | CREATE OBJECT mo_tlogo_bridge 69 | EXPORTING 70 | iv_object = mv_obj_type 71 | iv_object_name = mv_obj_name. 72 | CATCH lcx_obj_exception INTO lx_bridge_creation. 73 | RAISE EXCEPTION TYPE zcx_abapgitp_object 74 | EXPORTING 75 | text = lx_bridge_creation->get_text( ) 76 | previous = lx_bridge_creation. 77 | ENDTRY. 78 | ENDIF. 79 | 80 | ro_tlogo_bridge = mo_tlogo_bridge. 81 | ENDMETHOD. 82 | 83 | 84 | METHOD zif_abapgitp_plugin~delete. 85 | 86 | get_tlogo_bridge( )->delete_object_on_db( ). 87 | 88 | ENDMETHOD. 89 | 90 | 91 | METHOD zif_abapgitp_plugin~deserialize. 92 | DATA lo_object_container TYPE REF TO lcl_abapgit_xml_container. 93 | DATA lx_obj_exception TYPE REF TO lcx_obj_exception. 94 | 95 | CREATE OBJECT lo_object_container. 96 | 97 | lo_object_container->set_xml_input( io_xml ). 98 | 99 | TRY. 100 | get_tlogo_bridge( )->import_object( lo_object_container ). 101 | CATCH lcx_obj_exception INTO lx_obj_exception. 102 | RAISE EXCEPTION TYPE zcx_abapgitp_object 103 | EXPORTING 104 | text = |{ mv_obj_type } { mv_obj_name }: { 105 | lx_obj_exception->get_text( ) }| 106 | previous = lx_obj_exception. 107 | ENDTRY. 108 | 109 | me->create_tadir_entry( iv_package ). 110 | ENDMETHOD. 111 | 112 | 113 | METHOD zif_abapgitp_plugin~exists. 114 | TRY. 115 | rv_bool = get_tlogo_bridge( )->instance_exists( ). 116 | CATCH lcx_obj_exception zcx_abapgitp_object. 117 | rv_bool = abap_false. 118 | ENDTRY. 119 | ENDMETHOD. 120 | 121 | 122 | METHOD zif_abapgitp_plugin~get_metadata. 123 | rs_metadata = get_metadata( ). 124 | rs_metadata-delete_tadir = abap_true. 125 | ENDMETHOD. 126 | 127 | 128 | METHOD zif_abapgitp_plugin~jump. 129 | RETURN. 130 | ENDMETHOD. 131 | 132 | 133 | METHOD zif_abapgitp_plugin~serialize. 134 | DATA lo_object_container TYPE REF TO lcl_abapgit_xml_container. 135 | DATA lx_obj_exception TYPE REF TO lcx_obj_exception. 136 | 137 | TRY. 138 | IF get_tlogo_bridge( )->instance_exists( ) = abap_true. 139 | 140 | CREATE OBJECT lo_object_container. 141 | lo_object_container->set_xml_output( io_xml ). 142 | 143 | get_tlogo_bridge( )->export_object( lo_object_container ). 144 | 145 | ENDIF. "No else needed - if the object does not exist, we'll not serialize anything 146 | CATCH lcx_obj_exception INTO lx_obj_exception. 147 | RAISE EXCEPTION TYPE zcx_abapgitp_object 148 | EXPORTING 149 | text = lx_obj_exception->get_text( ) 150 | previous = lx_obj_exception. 151 | ENDTRY. 152 | ENDMETHOD. 153 | ENDCLASS. 154 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_object_by_sobj.clas.locals_def.abap: -------------------------------------------------------------------------------- 1 | CLASS lcx_obj_exception DEFINITION INHERITING FROM cx_static_check. 2 | PUBLIC SECTION. 3 | METHODS constructor 4 | IMPORTING 5 | textid LIKE textid OPTIONAL 6 | previous LIKE previous OPTIONAL 7 | iv_text TYPE string OPTIONAL. 8 | 9 | METHODS: get_text REDEFINITION. 10 | 11 | PROTECTED SECTION. 12 | DATA mv_text TYPE string. 13 | ENDCLASS. 14 | 15 | INTERFACE lif_external_object_container. 16 | TYPES: BEGIN OF ty_s_component, 17 | pos TYPE i, 18 | name TYPE cl_abap_structdescr=>component-name, 19 | type_kind TYPE abap_typekind, 20 | length TYPE i, 21 | decimals TYPE i, 22 | is_key TYPE abap_bool, 23 | END OF ty_s_component, 24 | ty_t_component TYPE STANDARD TABLE OF ty_s_component WITH KEY primary_key COMPONENTS pos 25 | WITH UNIQUE SORTED KEY name COMPONENTS name 26 | WITH NON-UNIQUE SORTED KEY is_key COMPONENTS is_key pos. 27 | TYPES: 28 | BEGIN OF ty_s_table_content, 29 | tabname TYPE tabname, 30 | field_catalog TYPE ty_t_component, 31 | data_tab TYPE REF TO data, 32 | END OF ty_s_table_content. 33 | TYPES: 34 | ty_t_table_content TYPE SORTED TABLE OF ty_s_table_content WITH UNIQUE KEY tabname. 35 | 36 | TYPES ty_t_tabname TYPE SORTED TABLE OF tabname WITH UNIQUE KEY table_line. 37 | 38 | METHODS store_obj_table 39 | IMPORTING 40 | is_table_content TYPE ty_s_table_content 41 | RAISING lcx_obj_exception. 42 | 43 | 44 | METHODS get_persisted_table_content 45 | IMPORTING 46 | it_relevant_table TYPE ty_t_tabname 47 | EXPORTING 48 | et_table_content TYPE ty_t_table_content 49 | RAISING lcx_obj_exception. 50 | 51 | METHODS backup_replaced_version 52 | IMPORTING 53 | it_table_content TYPE ty_t_table_content 54 | RAISING lcx_obj_exception. 55 | 56 | ENDINTERFACE. 57 | 58 | CLASS lcl_abapgit_xml_container DEFINITION. 59 | PUBLIC SECTION. 60 | INTERFACES lif_external_object_container. 61 | DATA mo_xml_input TYPE REF TO zif_abapgitp_xml_input READ-ONLY. 62 | DATA mo_xml_output TYPE REF TO zif_abapgitp_xml_output READ-ONLY. 63 | 64 | METHODS set_xml_input 65 | IMPORTING 66 | io_xml TYPE REF TO zif_abapgitp_xml_input. 67 | 68 | METHODS set_xml_output 69 | IMPORTING 70 | io_xml TYPE REF TO zif_abapgitp_xml_output. 71 | 72 | PROTECTED SECTION. 73 | CONSTANTS co_suffix_fieldcat TYPE string VALUE '_field_catalog'. 74 | METHODS create_table_descriptor 75 | IMPORTING 76 | it_field_catalog TYPE lif_external_object_container=>ty_s_table_content-field_catalog 77 | EXPORTING 78 | eo_tabledescr TYPE REF TO cl_abap_tabledescr 79 | RAISING 80 | lcx_obj_exception. 81 | ENDCLASS. 82 | 83 | CLASS ltcl_catalog DEFINITION DEFERRED. 84 | 85 | CLASS lcl_catalog DEFINITION FRIENDS ltcl_catalog. 86 | 87 | PUBLIC SECTION. 88 | CLASS-METHODS build 89 | IMPORTING iv_tobj_name TYPE objsl-tobj_name 90 | RETURNING VALUE(rt_catalog) TYPE lif_external_object_container=>ty_t_component 91 | RAISING lcx_obj_exception. 92 | 93 | ENDCLASS. 94 | 95 | CLASS lcl_tlogo_bridge DEFINITION. 96 | * This class is inspired by CL_RSO_TLOGO_XML_BRIDGE which provides 97 | * features to serialize a logical transport object based on its definition 98 | * in SOBJ. Sadly, the original class hides some information needed in 99 | * private tables and is not easily readable. 100 | * This class shall be easily consumable and offer additional features 101 | * such as existence checks etc. 102 | 103 | PUBLIC SECTION. 104 | METHODS constructor 105 | IMPORTING iv_object TYPE tadir-object "This is the name of the SOBJ-object (M1) which is the type of all objects derived from it 106 | iv_object_name TYPE sobj_name 107 | RAISING lcx_obj_exception. 108 | 109 | METHODS export_object 110 | IMPORTING 111 | io_object_container TYPE REF TO lif_external_object_container 112 | RAISING lcx_obj_exception. 113 | 114 | METHODS import_object 115 | IMPORTING 116 | io_object_container TYPE REF TO lif_external_object_container 117 | RAISING lcx_obj_exception. 118 | 119 | METHODS instance_exists 120 | RETURNING VALUE(rv_exists) TYPE abap_bool 121 | RAISING lcx_obj_exception. 122 | 123 | METHODS delete_object_on_db. 124 | 125 | PROTECTED SECTION. 126 | TYPES BEGIN OF ty_s_object_table. 127 | INCLUDE TYPE objsl AS objsl. 128 | TYPES field_catalog TYPE lif_external_object_container=>ty_t_component. 129 | TYPES END OF ty_s_object_table. 130 | 131 | TYPES ty_t_object_table TYPE SORTED TABLE OF ty_s_object_table 132 | WITH UNIQUE KEY objectname objecttype trwcount 133 | WITH NON-UNIQUE SORTED KEY table_name COMPONENTS tobj_name. 134 | 135 | TYPES ty_t_object_method TYPE SORTED TABLE OF objm WITH UNIQUE KEY objectname objecttype method. 136 | 137 | DATA mv_object TYPE objh-objectname. "This is the name of the SOBJ-object (M1) which is the type of all objects derived from it 138 | DATA mv_object_name TYPE sobj_name. 139 | DATA ms_object_header TYPE objh. 140 | DATA mt_object_table TYPE ty_t_object_table. 141 | DATA mt_object_method TYPE ty_t_object_method. 142 | DATA mv_tolerate_additional_tables TYPE abap_bool. 143 | DATA mv_tolerate_deviating_fields TYPE abap_bool. 144 | DATA mv_tolerate_deviating_types TYPE abap_bool. 145 | 146 | METHODS get_primary_table 147 | RETURNING 148 | VALUE(rs_object_table) TYPE ty_s_object_table 149 | RAISING lcx_obj_exception. 150 | 151 | METHODS 152 | get_where_clause 153 | IMPORTING 154 | iv_tobj_name TYPE sobj_name 155 | RETURNING VALUE(rv_where_on_keys) TYPE string. 156 | 157 | METHODS before_export. 158 | METHODS after_import. 159 | METHODS get_current_tables_content 160 | IMPORTING 161 | io_object_container TYPE REF TO lif_external_object_container OPTIONAL 162 | EXPORTING 163 | et_table_content TYPE lif_external_object_container=>ty_t_table_content 164 | RAISING lcx_obj_exception. 165 | METHODS do_insert 166 | IMPORTING 167 | iv_table_name TYPE lif_external_object_container=>ty_s_table_content-tabname 168 | it_data TYPE STANDARD TABLE. 169 | 170 | PRIVATE SECTION. 171 | TYPES: BEGIN OF ty_s_objkey, 172 | num TYPE numc3, 173 | value TYPE char128, 174 | END OF ty_s_objkey, 175 | ty_t_objkey TYPE SORTED TABLE OF ty_s_objkey WITH UNIQUE KEY num. 176 | 177 | METHODS val_fieldcatalog_compatibility 178 | IMPORTING 179 | it_imported_fieldcatalog TYPE lif_external_object_container=>ty_t_component 180 | it_local_fieldcatalog TYPE lif_external_object_container=>ty_t_component 181 | EXPORTING 182 | ev_is_identical TYPE abap_bool 183 | RAISING lcx_obj_exception. 184 | 185 | METHODS do_delete 186 | IMPORTING 187 | iv_table_name TYPE lcl_tlogo_bridge=>ty_s_object_table-tobj_name 188 | iv_where_on_keys TYPE string. 189 | 190 | METHODS split_value_to_keys 191 | IMPORTING 192 | it_key_component TYPE lcl_tlogo_bridge=>ty_s_object_table-field_catalog 193 | CHANGING 194 | ct_objkey TYPE lcl_tlogo_bridge=>ty_t_objkey 195 | cs_objkey TYPE lcl_tlogo_bridge=>ty_s_objkey 196 | cv_non_value_pos TYPE numc3. 197 | 198 | METHODS distribute_name_to_components 199 | IMPORTING 200 | it_key_component TYPE lcl_tlogo_bridge=>ty_s_object_table-field_catalog 201 | CHANGING 202 | ct_objkey TYPE lcl_tlogo_bridge=>ty_t_objkey 203 | cs_objkey TYPE lcl_tlogo_bridge=>ty_s_objkey 204 | cv_non_value_pos TYPE numc3. 205 | 206 | ENDCLASS. 207 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_object_by_sobj.clas.locals_imp.abap: -------------------------------------------------------------------------------- 1 | CLASS lcl_catalog IMPLEMENTATION. 2 | 3 | METHOD build. 4 | 5 | * field catalog of table structures in current system 6 | DATA lo_typedescr TYPE REF TO cl_abap_typedescr. 7 | DATA lo_structdescr TYPE REF TO cl_abap_structdescr. 8 | DATA lt_included_view TYPE cl_abap_structdescr=>included_view. 9 | DATA ls_component LIKE LINE OF lt_included_view. 10 | DATA ls_field_cat_comp LIKE LINE OF rt_catalog. 11 | DATA lo_elemdescr TYPE REF TO cl_abap_elemdescr. 12 | DATA lt_dfies TYPE dfies_table. "Needed for the keyflag 13 | FIELD-SYMBOLS LIKE LINE OF lt_dfies. 14 | 15 | 16 | cl_abap_structdescr=>describe_by_name( 17 | EXPORTING 18 | p_name = iv_tobj_name 19 | RECEIVING 20 | p_descr_ref = lo_typedescr 21 | EXCEPTIONS 22 | type_not_found = 1 23 | OTHERS = 2 ). 24 | IF sy-subrc <> 0. 25 | RAISE EXCEPTION TYPE lcx_obj_exception 26 | EXPORTING 27 | iv_text = |Structure of { iv_tobj_name } corrupt|. 28 | ENDIF. 29 | 30 | lo_structdescr ?= lo_typedescr. 31 | 32 | DATA lv_tabname_ddobj TYPE ddobjname. 33 | lv_tabname_ddobj = iv_tobj_name. 34 | CALL FUNCTION 'DDIF_NAMETAB_GET' 35 | EXPORTING 36 | tabname = lv_tabname_ddobj " Name of Table (of the Type) 37 | TABLES 38 | dfies_tab = lt_dfies 39 | EXCEPTIONS 40 | not_found = 1 41 | OTHERS = 2. 42 | IF sy-subrc <> 0. 43 | RAISE EXCEPTION TYPE lcx_obj_exception 44 | EXPORTING 45 | iv_text = |Structure of { iv_tobj_name } corrupt|. 46 | ENDIF. 47 | 48 | * There should not be more inclusion-levels than that - even in ERP 49 | lt_included_view = lo_structdescr->get_included_view( 1000 ). 50 | 51 | DATA lv_pos LIKE ls_field_cat_comp-pos. 52 | CLEAR lv_pos. 53 | LOOP AT lt_included_view INTO ls_component. 54 | CLEAR ls_field_cat_comp. 55 | 56 | ADD 1 TO lv_pos. 57 | ls_field_cat_comp-pos = lv_pos. 58 | ls_field_cat_comp-name = ls_component-name. 59 | TRY. 60 | lo_elemdescr ?= ls_component-type. 61 | CATCH cx_sy_move_cast_error. 62 | RAISE EXCEPTION TYPE lcx_obj_exception 63 | EXPORTING 64 | iv_text = |Structured database table structures as in { 65 | iv_tobj_name } are not expected and not yet supported|. 66 | ENDTRY. 67 | 68 | READ TABLE lt_dfies ASSIGNING WITH KEY fieldname = ls_field_cat_comp-name. 69 | ASSERT sy-subrc = 0. "Can't imagine why an element may have a different name than the field. 70 | 71 | ls_field_cat_comp-type_kind = lo_elemdescr->type_kind. 72 | IF ls_field_cat_comp-type_kind = cl_abap_typedescr=>typekind_packed. 73 | ls_field_cat_comp-length = lo_elemdescr->length. 74 | ELSE. 75 | ls_field_cat_comp-length = -leng. "lo_elemdescr->length funnily return the byte-length 76 | ENDIF. 77 | ls_field_cat_comp-decimals = lo_elemdescr->decimals. 78 | 79 | ls_field_cat_comp-is_key = -keyflag. 80 | 81 | INSERT ls_field_cat_comp INTO TABLE rt_catalog. 82 | ENDLOOP. 83 | 84 | ENDMETHOD. 85 | 86 | ENDCLASS. 87 | 88 | CLASS lcl_tlogo_bridge IMPLEMENTATION. 89 | 90 | METHOD constructor. 91 | 92 | FIELD-SYMBOLS LIKE LINE OF mt_object_table. 93 | 94 | 95 | mv_object = iv_object. 96 | mv_object_name = iv_object_name. 97 | 98 | * Default configuration for validation of metadata 99 | mv_tolerate_additional_tables = abap_false. 100 | mv_tolerate_deviating_fields = abap_true. 101 | mv_tolerate_deviating_types = abap_false. 102 | 103 | CONSTANTS co_logical_transport_object TYPE c LENGTH 1 VALUE 'L'. 104 | 105 | * get the TLOGO properties as stored in transaction SOBJ 106 | 107 | * object header 108 | SELECT SINGLE * FROM objh INTO ms_object_header 109 | WHERE objectname = mv_object 110 | AND objecttype = co_logical_transport_object. 111 | 112 | IF ms_object_header IS INITIAL. 113 | RAISE EXCEPTION TYPE lcx_obj_exception 114 | EXPORTING 115 | iv_text = |Unsupported object-type { mv_object }|. 116 | ENDIF. 117 | 118 | * object tables 119 | SELECT * FROM objsl INTO CORRESPONDING FIELDS OF TABLE mt_object_table 120 | WHERE objectname = mv_object 121 | AND objecttype = co_logical_transport_object 122 | AND tobject = 'TABU'. 123 | IF mt_object_table IS INITIAL. 124 | RAISE EXCEPTION TYPE lcx_obj_exception 125 | EXPORTING 126 | iv_text = |Obviously corrupted object-type { mv_object }: No tables defined|. 127 | ENDIF. 128 | 129 | LOOP AT mt_object_table ASSIGNING . 130 | -field_catalog = lcl_catalog=>build( -tobj_name ). 131 | ENDLOOP. 132 | 133 | * object methods 134 | SELECT * FROM objm INTO TABLE mt_object_method 135 | WHERE objectname = mv_object 136 | AND objecttype = co_logical_transport_object. 137 | 138 | ENDMETHOD. 139 | 140 | METHOD get_primary_table. 141 | READ TABLE mt_object_table INTO rs_object_table WITH KEY prim_table = abap_true. 142 | IF sy-subrc <> 0. 143 | * Fallback. For some objects, no primary table is explicitly flagged 144 | * The, the one with only one key field shall be chosen 145 | READ TABLE mt_object_table INTO rs_object_table WITH KEY tobjkey = '/&'. "#EC CI_SUBRC 146 | ENDIF. 147 | IF rs_object_table IS INITIAL. 148 | RAISE EXCEPTION TYPE lcx_obj_exception 149 | EXPORTING 150 | iv_text = |Object { mv_object } has got no defined primary table|. 151 | ENDIF. 152 | ENDMETHOD. 153 | 154 | METHOD export_object. 155 | DATA lt_table_content TYPE lif_external_object_container=>ty_t_table_content. 156 | me->before_export( ). 157 | 158 | me->get_current_tables_content( 159 | EXPORTING io_object_container = io_object_container "this allows the container to store tables one-by-one 160 | IMPORTING et_table_content = lt_table_content ). 161 | 162 | ENDMETHOD. 163 | 164 | METHOD import_object. 165 | 166 | * enable backing-up of current table's content 167 | DATA lt_current_table_content TYPE lif_external_object_container=>ty_t_table_content. 168 | me->get_current_tables_content( IMPORTING et_table_content = lt_current_table_content ). 169 | io_object_container->backup_replaced_version( lt_current_table_content ). 170 | 171 | * extract content from container 172 | DATA lt_imported_table_content TYPE lif_external_object_container=>ty_t_table_content. 173 | DATA lt_relevant_table TYPE lif_external_object_container=>ty_t_tabname. 174 | DATA lv_relevant_table LIKE LINE OF lt_relevant_table. 175 | FIELD-SYMBOLS LIKE LINE OF mt_object_table. 176 | 177 | CLEAR lt_relevant_table. 178 | LOOP AT mt_object_table ASSIGNING . 179 | lv_relevant_table = -tobj_name. 180 | INSERT lv_relevant_table INTO TABLE lt_relevant_table. 181 | ENDLOOP. 182 | 183 | io_object_container->get_persisted_table_content( 184 | EXPORTING 185 | it_relevant_table = lt_relevant_table 186 | IMPORTING 187 | et_table_content = lt_imported_table_content ). 188 | 189 | * validate the content to be imported: Based on the keys of the current system's primary-table, 190 | * the content to be imported must provide exactly one item! 191 | DATA ls_primary_table TYPE ty_s_object_table. 192 | DATA lv_where_primary_table TYPE string. 193 | FIELD-SYMBOLS LIKE LINE OF lt_imported_table_content. 194 | 195 | ls_primary_table = me->get_primary_table( ). 196 | lv_where_primary_table = me->get_where_clause( iv_tobj_name = ls_primary_table-tobj_name ). 197 | 198 | READ TABLE lt_imported_table_content ASSIGNING 199 | WITH TABLE KEY tabname = ls_primary_table-tobj_name. 200 | IF sy-subrc <> 0. 201 | RAISE EXCEPTION TYPE lcx_obj_exception 202 | EXPORTING 203 | iv_text = |Primary table { ls_primary_table-tobj_name } not found in imported container |. 204 | ENDIF. 205 | 206 | DATA lv_count TYPE i. 207 | FIELD-SYMBOLS TYPE ANY TABLE. 208 | CLEAR lv_count. 209 | 210 | ASSIGN -data_tab->* TO . 211 | LOOP AT TRANSPORTING NO FIELDS WHERE (lv_where_primary_table). 212 | ADD 1 TO lv_count. 213 | IF lv_count > 1. 214 | RAISE EXCEPTION TYPE lcx_obj_exception 215 | EXPORTING 216 | iv_text = |Primary table { ls_primary_table-tobj_name } contains more than one instance! |. 217 | ENDIF. 218 | ENDLOOP. 219 | 220 | 221 | * validate that max one local instance was affected by the import 222 | SELECT COUNT(*) FROM (ls_primary_table-tobj_name) WHERE (lv_where_primary_table). 223 | IF sy-dbcnt > 1. 224 | RAISE EXCEPTION TYPE lcx_obj_exception 225 | EXPORTING 226 | iv_text = |More than one instance exists locally in primary table { ls_primary_table-tobj_name }|. 227 | ENDIF. 228 | 229 | * do the actual update of the local data 230 | * as the imported data might not feature all aspects of the local object ( not all tables need to be populated) 231 | * we first purge local object data 232 | me->delete_object_on_db( ). 233 | 234 | * insert data from imported tables 235 | FIELD-SYMBOLS LIKE LINE OF lt_imported_table_content. 236 | DATA lv_structures_identical TYPE abap_bool. 237 | LOOP AT lt_imported_table_content ASSIGNING . 238 | IF NOT -data_tab IS INITIAL. 239 | ASSIGN -data_tab->* TO . 240 | ELSE. 241 | IF IS ASSIGNED. 242 | UNASSIGN . 243 | ENDIF. 244 | ENDIF. 245 | IF NOT IS ASSIGNED 246 | OR lines( ) = 0. 247 | CONTINUE. "Performance improvement 248 | ENDIF. 249 | READ TABLE mt_object_table ASSIGNING 250 | WITH KEY table_name COMPONENTS tobj_name = -tabname. 251 | IF sy-subrc <> 0. 252 | IF mv_tolerate_additional_tables = abap_true. 253 | CONTINUE. 254 | ELSE. 255 | RAISE EXCEPTION TYPE lcx_obj_exception 256 | EXPORTING 257 | iv_text = |Imported container contains table { -tabname 258 | } which does not exist in local object definition|. 259 | ENDIF. 260 | ENDIF. 261 | 262 | me->val_fieldcatalog_compatibility( 263 | EXPORTING 264 | it_imported_fieldcatalog = -field_catalog 265 | it_local_fieldcatalog = -field_catalog 266 | IMPORTING 267 | ev_is_identical = lv_structures_identical ). 268 | 269 | ** IF lv_structures_identical = abap_true. 270 | ** do_insert( iv_table_name = -tabname 271 | ** it_data = ). 272 | ** ELSE. 273 | * as the structure deviate, it's not an option to directly insert from the imported table. 274 | * The format needs to be adapted first (even in ABAP, there is no "INSERT INTO CORRESPONDING FIELDS OF dbtab" ;) 275 | DATA lr_local_format_tab TYPE REF TO data. 276 | DATA lr_local_format TYPE REF TO data. 277 | FIELD-SYMBOLS TYPE STANDARD TABLE. 278 | FIELD-SYMBOLS TYPE any. 279 | FIELD-SYMBOLS TYPE any. 280 | 281 | CREATE DATA lr_local_format_tab TYPE STANDARD TABLE OF (-tabname) WITH DEFAULT KEY. 282 | ASSIGN lr_local_format_tab->* TO . 283 | 284 | CREATE DATA lr_local_format TYPE (-tabname). 285 | ASSIGN lr_local_format->* TO . 286 | 287 | LOOP AT ASSIGNING . 288 | MOVE-CORRESPONDING TO . 289 | INSERT INTO TABLE . 290 | ENDLOOP. 291 | 292 | do_insert( iv_table_name = -tabname 293 | it_data = ). 294 | ** ENDIF. 295 | ENDLOOP. 296 | 297 | 298 | me->after_import( ). 299 | ENDMETHOD. 300 | 301 | 302 | METHOD before_export. 303 | FIELD-SYMBOLS LIKE LINE OF mt_object_method. 304 | DATA lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY. 305 | DATA ls_cts_object_entry LIKE LINE OF lt_cts_object_entry. 306 | DATA lt_cts_key TYPE STANDARD TABLE OF e071k WITH DEFAULT KEY. 307 | DATA lv_client TYPE trclient. 308 | 309 | lv_client = sy-mandt. 310 | 311 | ls_cts_object_entry-pgmid = rs_c_pgmid_r3tr. 312 | ls_cts_object_entry-object = mv_object. 313 | ls_cts_object_entry-obj_name = mv_object_name. 314 | INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry. 315 | 316 | READ TABLE mt_object_method ASSIGNING 317 | WITH TABLE KEY 318 | objectname = mv_object 319 | objecttype = 'L' 320 | method = 'BEFORE_EXP' ##no_text. 321 | 322 | IF sy-subrc = 0. 323 | CALL FUNCTION -methodname 324 | EXPORTING 325 | iv_client = lv_client 326 | TABLES 327 | tt_e071 = lt_cts_object_entry 328 | tt_e071k = lt_cts_key. 329 | ENDIF. 330 | ENDMETHOD. 331 | 332 | 333 | METHOD after_import. 334 | * this method re-uses the BW-function-module for executing the After-Import-methods 335 | 336 | DATA lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY. 337 | DATA ls_cts_object_entry LIKE LINE OF lt_cts_object_entry. 338 | DATA lt_cts_key TYPE STANDARD TABLE OF e071k WITH DEFAULT KEY. 339 | 340 | FIELD-SYMBOLS LIKE LINE OF mt_object_method. 341 | 342 | ls_cts_object_entry-pgmid = rs_c_pgmid_r3tr. 343 | ls_cts_object_entry-object = mv_object. 344 | ls_cts_object_entry-obj_name = mv_object_name. 345 | INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry. 346 | 347 | READ TABLE mt_object_method ASSIGNING 348 | WITH TABLE KEY 349 | objectname = mv_object 350 | objecttype = 'L' 351 | method = 'AFTER_IMP' ##no_text. 352 | 353 | IF sy-subrc = 0. 354 | CALL FUNCTION -methodname 355 | EXPORTING 356 | iv_tarclient = sy-mandt "this is actually optional for most AIM, but let's supply it and hope that those client-independent-ones just ignore it 357 | iv_is_upgrade = abap_false 358 | TABLES 359 | tt_e071 = lt_cts_object_entry 360 | tt_e071k = lt_cts_key. 361 | ENDIF. 362 | 363 | ENDMETHOD. 364 | 365 | 366 | METHOD instance_exists. 367 | * check whether an object with this name exists in the primary table 368 | DATA ls_primary_table LIKE LINE OF mt_object_table. 369 | DATA lv_where_clause TYPE string. 370 | 371 | ls_primary_table = get_primary_table( ). 372 | 373 | lv_where_clause = me->get_where_clause( ls_primary_table-tobj_name ). 374 | 375 | DATA lr_table_line TYPE REF TO data. 376 | FIELD-SYMBOLS TYPE any. 377 | CREATE DATA lr_table_line TYPE (ls_primary_table-tobj_name). 378 | ASSIGN lr_table_line->* TO . 379 | SELECT SINGLE * FROM (ls_primary_table-tobj_name) INTO WHERE (lv_where_clause). 380 | 381 | rv_exists = boolc( sy-dbcnt > 0 ). 382 | 383 | ENDMETHOD. 384 | 385 | METHOD get_where_clause. 386 | FIELD-SYMBOLS LIKE LINE OF mt_object_table. 387 | READ TABLE mt_object_table ASSIGNING WITH KEY table_name COMPONENTS tobj_name = iv_tobj_name. 388 | ASSERT sy-subrc = 0. 389 | 390 | DATA lv_objkey_pos TYPE i. 391 | DATA lv_next_objkey_pos TYPE i. 392 | DATA lv_value_pos TYPE i. 393 | DATA lv_objkey_length TYPE i. 394 | DATA lt_objkey TYPE ty_t_objkey. 395 | DATA ls_objkey LIKE LINE OF lt_objkey. 396 | DATA lv_non_value_pos TYPE numc3. 397 | DATA lt_key_component LIKE -field_catalog. 398 | DATA ls_fieldcat_component LIKE LINE OF lt_key_component. 399 | 400 | CLEAR lt_key_component. 401 | LOOP AT -field_catalog INTO ls_fieldcat_component USING KEY is_key 402 | WHERE is_key = abap_true. 403 | INSERT ls_fieldcat_component INTO TABLE lt_key_component. 404 | ENDLOOP. 405 | 406 | * analyze the object key and compose the key (table) 407 | CLEAR lt_objkey. 408 | CLEAR ls_objkey. 409 | lv_objkey_pos = 0. 410 | lv_non_value_pos = 1. 411 | lv_value_pos = 0. 412 | lv_objkey_length = strlen( -tobjkey ). 413 | WHILE lv_objkey_pos <= lv_objkey_length. 414 | ls_objkey-num = lv_non_value_pos. 415 | * command 416 | IF -tobjkey+lv_objkey_pos(1) = '/'. 417 | IF NOT ls_objkey-value IS INITIAL. 418 | * We reached the end of a key-definition. 419 | * this key part may address multiple fields. 420 | * E. g. six characters may address one boolean field and a five-digit version field. 421 | * Thus, we need to analyze the remaining key components which have not been covered yet. 422 | split_value_to_keys( 423 | EXPORTING 424 | it_key_component = lt_key_component 425 | CHANGING 426 | ct_objkey = lt_objkey 427 | cs_objkey = ls_objkey 428 | cv_non_value_pos = lv_non_value_pos ). 429 | ENDIF. 430 | lv_next_objkey_pos = lv_objkey_pos + 1. 431 | * '*' means all further key values 432 | IF -tobjkey+lv_next_objkey_pos(1) = '*'. 433 | ls_objkey-value = '*'. 434 | INSERT ls_objkey INTO TABLE lt_objkey. 435 | CLEAR ls_objkey. 436 | ADD 1 TO lv_non_value_pos. 437 | ADD 1 TO lv_objkey_pos. 438 | * object name 439 | ELSEIF -tobjkey+lv_next_objkey_pos(1) = '&'. 440 | "TODO 441 | ls_objkey-value = mv_object_name. 442 | * The object name might comprise multiple key components (e. g. WDCC) 443 | * This string needs to be split 444 | distribute_name_to_components( 445 | EXPORTING 446 | it_key_component = lt_key_component 447 | CHANGING 448 | ct_objkey = lt_objkey 449 | cs_objkey = ls_objkey 450 | cv_non_value_pos = lv_non_value_pos ). 451 | CLEAR ls_objkey. 452 | * ADD 1 TO lv_non_value_pos. 453 | ADD 1 TO lv_objkey_pos. 454 | * language 455 | ELSEIF -tobjkey+lv_next_objkey_pos(1) = 'L'. 456 | ls_objkey-value = sy-langu. 457 | INSERT ls_objkey INTO TABLE lt_objkey. 458 | CLEAR ls_objkey. 459 | ADD 1 TO lv_non_value_pos. 460 | ADD 1 TO lv_objkey_pos. 461 | * Client 462 | ELSEIF -tobjkey+lv_next_objkey_pos(1) = 'C'. 463 | ls_objkey-value = sy-mandt. 464 | INSERT ls_objkey INTO TABLE lt_objkey. 465 | CLEAR ls_objkey. 466 | ADD 1 TO lv_non_value_pos. 467 | ADD 1 TO lv_objkey_pos. 468 | ENDIF. 469 | lv_value_pos = 0. 470 | * value 471 | ELSE. 472 | ls_objkey-value+lv_value_pos(1) = -tobjkey+lv_objkey_pos(1). 473 | ADD 1 TO lv_value_pos. 474 | ENDIF. 475 | 476 | ADD 1 TO lv_objkey_pos. 477 | ENDWHILE. 478 | 479 | * Similarly to that, fixed values might be supplied in the object key which actually make up key components 480 | IF NOT ls_objkey-value IS INITIAL. 481 | split_value_to_keys( 482 | EXPORTING 483 | it_key_component = lt_key_component 484 | CHANGING 485 | ct_objkey = lt_objkey 486 | cs_objkey = ls_objkey 487 | cv_non_value_pos = lv_non_value_pos ). 488 | ENDIF. 489 | 490 | * compose the where clause 491 | DATA lv_is_asterix TYPE abap_bool. 492 | DATA lv_where_statement TYPE string. 493 | DATA lv_key_pos TYPE i. 494 | DATA lv_value128 TYPE string. 495 | FIELD-SYMBOLS LIKE LINE OF -field_catalog. 496 | 497 | lv_is_asterix = abap_false. 498 | lv_key_pos = 1. 499 | 500 | LOOP AT -field_catalog ASSIGNING 501 | USING KEY is_key WHERE is_key = abap_true. 502 | * #CP-SUPPRESS: FP no risc 503 | READ TABLE lt_objkey INTO ls_objkey 504 | WITH TABLE KEY num = lv_key_pos. 505 | IF sy-subrc <> 0 OR -name = 'LANGU'. 506 | CLEAR ls_objkey. 507 | ADD 1 TO lv_key_pos. 508 | CONTINUE. 509 | ENDIF. 510 | IF ls_objkey-value = '*'. 511 | lv_is_asterix = rs_c_true. 512 | ENDIF. 513 | IF lv_is_asterix = rs_c_true. 514 | CONTINUE. 515 | ENDIF. 516 | IF NOT lv_where_statement IS INITIAL. 517 | * #CP-SUPPRESS: FP no risc 518 | CONCATENATE lv_where_statement 'AND' INTO lv_where_statement 519 | SEPARATED BY space. 520 | ENDIF. 521 | * #CP-SUPPRESS: FP no risc 522 | CONCATENATE '''' ls_objkey-value '''' INTO lv_value128. 523 | * #CP-SUPPRESS: FP no risc 524 | CONCATENATE lv_where_statement -name '=' 525 | lv_value128 INTO lv_where_statement SEPARATED BY space. 526 | ADD 1 TO lv_key_pos. 527 | ENDLOOP. 528 | rv_where_on_keys = condense( lv_where_statement ). 529 | ENDMETHOD. 530 | 531 | 532 | METHOD get_current_tables_content. 533 | 534 | DATA ls_table_content LIKE LINE OF et_table_content. 535 | FIELD-SYMBOLS LIKE LINE OF mt_object_table. 536 | 537 | LOOP AT mt_object_table ASSIGNING . 538 | CLEAR ls_table_content. 539 | ls_table_content-tabname = -tobj_name. 540 | ls_table_content-field_catalog = -field_catalog. 541 | 542 | * select from database table using the key 543 | DATA lv_where_on_keys TYPE string. 544 | FIELD-SYMBOLS TYPE STANDARD TABLE. 545 | CREATE DATA ls_table_content-data_tab TYPE STANDARD TABLE OF (-tobj_name). 546 | ASSIGN ls_table_content-data_tab->* TO . 547 | 548 | lv_where_on_keys = me->get_where_clause( -tobj_name ). 549 | 550 | SELECT * FROM (-tobj_name) 551 | INTO TABLE 552 | WHERE (lv_where_on_keys) 553 | ORDER BY PRIMARY KEY. 554 | 555 | * two consumers: exporting the object to the container and providing all table-content to a container 556 | IF io_object_container IS NOT INITIAL. 557 | io_object_container->store_obj_table( ls_table_content ). 558 | ENDIF. 559 | 560 | IF et_table_content IS SUPPLIED. 561 | INSERT ls_table_content INTO TABLE et_table_content. 562 | ENDIF. 563 | ENDLOOP. 564 | 565 | ENDMETHOD. 566 | 567 | 568 | METHOD val_fieldcatalog_compatibility. 569 | * It is common that between releases the table structures of objects deviate. 570 | * Usually, in a newer release, fields are being added, rarely removed. 571 | * But as we cannot know whether the system from which is in-fact being imported 572 | * is on a more recent release, we can only check whether the structures deviate, 573 | * not whether there are "additional" or "missing" fields. 574 | 575 | * Types however rarely change. Therefore, this is a second validation. 576 | 577 | * Both validations can be skipped my manipulating member variables. 578 | 579 | DATA ls_local_field_def LIKE LINE OF it_local_fieldcatalog. 580 | DATA ls_imported_field_def LIKE LINE OF it_imported_fieldcatalog. 581 | 582 | DATA lt_imported_fieldcatalog LIKE it_imported_fieldcatalog. "create a copy in order to delete matching entries from it 583 | lt_imported_fieldcatalog = it_imported_fieldcatalog. 584 | 585 | ev_is_identical = abap_true. 586 | LOOP AT it_local_fieldcatalog INTO ls_local_field_def. 587 | READ TABLE it_imported_fieldcatalog INTO ls_imported_field_def 588 | WITH KEY name COMPONENTS name = ls_local_field_def-name. "#EC CI_SUBRC 589 | 590 | * The position of the attribute is not relevant with respect to comparison 591 | CLEAR: ls_imported_field_def-pos, 592 | ls_local_field_def-pos. 593 | 594 | IF sy-subrc <> 0. 595 | ev_is_identical = abap_false. 596 | IF mv_tolerate_deviating_fields = abap_true. 597 | CONTINUE. ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 598 | ELSE. 599 | RAISE EXCEPTION TYPE lcx_obj_exception 600 | EXPORTING 601 | iv_text = |Field { ls_local_field_def-name } does not exist in imported data structure|. 602 | ENDIF. 603 | ENDIF. 604 | 605 | IF ls_imported_field_def-type_kind <> ls_local_field_def-type_kind 606 | OR ls_imported_field_def-length > ls_local_field_def-length 607 | OR ls_imported_field_def-decimals > ls_local_field_def-decimals. 608 | ev_is_identical = abap_false. 609 | IF mv_tolerate_deviating_types = abap_true. 610 | CONTINUE. ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 611 | ELSE. 612 | RAISE EXCEPTION TYPE lcx_obj_exception 613 | EXPORTING 614 | iv_text = |Field { ls_local_field_def-name } has got a different type in local and imported data structure|. 615 | ENDIF. 616 | ENDIF. 617 | 618 | DELETE lt_imported_fieldcatalog WHERE name = ls_local_field_def-name. 619 | 620 | ENDLOOP. 621 | 622 | IF lt_imported_fieldcatalog IS NOT INITIAL. "not all fields matched. 623 | ev_is_identical = abap_false. 624 | IF mv_tolerate_deviating_fields = abap_false. 625 | RAISE EXCEPTION TYPE lcx_obj_exception 626 | EXPORTING 627 | iv_text = |There are fields in the imported table which do not exist in local data structure|. 628 | ENDIF. 629 | ENDIF. 630 | 631 | ENDMETHOD. 632 | 633 | 634 | METHOD do_insert. 635 | * do not operate on the database if executed as part of the unittest. 636 | INSERT (iv_table_name) FROM TABLE it_data. 637 | ENDMETHOD. 638 | 639 | 640 | METHOD do_delete. 641 | * do not operate on the database if executed as part of the unittest. 642 | DELETE FROM (iv_table_name) WHERE (iv_where_on_keys). 643 | ENDMETHOD. 644 | 645 | 646 | METHOD delete_object_on_db. 647 | DATA lv_where_on_keys TYPE string. 648 | FIELD-SYMBOLS LIKE LINE OF mt_object_table. 649 | 650 | LOOP AT mt_object_table ASSIGNING . 651 | lv_where_on_keys = me->get_where_clause( -tobj_name ). 652 | 653 | do_delete( iv_table_name = -tobj_name 654 | iv_where_on_keys = lv_where_on_keys ). 655 | 656 | IF -prim_table = abap_true. 657 | ASSERT sy-dbcnt <= 1. "Just to be on the very safe side 658 | ENDIF. 659 | ENDLOOP. 660 | ENDMETHOD. 661 | 662 | METHOD split_value_to_keys. 663 | 664 | DATA lt_key_component_uncovered TYPE lcl_tlogo_bridge=>ty_s_object_table-field_catalog. 665 | DATA ls_key_component_uncovered TYPE lif_external_object_container=>ty_s_component. 666 | 667 | lt_key_component_uncovered = it_key_component. 668 | DATA ls_dummy LIKE LINE OF ct_objkey. 669 | 670 | * we want to fill the atribute values which are not covered by explicit key components yet 671 | LOOP AT ct_objkey INTO ls_dummy. 672 | DELETE lt_key_component_uncovered INDEX 1. 673 | ENDLOOP. 674 | 675 | DATA ls_objkey_sub LIKE cs_objkey. 676 | DATA lv_objkey_sub_pos TYPE i. 677 | 678 | ls_objkey_sub-num = cs_objkey-num. 679 | lv_objkey_sub_pos = 0. 680 | LOOP AT lt_key_component_uncovered INTO ls_key_component_uncovered. 681 | CLEAR ls_objkey_sub-value. 682 | ls_objkey_sub-value = cs_objkey-value+lv_objkey_sub_pos(ls_key_component_uncovered-length). 683 | ls_objkey_sub-num = cv_non_value_pos. 684 | 685 | INSERT ls_objkey_sub INTO TABLE ct_objkey. 686 | 687 | ADD ls_key_component_uncovered-length TO lv_objkey_sub_pos. 688 | ADD 1 TO cv_non_value_pos. 689 | CLEAR ls_objkey_sub. 690 | 691 | IF lv_objkey_sub_pos = strlen( cs_objkey-value ). 692 | cs_objkey-num = cv_non_value_pos. 693 | EXIT. "end splitting - all characters captured 694 | ENDIF. 695 | ENDLOOP. 696 | 697 | ENDMETHOD. 698 | 699 | METHOD distribute_name_to_components. 700 | DATA lt_key_component_uncovered TYPE lcl_tlogo_bridge=>ty_s_object_table-field_catalog. 701 | DATA ls_key_component_uncovered TYPE lif_external_object_container=>ty_s_component. 702 | DATA ls_dummy LIKE LINE OF ct_objkey. 703 | DATA ls_objkey_sub LIKE cs_objkey. 704 | DATA lv_objkey_sub_pos TYPE i. 705 | 706 | lt_key_component_uncovered = it_key_component. 707 | ls_objkey_sub-num = cs_objkey-num. 708 | lv_objkey_sub_pos = 0. 709 | 710 | * we want to fill the atribute values which are not covered by explicit key components yet 711 | DATA lv_count_components_covered LIKE ls_objkey_sub-num. 712 | lv_count_components_covered = ls_objkey_sub-num - 1. 713 | DO lv_count_components_covered TIMES. 714 | DELETE lt_key_component_uncovered INDEX 1. 715 | ENDDO. 716 | 717 | LOOP AT lt_key_component_uncovered INTO ls_key_component_uncovered. 718 | CLEAR ls_objkey_sub-value. 719 | DATA lv_len LIKE ls_key_component_uncovered-length. 720 | 721 | * Some datatype used in the key might exceed the total remaining characters length (e. g. SICF) 722 | TRY. 723 | DATA: lv_remaining_length TYPE i. 724 | lv_remaining_length = strlen( |{ substring( val = cs_objkey-value off = lv_objkey_sub_pos ) }| ). 725 | CATCH cx_sy_range_out_of_bounds. 726 | lv_remaining_length = 0. 727 | RETURN. ">>>>>>>>>>>>>>>>>>>>>>>>>>> 728 | ENDTRY. 729 | IF ls_key_component_uncovered-length <= lv_remaining_length. 730 | lv_len = ls_key_component_uncovered-length. 731 | ELSE. 732 | lv_len = lv_remaining_length. 733 | ENDIF. 734 | 735 | ls_objkey_sub-value = |{ substring( val = cs_objkey-value off = lv_objkey_sub_pos len = lv_len ) }|. 736 | ls_objkey_sub-num = cv_non_value_pos. 737 | 738 | IF ls_key_component_uncovered-type_kind = cl_abap_typedescr=>typekind_int 739 | AND condense( ls_objkey_sub-value ) CN '0123456789'. 740 | " Avoid CONVT_NO_NUMBER dump for tables with INT-keys 741 | CONTINUE. 742 | ENDIF. 743 | 744 | INSERT ls_objkey_sub INTO TABLE ct_objkey. 745 | 746 | ADD ls_key_component_uncovered-length TO lv_objkey_sub_pos. 747 | ADD 1 TO cv_non_value_pos. 748 | CLEAR ls_objkey_sub. 749 | 750 | IF lv_objkey_sub_pos = strlen( cs_objkey-value ). 751 | cs_objkey-num = cv_non_value_pos. 752 | EXIT. "end splitting - all characters captured 753 | ENDIF. 754 | ENDLOOP. 755 | ENDMETHOD. 756 | 757 | ENDCLASS. 758 | 759 | 760 | CLASS lcx_obj_exception IMPLEMENTATION. 761 | 762 | METHOD constructor. 763 | super->constructor( textid = textid 764 | previous = previous ). 765 | mv_text = iv_text. 766 | ENDMETHOD. 767 | 768 | METHOD get_text. 769 | * todo, perhaps remove mv_text attribute? 770 | result = mv_text. 771 | ENDMETHOD. 772 | 773 | ENDCLASS. 774 | 775 | 776 | CLASS lcl_abapgit_xml_container IMPLEMENTATION. 777 | 778 | METHOD lif_external_object_container~store_obj_table. 779 | 780 | DATA lx_abapgit_object TYPE REF TO zcx_abapgitp_object. 781 | 782 | FIELD-SYMBOLS TYPE ANY TABLE. 783 | 784 | ASSIGN is_table_content-data_tab->* TO . 785 | TRY. 786 | mo_xml_output->add( iv_name = |{ is_table_content-tabname }| 787 | ig_data = ). 788 | 789 | mo_xml_output->add( iv_name = |{ is_table_content-tabname }{ co_suffix_fieldcat }| 790 | ig_data = is_table_content-field_catalog ). 791 | 792 | CATCH zcx_abapgitp_object INTO lx_abapgit_object. 793 | RAISE EXCEPTION TYPE lcx_obj_exception 794 | EXPORTING 795 | iv_text = lx_abapgit_object->get_text( ) 796 | previous = lx_abapgit_object. 797 | ENDTRY. 798 | ENDMETHOD. 799 | 800 | METHOD lif_external_object_container~get_persisted_table_content. 801 | DATA: lx_abapgit_object TYPE REF TO zcx_abapgitp_object, 802 | ls_table_content LIKE LINE OF et_table_content. 803 | 804 | FIELD-SYMBOLS: TYPE ANY TABLE, 805 | LIKE LINE OF et_table_content. 806 | 807 | 808 | LOOP AT it_relevant_table INTO ls_table_content-tabname. 809 | INSERT ls_table_content INTO TABLE et_table_content ASSIGNING . 810 | 811 | * The content in the external container may deviate with respect to its structure from the local one. 812 | * No! "create data -data_tab type STANDARD TABLE OF (-tabname) with DEFAULT KEY." 813 | * Thus, the persisted content needs to be read into a structure which matches the fieldcatalog 814 | * with which it has been serialized 815 | TRY. 816 | 817 | mo_xml_input->read( 818 | EXPORTING 819 | iv_name = |{ -tabname }{ co_suffix_fieldcat }| 820 | CHANGING 821 | cg_data = -field_catalog ). 822 | CATCH zcx_abapgitp_object INTO lx_abapgit_object. 823 | RAISE EXCEPTION TYPE lcx_obj_exception 824 | EXPORTING 825 | iv_text = lx_abapgit_object->get_text( ) 826 | previous = lx_abapgit_object. 827 | CATCH cx_sy_move_cast_error. 828 | RAISE EXCEPTION TYPE lcx_obj_exception 829 | EXPORTING 830 | iv_text = |Table metadata could not be serialized properly. Could not serialize table { -tabname }|. 831 | ENDTRY. 832 | 833 | 834 | IF lines( -field_catalog ) = 0. 835 | * ignore tables that are new in upgraded systems 836 | CONTINUE. 837 | ENDIF. 838 | 839 | DATA lo_tabledescr TYPE REF TO cl_abap_tabledescr. 840 | 841 | 842 | create_table_descriptor( 843 | EXPORTING 844 | it_field_catalog = -field_catalog 845 | IMPORTING 846 | eo_tabledescr = lo_tabledescr ). 847 | 848 | CREATE DATA -data_tab TYPE HANDLE lo_tabledescr. 849 | 850 | ASSIGN -data_tab->* TO . 851 | 852 | * Read the persisted data 853 | TRY. 854 | mo_xml_input->read( 855 | EXPORTING 856 | iv_name = |{ -tabname }| 857 | CHANGING 858 | cg_data = ). 859 | 860 | CATCH zcx_abapgitp_object INTO lx_abapgit_object. 861 | RAISE EXCEPTION TYPE lcx_obj_exception 862 | EXPORTING 863 | iv_text = lx_abapgit_object->get_text( ) 864 | previous = lx_abapgit_object. 865 | CATCH cx_sy_move_cast_error. 866 | RAISE EXCEPTION TYPE lcx_obj_exception 867 | EXPORTING 868 | iv_text = |Persisted structure deviated from metadata. Could not serialize table { -tabname }|. 869 | ENDTRY. 870 | ENDLOOP. 871 | ENDMETHOD. 872 | 873 | METHOD lif_external_object_container~backup_replaced_version. 874 | "todo: not implemented yet. 875 | * Idea: create a new file containing the backup. 876 | * Open: How to properly inject the files-object 877 | ENDMETHOD. 878 | 879 | METHOD create_table_descriptor. 880 | 881 | DATA lo_structdescr TYPE REF TO cl_abap_structdescr. 882 | DATA lt_component TYPE cl_abap_structdescr=>component_table. 883 | DATA ls_component LIKE LINE OF lt_component. 884 | DATA lx_parameter_invalid_range TYPE REF TO cx_parameter_invalid_range. 885 | FIELD-SYMBOLS LIKE LINE OF it_field_catalog. 886 | 887 | CLEAR: ls_component, lt_component, lo_structdescr. 888 | LOOP AT it_field_catalog ASSIGNING . 889 | ls_component-name = -name. 890 | TRY. 891 | CASE -type_kind. 892 | WHEN cl_abap_typedescr=>typekind_char 893 | OR cl_abap_typedescr=>typekind_clike 894 | OR cl_abap_typedescr=>typekind_csequence. 895 | ls_component-type = cl_abap_elemdescr=>get_c( -length ). 896 | WHEN cl_abap_typedescr=>typekind_date. 897 | ls_component-type = cl_abap_elemdescr=>get_d( ). 898 | WHEN cl_abap_typedescr=>typekind_decfloat 899 | OR cl_abap_typedescr=>typekind_float. 900 | ls_component-type = cl_abap_elemdescr=>get_f( ). 901 | WHEN cl_abap_typedescr=>typekind_decfloat16. 902 | ls_component-type = cl_abap_elemdescr=>get_decfloat16( ). 903 | WHEN cl_abap_typedescr=>typekind_decfloat34. 904 | ls_component-type = cl_abap_elemdescr=>get_decfloat34( ). 905 | WHEN cl_abap_typedescr=>typekind_hex. 906 | ls_component-type = cl_abap_elemdescr=>get_x( -length ). 907 | WHEN cl_abap_typedescr=>typekind_int 908 | OR cl_abap_typedescr=>typekind_int1 909 | OR cl_abap_typedescr=>typekind_int2 910 | OR cl_abap_typedescr=>typekind_simple. 911 | ls_component-type = cl_abap_elemdescr=>get_i( ). 912 | WHEN cl_abap_typedescr=>typekind_num 913 | OR cl_abap_typedescr=>typekind_numeric. 914 | ls_component-type = cl_abap_elemdescr=>get_n( -length ). 915 | WHEN cl_abap_typedescr=>typekind_packed. 916 | ls_component-type = cl_abap_elemdescr=>get_p( 917 | p_length = -length 918 | p_decimals = -decimals ). 919 | WHEN cl_abap_typedescr=>typekind_time. 920 | ls_component-type = cl_abap_elemdescr=>get_t( ). 921 | WHEN cl_abap_typedescr=>typekind_string. 922 | ls_component-type = cl_abap_elemdescr=>get_string( ). 923 | WHEN cl_abap_typedescr=>typekind_xsequence 924 | OR cl_abap_typedescr=>typekind_xstring. 925 | ls_component-type = cl_abap_elemdescr=>get_xstring( ). 926 | WHEN OTHERS. 927 | RAISE EXCEPTION TYPE lcx_obj_exception 928 | EXPORTING 929 | iv_text = |Unsupported type_kind { -type_kind }|. 930 | ENDCASE. 931 | 932 | INSERT ls_component INTO TABLE lt_component. 933 | 934 | CATCH cx_parameter_invalid_range INTO lx_parameter_invalid_range. 935 | RAISE EXCEPTION TYPE lcx_obj_exception 936 | EXPORTING 937 | iv_text = |Creation of type_kind { -type_kind } not possible| 938 | previous = lx_parameter_invalid_range. 939 | ENDTRY. 940 | ENDLOOP. 941 | 942 | * Create a data structure matching the persisted data's table 943 | DATA lx_sy_struct_creation TYPE REF TO cx_sy_struct_creation. 944 | TRY. 945 | lo_structdescr = cl_abap_structdescr=>create( lt_component ). 946 | CATCH cx_sy_struct_creation INTO lx_sy_struct_creation. 947 | RAISE EXCEPTION TYPE lcx_obj_exception 948 | EXPORTING 949 | iv_text = lx_sy_struct_creation->get_text( ) 950 | previous = lx_sy_struct_creation. 951 | ENDTRY. 952 | 953 | DATA lx_sy_table_creation TYPE REF TO cx_sy_table_creation. 954 | TRY. 955 | eo_tabledescr = cl_abap_tabledescr=>create( 956 | p_line_type = lo_structdescr 957 | p_table_kind = cl_abap_tabledescr=>tablekind_std ). 958 | CATCH cx_sy_table_creation INTO lx_sy_table_creation. 959 | RAISE EXCEPTION TYPE lcx_obj_exception 960 | EXPORTING 961 | iv_text = lx_sy_struct_creation->get_text( ) 962 | previous = lx_sy_struct_creation. 963 | ENDTRY. 964 | 965 | ENDMETHOD. 966 | 967 | METHOD set_xml_input. 968 | mo_xml_input = io_xml. 969 | ENDMETHOD. 970 | 971 | METHOD set_xml_output. 972 | mo_xml_output = io_xml. 973 | ENDMETHOD. 974 | 975 | ENDCLASS. 976 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_object_by_sobj.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAPGITP_OBJECT_BY_SOBJ 7 | E 8 | ABAPGit-Adapter for all SOBJ-based logical transport objects 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_xml_factory.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_abapgitp_xml_factory DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PRIVATE . 5 | 6 | PUBLIC SECTION. 7 | 8 | CLASS-METHODS wrap_xml_input 9 | IMPORTING 10 | !io_xml TYPE REF TO object 11 | RETURNING 12 | VALUE(ro_xml_proxy) TYPE REF TO zif_abapgitp_xml_input . 13 | CLASS-METHODS wrap_xml_output 14 | IMPORTING 15 | !io_xml TYPE REF TO object 16 | RETURNING 17 | VALUE(ro_xml_proxy) TYPE REF TO zif_abapgitp_xml_output . 18 | CLASS-METHODS create_xml_input 19 | IMPORTING 20 | !iv_xml TYPE string OPTIONAL 21 | RETURNING 22 | VALUE(ro_xml_proxy) TYPE REF TO zif_abapgitp_xml_input 23 | RAISING 24 | zcx_abapgitp_object . 25 | CLASS-METHODS create_xml_output 26 | RETURNING 27 | VALUE(ro_xml_proxy) TYPE REF TO zif_abapgitp_xml_output 28 | RAISING 29 | zcx_abapgitp_object . 30 | PROTECTED SECTION. 31 | PRIVATE SECTION. 32 | ENDCLASS. 33 | 34 | 35 | 36 | CLASS ZCL_ABAPGITP_XML_FACTORY IMPLEMENTATION. 37 | 38 | 39 | METHOD create_xml_input. 40 | DATA lo_wrapped_xml TYPE REF TO object. 41 | 42 | * IF iv_xml IS SUPPLIED. 43 | CREATE OBJECT lo_wrapped_xml TYPE zcl_abapgit_xml_input 44 | EXPORTING 45 | iv_xml = iv_xml. 46 | * ELSE. 47 | * CREATE OBJECT lo_wrapped_xml TYPE zcl_abapgit_xml_input. 48 | * ENDIF. 49 | 50 | ro_xml_proxy = wrap_xml_input( lo_wrapped_xml ). 51 | 52 | ENDMETHOD. 53 | 54 | 55 | METHOD create_xml_output. 56 | DATA lo_wrapped_xml TYPE REF TO object. 57 | CREATE OBJECT lo_wrapped_xml TYPE zcl_abapgit_xml_output. 58 | 59 | ro_xml_proxy = wrap_xml_output( lo_wrapped_xml ). 60 | 61 | ENDMETHOD. 62 | 63 | 64 | METHOD wrap_xml_input. 65 | CREATE OBJECT ro_xml_proxy TYPE lcl_xml_input 66 | EXPORTING 67 | io_xml = io_xml. 68 | ENDMETHOD. 69 | 70 | 71 | METHOD wrap_xml_output. 72 | CREATE OBJECT ro_xml_proxy TYPE lcl_xml_output 73 | EXPORTING 74 | io_xml = io_xml. 75 | ENDMETHOD. 76 | ENDCLASS. 77 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_xml_factory.clas.locals_imp.abap: -------------------------------------------------------------------------------- 1 | CLASS lcl_xml_output DEFINITION FINAL. 2 | PUBLIC SECTION. 3 | INTERFACES zif_abapgitp_xml_output. 4 | 5 | METHODS constructor 6 | IMPORTING 7 | io_xml TYPE REF TO object. 8 | 9 | PRIVATE SECTION. 10 | DATA mo_wrapped_xml TYPE REF TO object. 11 | ENDCLASS. 12 | 13 | CLASS lcl_xml_output IMPLEMENTATION. 14 | 15 | METHOD constructor. 16 | mo_wrapped_xml = io_xml. 17 | ENDMETHOD. 18 | 19 | METHOD zif_abapgitp_xml_output~add. 20 | CALL METHOD mo_wrapped_xml->('ZIF_ABAPGIT_XML_OUTPUT~ADD') 21 | EXPORTING 22 | iv_name = iv_name 23 | ig_data = ig_data. 24 | ENDMETHOD. 25 | 26 | METHOD zif_abapgitp_xml_output~set_raw. 27 | CALL METHOD mo_wrapped_xml->('ZIF_ABAPGIT_XML_OUTPUT~SET_RAW') 28 | EXPORTING 29 | ii_raw = ii_raw. 30 | ENDMETHOD. 31 | 32 | METHOD zif_abapgitp_xml_output~render. 33 | CALL METHOD mo_wrapped_xml->('ZIF_ABAPGIT_XML_OUTPUT~RENDER') 34 | EXPORTING 35 | iv_normalize = iv_normalize 36 | is_metadata = is_metadata 37 | RECEIVING 38 | rv_xml = rv_xml. 39 | ENDMETHOD. 40 | 41 | METHOD zif_abapgitp_xml_output~get_wrapped_xml. 42 | ro_object = mo_wrapped_xml. 43 | ENDMETHOD. 44 | 45 | ENDCLASS. 46 | 47 | CLASS lcl_xml_input DEFINITION FINAL. 48 | PUBLIC SECTION. 49 | INTERFACES zif_abapgitp_xml_input. 50 | 51 | METHODS constructor 52 | IMPORTING 53 | io_xml TYPE REF TO object. 54 | PRIVATE SECTION. 55 | DATA mo_wrapped_xml TYPE REF TO object. 56 | ENDCLASS. 57 | 58 | CLASS lcl_xml_input IMPLEMENTATION. 59 | 60 | METHOD constructor. 61 | mo_wrapped_xml = io_xml. 62 | ENDMETHOD. 63 | 64 | METHOD zif_abapgitp_xml_input~read. 65 | CALL METHOD mo_wrapped_xml->('ZIF_ABAPGIT_XML_INPUT~READ') 66 | EXPORTING 67 | iv_name = iv_name 68 | CHANGING 69 | cg_data = cg_data. 70 | ENDMETHOD. 71 | 72 | METHOD zif_abapgitp_xml_input~get_raw. 73 | CALL METHOD mo_wrapped_xml->('ZIF_ABAPGIT_XML_INPUT~GET_RAW') 74 | RECEIVING 75 | ri_raw = ri_raw. 76 | ENDMETHOD. 77 | 78 | METHOD zif_abapgitp_xml_input~get_wrapped_xml. 79 | ro_object = mo_wrapped_xml. 80 | ENDMETHOD. 81 | 82 | ENDCLASS. 83 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_xml_factory.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | 2 | CLASS ltcl_test DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS FINAL. 3 | 4 | PRIVATE SECTION. 5 | METHODS: create_xml_output FOR TESTING RAISING zcx_abapgitp_object. 6 | 7 | ENDCLASS. "ltcl_Test 8 | 9 | 10 | CLASS ltcl_test IMPLEMENTATION. 11 | 12 | METHOD create_xml_output. 13 | 14 | DATA: li_output TYPE REF TO zif_abapgitp_xml_output, 15 | ls_meta TYPE zif_abapgit_definitions=>ty_metadata, 16 | lv_output TYPE string, 17 | ls_data TYPE usr02. 18 | 19 | li_output = zcl_abapgitp_xml_factory=>create_xml_output( ). 20 | 21 | li_output->add( 22 | iv_name = 'FOOBAR' 23 | ig_data = ls_data ). 24 | 25 | lv_output = li_output->render( ls_meta ). 26 | 27 | cl_abap_unit_assert=>assert_not_initial( lv_output ). 28 | 29 | ENDMETHOD. 30 | 31 | ENDCLASS. 32 | -------------------------------------------------------------------------------- /src/zcl_abapgitp_xml_factory.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAPGITP_XML_FACTORY 7 | E 8 | Instantiates abapgit xml interfaces 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/zcx_abapgitp_object.clas.abap: -------------------------------------------------------------------------------- 1 | class ZCX_ABAPGITP_OBJECT definition 2 | public 3 | inheriting from CX_STATIC_CHECK 4 | create public . 5 | 6 | public section. 7 | 8 | data TEXT type STRING read-only . 9 | 10 | methods CONSTRUCTOR 11 | importing 12 | !TEXTID like TEXTID optional 13 | !PREVIOUS like PREVIOUS optional 14 | !TEXT type STRING optional . 15 | 16 | methods IF_MESSAGE~GET_TEXT 17 | redefinition . 18 | protected section. 19 | private section. 20 | ENDCLASS. 21 | 22 | 23 | 24 | CLASS ZCX_ABAPGITP_OBJECT IMPLEMENTATION. 25 | 26 | 27 | method CONSTRUCTOR. 28 | CALL METHOD SUPER->CONSTRUCTOR 29 | EXPORTING 30 | TEXTID = TEXTID 31 | PREVIOUS = PREVIOUS 32 | . 33 | me->TEXT = TEXT . 34 | endmethod. 35 | 36 | 37 | METHOD IF_MESSAGE~GET_TEXT. 38 | 39 | IF text IS NOT INITIAL. 40 | result = text. 41 | ELSE. 42 | result = super->get_text( ). 43 | ENDIF. 44 | 45 | ENDMETHOD. 46 | ENDCLASS. 47 | -------------------------------------------------------------------------------- /src/zcx_abapgitp_object.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCX_ABAPGITP_OBJECT 7 | E 8 | Exception in ABAPGit-plugin 9 | 40 10 | 1 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/zif_abapgitp_plugin.intf.abap: -------------------------------------------------------------------------------- 1 | INTERFACE zif_abapgitp_plugin 2 | PUBLIC . 3 | 4 | 5 | TYPES: 6 | BEGIN OF ty_metadata, 7 | class TYPE string, 8 | version TYPE string, 9 | late_deser TYPE abap_bool, 10 | delete_tadir TYPE abap_bool, 11 | ddic TYPE abap_bool, 12 | END OF ty_metadata . 13 | 14 | METHODS serialize 15 | IMPORTING 16 | !io_xml TYPE REF TO zif_abapgitp_xml_output 17 | RAISING 18 | zcx_abapgitp_object . 19 | METHODS deserialize 20 | IMPORTING 21 | !iv_package TYPE devclass 22 | !io_xml TYPE REF TO zif_abapgitp_xml_input 23 | RAISING 24 | zcx_abapgitp_object . 25 | METHODS delete 26 | RAISING 27 | zcx_abapgitp_object . 28 | METHODS exists 29 | RETURNING 30 | VALUE(rv_bool) TYPE abap_bool 31 | RAISING 32 | zcx_abapgitp_object . 33 | METHODS jump . 34 | METHODS get_metadata 35 | RETURNING 36 | VALUE(rs_metadata) TYPE ty_metadata . 37 | ENDINTERFACE. 38 | -------------------------------------------------------------------------------- /src/zif_abapgitp_plugin.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_ABAPGITP_PLUGIN 7 | E 8 | Plugin 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/zif_abapgitp_xml_input.intf.abap: -------------------------------------------------------------------------------- 1 | INTERFACE zif_abapgitp_xml_input 2 | PUBLIC . 3 | 4 | 5 | * Proxy for lcl_xml_input in ZABAPGIT 6 | METHODS read 7 | IMPORTING 8 | !iv_name TYPE clike 9 | CHANGING 10 | !cg_data TYPE any 11 | RAISING 12 | zcx_abapgitp_object . 13 | METHODS get_raw 14 | RETURNING 15 | VALUE(ri_raw) TYPE REF TO if_ixml_node . 16 | METHODS get_wrapped_xml 17 | RETURNING 18 | VALUE(ro_object) TYPE REF TO object . 19 | ENDINTERFACE. 20 | -------------------------------------------------------------------------------- /src/zif_abapgitp_xml_input.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_ABAPGITP_XML_INPUT 7 | E 8 | Writes to an XML container 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/zif_abapgitp_xml_output.intf.abap: -------------------------------------------------------------------------------- 1 | INTERFACE zif_abapgitp_xml_output 2 | PUBLIC . 3 | 4 | 5 | * Proxy for lcl_xml_output in ZABAPGIT 6 | METHODS add 7 | IMPORTING 8 | !iv_name TYPE clike 9 | !ig_data TYPE any 10 | RAISING 11 | zcx_abapgitp_object . 12 | METHODS set_raw 13 | IMPORTING 14 | !ii_raw TYPE REF TO if_ixml_element . 15 | METHODS render 16 | IMPORTING 17 | !iv_normalize TYPE sap_bool DEFAULT abap_true 18 | !is_metadata TYPE zif_abapgit_definitions=>ty_metadata 19 | RETURNING 20 | VALUE(rv_xml) TYPE string . 21 | METHODS get_wrapped_xml 22 | RETURNING 23 | VALUE(ro_object) TYPE REF TO object . 24 | ENDINTERFACE. 25 | -------------------------------------------------------------------------------- /src/zif_abapgitp_xml_output.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_ABAPGITP_XML_OUTPUT 7 | E 8 | Writes to an XML container 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | --------------------------------------------------------------------------------