REPORT zabapgit. * See http://www.abapgit.org CONSTANTS: gc_xml_version TYPE string VALUE 'v1.0.0', "#EC NOTEXT gc_abap_version TYPE string VALUE 'v1.0.0'. "#EC NOTEXT ******************************************************************************** * The MIT License (MIT) * * Copyright (c) 2014 Lars Hvam Petersen * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************** TYPE-POOLS seop. TYPES: ty_type TYPE c LENGTH 6, ty_bitbyte TYPE c LENGTH 8, ty_sha1 TYPE c LENGTH 40. TYPES: BEGIN OF ty_file, path TYPE string, filename TYPE string, data TYPE xstring, END OF ty_file. TYPES: ty_files_tt TYPE STANDARD TABLE OF ty_file WITH DEFAULT KEY. TYPES: ty_string_tt TYPE STANDARD TABLE OF string WITH DEFAULT KEY. TYPES: BEGIN OF ty_comment, username TYPE string, email TYPE string, comment TYPE string, END OF ty_comment. TYPES: BEGIN OF ty_item, obj_type TYPE tadir-object, obj_name TYPE tadir-obj_name, END OF ty_item. CONSTANTS: BEGIN OF gc_type, commit TYPE ty_type VALUE 'commit', "#EC NOTEXT tree TYPE ty_type VALUE 'tree', "#EC NOTEXT ref_d TYPE ty_type VALUE 'ref_d', "#EC NOTEXT blob TYPE ty_type VALUE 'blob', "#EC NOTEXT END OF gc_type. CONSTANTS: BEGIN OF gc_chmod, file TYPE c LENGTH 6 VALUE '100644', dir TYPE c LENGTH 5 VALUE '40000', END OF gc_chmod. CONSTANTS: gc_newline TYPE abap_char1 VALUE cl_abap_char_utilities=>newline. CONSTANTS: gc_english TYPE spras VALUE 'E'. DEFINE _raise. RAISE EXCEPTION TYPE lcx_exception EXPORTING iv_text = &1. "#EC NOTEXT END-OF-DEFINITION. ****************** SELECTION-SCREEN BEGIN OF SCREEN 1001. * dummy for triggering screen SELECTION-SCREEN END OF SCREEN 1001. ****************** START-OF-SELECTION. PERFORM run. *----------------------------------------------------------------------* * CLASS LCX_EXCEPTION DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcx_exception DEFINITION INHERITING FROM cx_static_check FINAL. PUBLIC SECTION. DATA mv_text TYPE string. METHODS constructor IMPORTING iv_text TYPE string ix_previous TYPE REF TO cx_root OPTIONAL. PRIVATE SECTION. DATA mx_previous TYPE REF TO cx_root. ENDCLASS. "CX_LOCAL_EXCEPTION DEFINITION *----------------------------------------------------------------------* * CLASS LCX_EXCEPTION IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcx_exception IMPLEMENTATION. METHOD constructor. super->constructor( ). mv_text = iv_text. mx_previous = previous. ENDMETHOD. "CONSTRUCTOR ENDCLASS. "lcx_exception IMPLEMENTATION *----------------------------------------------------------------------* * CLASS LCX_NOT_FOUND DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcx_not_found DEFINITION INHERITING FROM cx_static_check FINAL. ENDCLASS. "CX_LOCAL_EXCEPTION DEFINITION *----------------------------------------------------------------------* * CLASS LCX_NOT_FOUND IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcx_not_found IMPLEMENTATION. ENDCLASS. "lcx_not_found IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_zlib_huffman DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib_huffman DEFINITION FINAL. PUBLIC SECTION. TYPES: ty_lengths TYPE STANDARD TABLE OF i WITH DEFAULT KEY. CONSTANTS: c_maxbits TYPE i VALUE 15. METHODS: constructor IMPORTING it_lengths TYPE ty_lengths, get_count IMPORTING iv_index TYPE i RETURNING VALUE(rv_value) TYPE i, get_symbol IMPORTING iv_index TYPE i RETURNING VALUE(rv_value) TYPE i. PRIVATE SECTION. DATA: mt_count TYPE STANDARD TABLE OF i WITH DEFAULT KEY, mt_symbol TYPE STANDARD TABLE OF i WITH DEFAULT KEY. ENDCLASS. "lcl_zlib_huffman DEFINITION *----------------------------------------------------------------------* * CLASS lcl_zlib_huffman DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib_huffman IMPLEMENTATION. METHOD get_count. READ TABLE mt_count INDEX iv_index INTO rv_value. "#EC CI_SUBRC ENDMETHOD. "count METHOD get_symbol. READ TABLE mt_symbol INDEX iv_index INTO rv_value. "#EC CI_SUBRC ENDMETHOD. "symbol METHOD constructor. DATA: lv_index TYPE i, lt_offset TYPE TABLE OF i, lv_length LIKE LINE OF it_lengths, lv_prev TYPE i, lv_count LIKE LINE OF mt_count. FIELD-SYMBOLS: LIKE LINE OF lt_offset, LIKE LINE OF mt_symbol, LIKE LINE OF it_lengths. DO c_maxbits TIMES. APPEND 0 TO mt_count. ENDDO. LOOP AT it_lengths INTO lv_index. IF lv_index = 0. CONTINUE. ENDIF. READ TABLE mt_count INDEX lv_index ASSIGNING . ASSERT sy-subrc = 0. = + 1. ENDLOOP. ************ APPEND 0 TO lt_offset. DO c_maxbits - 1 TIMES. READ TABLE mt_count INDEX sy-index INTO lv_count. ASSERT sy-subrc = 0. lv_prev = lv_prev + lv_count. APPEND lv_prev TO lt_offset. ENDDO. DO lines( it_lengths ) TIMES. APPEND 0 TO mt_symbol. ENDDO. DO lines( it_lengths ) TIMES. lv_index = sy-index. READ TABLE it_lengths INDEX lv_index INTO lv_length. ASSERT sy-subrc = 0. IF lv_length = 0. CONTINUE. ENDIF. READ TABLE lt_offset INDEX lv_length ASSIGNING . ASSERT sy-subrc = 0. READ TABLE mt_symbol INDEX + 1 ASSIGNING . ASSERT sy-subrc = 0. = lv_index - 1. = + 1. ENDDO. ENDMETHOD. "constructor ENDCLASS. "lcl_zlib_huffman DEFINITION *----------------------------------------------------------------------* * CLASS lcl_zlib_convert DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib_convert DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS: hex_to_bits IMPORTING iv_hex TYPE xsequence RETURNING VALUE(rv_bits) TYPE string, bits_to_int IMPORTING iv_bits TYPE clike RETURNING VALUE(rv_int) TYPE i, int_to_hex IMPORTING iv_int TYPE i RETURNING VALUE(rv_hex) TYPE xstring. ENDCLASS. "lcl_zlib_convert DEFINITION *----------------------------------------------------------------------* * CLASS lcl_zlib_convert IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib_convert IMPLEMENTATION. METHOD hex_to_bits. DATA: lv_x TYPE x LENGTH 1, lv_c TYPE c LENGTH 1, lv_bit TYPE i, lv_hex TYPE xstring. lv_hex = iv_hex. WHILE NOT lv_hex IS INITIAL. lv_x = lv_hex. DO 8 TIMES. lv_bit = sy-index. GET BIT lv_bit OF lv_x INTO lv_c. CONCATENATE rv_bits lv_c INTO rv_bits. ENDDO. lv_hex = lv_hex+1. ENDWHILE. ENDMETHOD. "hex_to_bits METHOD bits_to_int. DATA: lv_c TYPE c LENGTH 1, lv_bits TYPE string. lv_bits = iv_bits. WHILE NOT lv_bits IS INITIAL. lv_c = lv_bits. rv_int = rv_int * 2. rv_int = rv_int + lv_c. lv_bits = lv_bits+1. ENDWHILE. ENDMETHOD. "bits_to_int METHOD int_to_hex. DATA: lv_x TYPE x. lv_x = iv_int. rv_hex = lv_x. ENDMETHOD. "int_to_hex ENDCLASS. "lcl_zlib_convert IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_zlib_stream DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib_stream DEFINITION FINAL. PUBLIC SECTION. METHODS: constructor IMPORTING iv_data TYPE xstring, take_bits IMPORTING iv_length TYPE i RETURNING VALUE(rv_bits) TYPE string, take_int IMPORTING iv_length TYPE i RETURNING VALUE(rv_int) TYPE i, remaining RETURNING VALUE(rv_length) TYPE i. PRIVATE SECTION. DATA: mv_compressed TYPE xstring, mv_bits TYPE string. ENDCLASS. "lcl_zlib_stream DEFINITION *----------------------------------------------------------------------* * CLASS lcl_zlib_stream IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib_stream IMPLEMENTATION. METHOD constructor. mv_compressed = iv_data. ENDMETHOD. "constructor METHOD remaining. rv_length = xstrlen( mv_compressed ) + 1. ENDMETHOD. "remaining METHOD take_int. rv_int = lcl_zlib_convert=>bits_to_int( take_bits( iv_length ) ). ENDMETHOD. "take_int METHOD take_bits. DATA: lv_left TYPE i, lv_index TYPE i, lv_x TYPE x LENGTH 1. WHILE strlen( rv_bits ) < iv_length. IF mv_bits IS INITIAL. lv_x = mv_compressed(1). mv_bits = lcl_zlib_convert=>hex_to_bits( lv_x ). mv_compressed = mv_compressed+1. ENDIF. lv_left = iv_length - strlen( rv_bits ). IF lv_left >= strlen( mv_bits ). CONCATENATE mv_bits rv_bits INTO rv_bits. CLEAR mv_bits. ELSE. lv_index = strlen( mv_bits ) - lv_left. CONCATENATE mv_bits+lv_index(lv_left) rv_bits INTO rv_bits. mv_bits = mv_bits(lv_index). ENDIF. ENDWHILE. ENDMETHOD. "take_bits ENDCLASS. "lcl_zlib_stream IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_zlib DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib DEFINITION FINAL. PUBLIC SECTION. TYPES: BEGIN OF ty_decompress, raw TYPE xstring, compressed_len TYPE i, END OF ty_decompress. CLASS-METHODS: decompress IMPORTING iv_compressed TYPE xsequence RETURNING VALUE(rs_data) TYPE ty_decompress. PRIVATE SECTION. CONSTANTS: c_maxdcodes TYPE i VALUE 30. CLASS-DATA: gv_out TYPE xstring, go_lencode TYPE REF TO lcl_zlib_huffman, go_distcode TYPE REF TO lcl_zlib_huffman, go_stream TYPE REF TO lcl_zlib_stream. TYPES: BEGIN OF ty_pair, length TYPE i, distance TYPE i, END OF ty_pair. CLASS-METHODS: decode IMPORTING io_huffman TYPE REF TO lcl_zlib_huffman RETURNING VALUE(rv_symbol) TYPE i, map_length IMPORTING iv_code TYPE i RETURNING VALUE(rv_length) TYPE i, map_distance IMPORTING iv_code TYPE i RETURNING VALUE(rv_distance) TYPE i, dynamic, fixed, read_pair IMPORTING iv_length TYPE i RETURNING VALUE(rs_pair) TYPE ty_pair, copy_out IMPORTING is_pair TYPE ty_pair. ENDCLASS. "lcl_zlib DEFINITION *----------------------------------------------------------------------* * CLASS lcl_zlib IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zlib IMPLEMENTATION. METHOD decode. DATA: lv_bit TYPE c LENGTH 1, lv_len TYPE i, lv_count TYPE i, lv_code TYPE i, lv_index TYPE i, lv_first TYPE i, lv_bits TYPE string. DO lcl_zlib_huffman=>c_maxbits TIMES. lv_len = sy-index. lv_bit = go_stream->take_bits( 1 ). CONCATENATE lv_bits lv_bit INTO lv_bits. lv_code = lcl_zlib_convert=>bits_to_int( lv_bits ). lv_count = io_huffman->get_count( lv_len ). IF lv_code - lv_count < lv_first. rv_symbol = io_huffman->get_symbol( lv_index + lv_code - lv_first + 1 ). RETURN. ENDIF. lv_index = lv_index + lv_count. lv_first = lv_first + lv_count. lv_first = lv_first * 2. ENDDO. ENDMETHOD. "decode METHOD fixed. DATA: lt_lengths TYPE lcl_zlib_huffman=>ty_lengths. DO 144 TIMES. APPEND 8 TO lt_lengths. ENDDO. DO 112 TIMES. APPEND 9 TO lt_lengths. ENDDO. DO 24 TIMES. APPEND 7 TO lt_lengths. ENDDO. DO 8 TIMES. APPEND 8 TO lt_lengths. ENDDO. CREATE OBJECT go_lencode EXPORTING it_lengths = lt_lengths. CLEAR lt_lengths. DO c_maxdcodes TIMES. APPEND 5 TO lt_lengths. ENDDO. CREATE OBJECT go_distcode EXPORTING it_lengths = lt_lengths. ENDMETHOD. "fixed METHOD copy_out. * copy one byte at a time, it is not possible to copy using * string offsets, as it might copy data that does not exist * in mv_out yet DATA: lv_distance TYPE i, lv_index TYPE i, lv_x TYPE x LENGTH 1. lv_distance = xstrlen( gv_out ) - is_pair-distance. DO is_pair-length TIMES. lv_index = sy-index - 1 + lv_distance. lv_x = gv_out+lv_index(1). CONCATENATE gv_out lv_x INTO gv_out IN BYTE MODE. ENDDO. ENDMETHOD. "copy_out METHOD dynamic. DATA: lv_nlen TYPE i, lv_ndist TYPE i, lv_ncode TYPE i, lv_index TYPE i, lv_length TYPE i, lv_symbol TYPE i, lt_order TYPE TABLE OF i, lt_lengths TYPE lcl_zlib_huffman=>ty_lengths, lt_dists TYPE lcl_zlib_huffman=>ty_lengths. FIELD-SYMBOLS: LIKE LINE OF lt_lengths. APPEND 16 TO lt_order. APPEND 17 TO lt_order. APPEND 18 TO lt_order. APPEND 0 TO lt_order. APPEND 8 TO lt_order. APPEND 7 TO lt_order. APPEND 9 TO lt_order. APPEND 6 TO lt_order. APPEND 10 TO lt_order. APPEND 5 TO lt_order. APPEND 11 TO lt_order. APPEND 4 TO lt_order. APPEND 12 TO lt_order. APPEND 3 TO lt_order. APPEND 13 TO lt_order. APPEND 2 TO lt_order. APPEND 14 TO lt_order. APPEND 1 TO lt_order. APPEND 15 TO lt_order. lv_nlen = go_stream->take_int( 5 ) + 257. lv_ndist = go_stream->take_int( 5 ) + 1. lv_ncode = go_stream->take_int( 4 ) + 4. DO 19 TIMES. APPEND 0 TO lt_lengths. ENDDO. DO lv_ncode TIMES. READ TABLE lt_order INDEX sy-index INTO lv_index. ASSERT sy-subrc = 0. lv_index = lv_index + 1. READ TABLE lt_lengths INDEX lv_index ASSIGNING . ASSERT sy-subrc = 0. = go_stream->take_int( 3 ). ENDDO. CREATE OBJECT go_lencode EXPORTING it_lengths = lt_lengths. CLEAR lt_lengths. WHILE lines( lt_lengths ) < lv_nlen + lv_ndist. lv_symbol = decode( go_lencode ). IF lv_symbol < 16. APPEND lv_symbol TO lt_lengths. ELSE. lv_length = 0. IF lv_symbol = 16. READ TABLE lt_lengths INDEX lines( lt_lengths ) INTO lv_length. ASSERT sy-subrc = 0. lv_symbol = go_stream->take_int( 2 ) + 3. ELSEIF lv_symbol = 17. lv_symbol = go_stream->take_int( 3 ) + 3. ELSE. lv_symbol = go_stream->take_int( 7 ) + 11. ENDIF. DO lv_symbol TIMES. APPEND lv_length TO lt_lengths. ENDDO. ENDIF. ENDWHILE. lt_dists = lt_lengths. DELETE lt_lengths FROM lv_nlen + 1. DELETE lt_dists TO lv_nlen. CREATE OBJECT go_lencode EXPORTING it_lengths = lt_lengths. CREATE OBJECT go_distcode EXPORTING it_lengths = lt_dists. ENDMETHOD. "dynamic METHOD read_pair. DATA: lv_symbol TYPE i. rs_pair-length = map_length( iv_length ). lv_symbol = decode( go_distcode ). rs_pair-distance = map_distance( lv_symbol ). ENDMETHOD. "read_pair METHOD map_distance. DEFINE _distance. rv_distance = go_stream->take_int( &1 ). rv_distance = rv_distance + &2. END-OF-DEFINITION. CASE iv_code. WHEN 0. _distance 0 1. WHEN 1. _distance 0 2. WHEN 2. _distance 0 3. WHEN 3. _distance 0 4. WHEN 4. _distance 1 5. WHEN 5. _distance 1 7. WHEN 6. _distance 2 9. WHEN 7. _distance 2 13. WHEN 8. _distance 3 17. WHEN 9. _distance 3 25. WHEN 10. _distance 4 33. WHEN 11. _distance 4 49. WHEN 12. _distance 5 65. WHEN 13. _distance 5 97. WHEN 14. _distance 6 129. WHEN 15. _distance 6 193. WHEN 16. _distance 7 257. WHEN 17. _distance 7 385. WHEN 18. _distance 8 513. WHEN 19. _distance 8 769. WHEN 20. _distance 9 1025. WHEN 21. _distance 9 1537. WHEN 22. _distance 10 2049. WHEN 23. _distance 10 3073. WHEN 24. _distance 11 4097. WHEN 25. _distance 11 6145. WHEN 26. _distance 12 8193. WHEN 27. _distance 12 12289. WHEN 28. _distance 13 16385. WHEN 29. _distance 13 24577. WHEN OTHERS. ASSERT 1 = 0. ENDCASE. ENDMETHOD. "map_distance METHOD map_length. DEFINE _length. rv_length = go_stream->take_int( &1 ). rv_length = rv_length + &2. END-OF-DEFINITION. CASE iv_code. WHEN 257. _length 0 3. WHEN 258. _length 0 4. WHEN 259. _length 0 5. WHEN 260. _length 0 6. WHEN 261. _length 0 7. WHEN 262. _length 0 8. WHEN 263. _length 0 9. WHEN 264. _length 0 10. WHEN 265. _length 1 11. WHEN 266. _length 1 13. WHEN 267. _length 1 15. WHEN 268. _length 1 17. WHEN 269. _length 2 19. WHEN 270. _length 2 23. WHEN 271. _length 2 27. WHEN 272. _length 2 31. WHEN 273. _length 3 35. WHEN 274. _length 3 43. WHEN 275. _length 3 51. WHEN 276. _length 3 59. WHEN 277. _length 4 67. WHEN 278. _length 4 83. WHEN 279. _length 4 99. WHEN 280. _length 4 115. WHEN 281. _length 5 131. WHEN 282. _length 5 163. WHEN 283. _length 5 195. WHEN 284. _length 5 227. WHEN 285. _length 0 258. WHEN OTHERS. ASSERT 1 = 0. ENDCASE. ENDMETHOD. "map_length METHOD decompress. DATA: lv_x TYPE x LENGTH 1, lv_symbol TYPE i, lv_bfinal TYPE c LENGTH 1, lv_btype TYPE c LENGTH 2. IF iv_compressed IS INITIAL. RETURN. ENDIF. CLEAR gv_out. CREATE OBJECT go_stream EXPORTING iv_data = iv_compressed. DO. lv_bfinal = go_stream->take_bits( 1 ). lv_btype = go_stream->take_bits( 2 ). CASE lv_btype. WHEN '01'. fixed( ). WHEN '10'. dynamic( ). WHEN OTHERS. ASSERT 1 = 0. ENDCASE. DO. lv_symbol = decode( go_lencode ). IF lv_symbol < 256. lv_x = lcl_zlib_convert=>int_to_hex( lv_symbol ). CONCATENATE gv_out lv_x INTO gv_out IN BYTE MODE. ELSEIF lv_symbol = 256. EXIT. ELSE. copy_out( read_pair( lv_symbol ) ). ENDIF. ENDDO. IF lv_bfinal = '1'. EXIT. ENDIF. ENDDO. rs_data-raw = gv_out. rs_data-compressed_len = xstrlen( iv_compressed ) - go_stream->remaining( ). ENDMETHOD. "decompress ENDCLASS. "lcl_zlib IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_tadir DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_tadir DEFINITION FINAL. PUBLIC SECTION. TYPES: BEGIN OF ty_tadir, pgmid TYPE tadir-pgmid, object TYPE tadir-object, obj_name TYPE tadir-obj_name, devclass TYPE tadir-devclass, korrnum TYPE tadir-korrnum, path TYPE string, END OF ty_tadir. TYPES: ty_tadir_tt TYPE STANDARD TABLE OF ty_tadir WITH DEFAULT KEY. CLASS-METHODS: read IMPORTING iv_package TYPE tadir-devclass RETURNING VALUE(rt_tadir) TYPE ty_tadir_tt RAISING lcx_exception, read_single IMPORTING iv_pgmid TYPE tadir-pgmid DEFAULT 'R3TR' iv_object TYPE tadir-object iv_obj_name TYPE tadir-obj_name RETURNING VALUE(rs_tadir) TYPE tadir. PRIVATE SECTION. CLASS-METHODS: check_exists IMPORTING it_tadir TYPE ty_tadir_tt RETURNING VALUE(rt_tadir) TYPE ty_tadir_tt RAISING lcx_exception, build IMPORTING iv_package TYPE tadir-devclass iv_parent TYPE tadir-devclass iv_path TYPE string RETURNING VALUE(rt_tadir) TYPE ty_tadir_tt RAISING lcx_exception. ENDCLASS. "lcl_tadir DEFINITION *----------------------------------------------------------------------* * CLASS lcl_user DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_user DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS set_username IMPORTING iv_username TYPE string RAISING lcx_exception. CLASS-METHODS get_username RETURNING VALUE(rv_username) TYPE string RAISING lcx_exception. CLASS-METHODS set_email IMPORTING iv_email TYPE string RAISING lcx_exception. CLASS-METHODS get_email RETURNING VALUE(rv_email) TYPE string RAISING lcx_exception. PRIVATE SECTION. CLASS-METHODS read IMPORTING iv_name TYPE tdobname RETURNING VALUE(rv_value) TYPE string RAISING lcx_exception. CLASS-METHODS save IMPORTING iv_name TYPE tdobname iv_value TYPE string RAISING lcx_exception. ENDCLASS. "lcl_user DEFINITION *----------------------------------------------------------------------* * CLASS lcl_user IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_user IMPLEMENTATION. METHOD read. DATA: lt_lines TYPE TABLE OF tline, ls_line LIKE LINE OF lt_lines. CALL FUNCTION 'READ_TEXT' EXPORTING id = 'ST' language = gc_english name = iv_name object = 'TEXT' TABLES lines = lt_lines EXCEPTIONS id = 1 language = 2 name = 3 not_found = 4 object = 5 reference_check = 6 wrong_access_to_archive = 7 OTHERS = 8. IF sy-subrc <> 4 AND sy-subrc <> 0. _raise 'error from READ_TEXT'. ENDIF. READ TABLE lt_lines INTO ls_line INDEX 1. IF sy-subrc = 0. rv_value = ls_line-tdline. ENDIF. ENDMETHOD. "get_details METHOD save. DATA: ls_header TYPE thead, lt_lines TYPE TABLE OF tline, ls_line LIKE LINE OF lt_lines. ls_line-tdformat = '*'. ls_line-tdline = iv_value. APPEND ls_line TO lt_lines. ls_header-tdid = 'ST'. ls_header-tdspras = gc_english. ls_header-tdname = iv_name. ls_header-tdobject = 'TEXT'. CALL FUNCTION 'SAVE_TEXT' EXPORTING header = ls_header TABLES lines = lt_lines EXCEPTIONS id = 1 language = 2 name = 3 object = 4 OTHERS = 5. IF sy-subrc <> 0. ROLLBACK WORK. _raise 'error from SAVE_TEXT'. ENDIF. COMMIT WORK. ENDMETHOD. "change METHOD set_username. DATA: lv_name TYPE tdobname. CONCATENATE 'ZABAPGIT_USERNAME_' sy-uname INTO lv_name. save( iv_name = lv_name iv_value = iv_username ). ENDMETHOD. "set_username METHOD get_username. DATA: lv_name TYPE tdobname. CONCATENATE 'ZABAPGIT_USERNAME_' sy-uname INTO lv_name. rv_username = read( lv_name ). ENDMETHOD. "get_username METHOD set_email. DATA: lv_name TYPE tdobname. CONCATENATE 'ZABAPGIT_EMAIL_' sy-uname INTO lv_name. save( iv_name = lv_name iv_value = iv_email ). ENDMETHOD. "set_email METHOD get_email. DATA: lv_name TYPE tdobname. CONCATENATE 'ZABAPGIT_EMAIL_' sy-uname INTO lv_name. rv_email = read( lv_name ). ENDMETHOD. "get_email ENDCLASS. "lcl_user IMPLEMENTATION CLASS lcl_xml DEFINITION ABSTRACT. PUBLIC SECTION. METHODS: constructor. PROTECTED SECTION. DATA: mi_ixml TYPE REF TO if_ixml, mi_xml_doc TYPE REF TO if_ixml_document. CONSTANTS: c_abapgit_tag TYPE string VALUE 'abapGit'. METHODS to_xml IMPORTING iv_normalize TYPE sap_bool DEFAULT abap_true RETURNING VALUE(rv_xml) TYPE string. METHODS parse IMPORTING iv_normalize TYPE abap_bool DEFAULT abap_true iv_xml TYPE string RAISING lcx_exception. PRIVATE SECTION. METHODS error IMPORTING ii_parser TYPE REF TO if_ixml_parser RAISING lcx_exception. METHODS display_xml_error RAISING lcx_exception. ENDCLASS. CLASS lcl_xml IMPLEMENTATION. METHOD constructor. mi_ixml = cl_ixml=>create( ). mi_xml_doc = mi_ixml->create_document( ). ENDMETHOD. METHOD parse. DATA: li_stream_factory TYPE REF TO if_ixml_stream_factory, li_istream TYPE REF TO if_ixml_istream, li_element TYPE REF TO if_ixml_element, li_version TYPE REF TO if_ixml_node, li_parser TYPE REF TO if_ixml_parser. ASSERT NOT iv_xml IS INITIAL. li_stream_factory = mi_ixml->create_stream_factory( ). li_istream = li_stream_factory->create_istream_string( iv_xml ). li_parser = mi_ixml->create_parser( stream_factory = li_stream_factory istream = li_istream document = mi_xml_doc ). li_parser->set_normalizing( iv_normalize ). IF li_parser->parse( ) <> 0. error( li_parser ). ENDIF. li_istream->close( ). li_element = mi_xml_doc->find_from_name( depth = 0 name = c_abapgit_tag ). li_version = li_element->if_ixml_node~get_attributes( )->get_named_item_ns( 'version' ) ##NO_TEXT. IF li_version->get_value( ) <> gc_xml_version. display_xml_error( ). ENDIF. ENDMETHOD. METHOD display_xml_error. DATA: lv_version TYPE string. lv_version = |abapGit version: { gc_abap_version }|. CALL FUNCTION 'POPUP_TO_INFORM' EXPORTING titel = 'abapGit XML version mismatch' txt1 = 'abapGit XML version mismatch' txt2 = 'See https://github.com/larshp/abapGit/wiki/XML-Mismatch' txt3 = lv_version. "#EC NOTEXT _raise 'XML error'. ENDMETHOD. METHOD to_xml. * will render to codepage UTF-16 DATA: li_ostream TYPE REF TO if_ixml_ostream, li_renderer TYPE REF TO if_ixml_renderer, li_streamfactory TYPE REF TO if_ixml_stream_factory. li_streamfactory = mi_ixml->create_stream_factory( ). li_ostream = li_streamfactory->create_ostream_cstring( rv_xml ). li_renderer = mi_ixml->create_renderer( ostream = li_ostream document = mi_xml_doc ). li_renderer->set_normalizing( iv_normalize ). li_renderer->render( ). ENDMETHOD. METHOD error. DATA: lv_error TYPE i, lv_txt1 TYPE string, lv_txt2 TYPE string, lv_txt3 TYPE string, lv_times TYPE i, li_error TYPE REF TO if_ixml_parse_error. IF ii_parser->num_errors( ) <> 0. lv_times = ii_parser->num_errors( ). DO lv_times TIMES. lv_error = sy-index - 1. li_error = ii_parser->get_error( lv_error ). lv_txt1 = li_error->get_column( ). CONCATENATE 'Column:' lv_txt1 INTO lv_txt1. "#EC NOTEXT lv_txt2 = li_error->get_line( ). CONCATENATE 'Line:' lv_txt2 INTO lv_txt2. "#EC NOTEXT lv_txt3 = li_error->get_reason( ). CALL FUNCTION 'POPUP_TO_INFORM' EXPORTING titel = 'Error from XML parser' "#EC NOTEXT txt1 = lv_txt1 txt2 = lv_txt2 txt3 = lv_txt3. ENDDO. ENDIF. _raise 'Error while parsing XML'. ENDMETHOD. ENDCLASS. CLASS lcl_xml_output DEFINITION FINAL INHERITING FROM lcl_xml CREATE PUBLIC. PUBLIC SECTION. METHODS: add IMPORTING iv_name TYPE clike ig_data TYPE any RAISING lcx_exception, set_raw IMPORTING ii_raw TYPE REF TO if_ixml_element, render IMPORTING iv_normalize TYPE sap_bool DEFAULT abap_true RETURNING VALUE(rv_xml) TYPE string. PRIVATE SECTION. DATA: mi_raw TYPE REF TO if_ixml_element, mt_stab TYPE abap_trans_srcbind_tab. ENDCLASS. CLASS lcl_xml_output IMPLEMENTATION. METHOD set_raw. mi_raw = ii_raw. ENDMETHOD. METHOD add. FIELD-SYMBOLS: LIKE LINE OF mt_stab. ASSERT NOT iv_name IS INITIAL. READ TABLE mt_stab WITH KEY name = iv_name TRANSPORTING NO FIELDS. IF sy-subrc = 0. _raise 'XML mt_stab name already exists'. ENDIF. APPEND INITIAL LINE TO mt_stab ASSIGNING . -name = iv_name. GET REFERENCE OF ig_data INTO -value. ENDMETHOD. METHOD render. DATA: li_git TYPE REF TO if_ixml_element, li_abap TYPE REF TO if_ixml_element. IF mi_raw IS INITIAL. CALL TRANSFORMATION id SOURCE (mt_stab) RESULT XML mi_xml_doc. li_abap ?= mi_xml_doc->get_root( )->get_first_child( ). mi_xml_doc->get_root( )->remove_child( li_abap ). ELSE. li_abap = mi_raw. ENDIF. li_git = mi_xml_doc->create_element( c_abapgit_tag ). li_git->set_attribute( name = 'version' value = gc_xml_version ). "#EC NOTEXT li_git->append_child( li_abap ). mi_xml_doc->get_root( )->append_child( li_git ). rv_xml = to_xml( iv_normalize ). ENDMETHOD. ENDCLASS. CLASS lcl_xml_input DEFINITION FINAL INHERITING FROM lcl_xml CREATE PUBLIC. PUBLIC SECTION. METHODS: constructor IMPORTING iv_xml TYPE clike RAISING lcx_exception, read IMPORTING iv_name TYPE clike CHANGING cg_data TYPE any RAISING lcx_exception, get_raw RETURNING VALUE(ri_raw) TYPE REF TO if_ixml_node. PRIVATE SECTION. METHODS: fix_xml. ENDCLASS. CLASS lcl_xml_input IMPLEMENTATION. METHOD constructor. super->constructor( ). parse( iv_xml ). fix_xml( ). ENDMETHOD. METHOD get_raw. ri_raw = mi_xml_doc->get_root_element( ). ENDMETHOD. METHOD fix_xml. DATA: li_git TYPE REF TO if_ixml_element, li_abap TYPE REF TO if_ixml_node. li_git ?= mi_xml_doc->get_root( )->get_first_child( ). li_abap = li_git->get_first_child( ). mi_xml_doc->get_root( )->remove_child( li_git ). mi_xml_doc->get_root( )->append_child( li_abap ). ENDMETHOD. METHOD read. DATA: lv_text TYPE string, lx_error TYPE REF TO cx_transformation_error, lt_rtab TYPE abap_trans_resbind_tab. FIELD-SYMBOLS: LIKE LINE OF lt_rtab. ASSERT NOT iv_name IS INITIAL. APPEND INITIAL LINE TO lt_rtab ASSIGNING . -name = iv_name. GET REFERENCE OF cg_data INTO -value. TRY. CALL TRANSFORMATION id OPTIONS value_handling = 'accept_data_loss' SOURCE XML mi_xml_doc RESULT (lt_rtab) ##NO_TEXT. CATCH cx_transformation_error INTO lx_error. lv_text = lx_error->if_message~get_text( ). _raise lv_text. ENDTRY. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_time DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_time DEFINITION FINAL. PUBLIC SECTION. TYPES: ty_unixtime TYPE c LENGTH 16. CLASS-METHODS get RETURNING VALUE(rv_time) TYPE ty_unixtime RAISING lcx_exception. PRIVATE SECTION. CONSTANTS: c_epoch TYPE datum VALUE '19700101'. ENDCLASS. "lcl_time DEFINITION *----------------------------------------------------------------------* * CLASS lcl_time IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_time IMPLEMENTATION. METHOD get. DATA: lv_i TYPE i, lv_tz TYPE tznzone, lv_utcdiff TYPE tznutcdiff, lv_utcsign TYPE tznutcsign. lv_i = sy-datum - c_epoch. lv_i = lv_i * 86400. lv_i = lv_i + sy-uzeit. CALL FUNCTION 'TZON_GET_OS_TIMEZONE' IMPORTING ef_timezone = lv_tz. CALL FUNCTION 'TZON_GET_OFFSET' EXPORTING if_timezone = lv_tz if_local_date = sy-datum if_local_time = sy-uzeit IMPORTING ef_utcdiff = lv_utcdiff ef_utcsign = lv_utcsign EXCEPTIONS conversion_error = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Timezone error'. ENDIF. CASE lv_utcsign. WHEN '+'. lv_i = lv_i - lv_utcdiff. WHEN '-'. lv_i = lv_i + lv_utcdiff. ENDCASE. rv_time = lv_i. CONDENSE rv_time. rv_time+11 = lv_utcsign. rv_time+12 = lv_utcdiff. ENDMETHOD. "get ENDCLASS. "lcl_time IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_repo DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_url DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS host IMPORTING iv_repo TYPE string RETURNING VALUE(rv_host) TYPE string RAISING lcx_exception. CLASS-METHODS name IMPORTING iv_repo TYPE string RETURNING VALUE(rv_name) TYPE string RAISING lcx_exception. CLASS-METHODS path_name IMPORTING iv_repo TYPE string RETURNING VALUE(rv_path_name) TYPE string RAISING lcx_exception. PRIVATE SECTION. CLASS-METHODS regex IMPORTING iv_repo TYPE string EXPORTING ev_host TYPE string ev_path TYPE string ev_name TYPE string RAISING lcx_exception. ENDCLASS. "lcl_repo DEFINITION *----------------------------------------------------------------------* * CLASS lcl_repo IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_url IMPLEMENTATION. METHOD host. regex( EXPORTING iv_repo = iv_repo IMPORTING ev_host = rv_host ). ENDMETHOD. "host METHOD name. regex( EXPORTING iv_repo = iv_repo IMPORTING ev_name = rv_name ). ENDMETHOD. "short_name METHOD path_name. DATA: lv_path TYPE string, lv_name TYPE string. regex( EXPORTING iv_repo = iv_repo IMPORTING ev_path = lv_path ev_name = lv_name ). CONCATENATE lv_path lv_name INTO rv_path_name. ENDMETHOD. "path_name METHOD regex. FIND REGEX '(.*://[^/]*)(.*/)(.*).git' IN iv_repo SUBMATCHES ev_host ev_path ev_name. IF sy-subrc <> 0. _raise 'Malformed URL'. ENDIF. ENDMETHOD. "url ENDCLASS. "lcl_repo IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_convert DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_convert DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS bitbyte_to_int IMPORTING iv_bits TYPE clike RETURNING VALUE(rv_int) TYPE i. CLASS-METHODS x_to_bitbyte IMPORTING iv_x TYPE x RETURNING VALUE(rv_bitbyte) TYPE ty_bitbyte. CLASS-METHODS string_to_xstring_utf8 IMPORTING iv_string TYPE string RETURNING VALUE(rv_xstring) TYPE xstring. CLASS-METHODS xstring_to_string_utf8 IMPORTING iv_data TYPE xstring RETURNING VALUE(rv_string) TYPE string. CLASS-METHODS xstring_to_int IMPORTING iv_xstring TYPE xstring RETURNING VALUE(rv_i) TYPE i RAISING lcx_exception. CLASS-METHODS int_to_xstring IMPORTING iv_i TYPE i iv_length TYPE i RETURNING VALUE(rv_xstring) TYPE xstring. ENDCLASS. "lcl_convert DEFINITION *----------------------------------------------------------------------* * CLASS lcl_convert IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_convert IMPLEMENTATION. METHOD int_to_xstring. DATA: lv_x TYPE x LENGTH 4. ASSERT iv_length = 4. " other cases not implemented lv_x = iv_i. rv_xstring = lv_x. ENDMETHOD. "int_to_xstring METHOD xstring_to_int. DATA: lv_xstring TYPE xstring, lv_x TYPE x. lv_xstring = iv_xstring. WHILE xstrlen( lv_xstring ) > 0. lv_x = lv_xstring(1). rv_i = rv_i * 256 + lv_x. lv_xstring = lv_xstring+1. ENDWHILE. ENDMETHOD. "xstring_to_int METHOD xstring_to_string_utf8. DATA: lv_len TYPE i, lo_obj TYPE REF TO cl_abap_conv_in_ce. TRY. lo_obj = cl_abap_conv_in_ce=>create( input = iv_data encoding = 'UTF-8' ). lv_len = xstrlen( iv_data ). lo_obj->read( EXPORTING n = lv_len IMPORTING data = rv_string ). CATCH cx_parameter_invalid_range cx_sy_codepage_converter_init cx_sy_conversion_codepage cx_parameter_invalid_type. "#EC NO_HANDLER ENDTRY. ENDMETHOD. "xstring_to_string_utf8 METHOD string_to_xstring_utf8. DATA: lo_obj TYPE REF TO cl_abap_conv_out_ce. TRY. lo_obj = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ). lo_obj->convert( EXPORTING data = iv_string IMPORTING buffer = rv_xstring ). CATCH cx_parameter_invalid_range cx_sy_codepage_converter_init cx_sy_conversion_codepage cx_parameter_invalid_type. "#EC NO_HANDLER ENDTRY. ENDMETHOD. "string_to_xstring_utf8 METHOD bitbyte_to_int. DATA: lv_bits TYPE string. lv_bits = iv_bits. rv_int = 0. WHILE strlen( lv_bits ) > 0. rv_int = rv_int * 2. IF lv_bits(1) = '1'. rv_int = rv_int + 1. ENDIF. lv_bits = lv_bits+1. ENDWHILE. ENDMETHOD. "bitbyte_to_int METHOD x_to_bitbyte. DATA: lv_b TYPE n. CLEAR rv_bitbyte. DO 8 TIMES. GET BIT sy-index OF iv_x INTO lv_b. CONCATENATE rv_bitbyte lv_b INTO rv_bitbyte. ENDDO. ENDMETHOD. "x_to_bitbyte ENDCLASS. "lcl_convert IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_diff DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_diff DEFINITION FINAL. PUBLIC SECTION. CONSTANTS: BEGIN OF c_diff, insert TYPE c LENGTH 1 VALUE 'I', delete TYPE c LENGTH 1 VALUE 'D', update TYPE c LENGTH 1 VALUE 'U', END OF c_diff. TYPES: BEGIN OF ty_diff, local TYPE string, result TYPE c LENGTH 1, remote TYPE string, END OF ty_diff. TYPES: ty_diffs_tt TYPE STANDARD TABLE OF ty_diff WITH DEFAULT KEY. TYPES: BEGIN OF ty_count, insert TYPE i, delete TYPE i, update TYPE i, END OF ty_count. * assumes data is UTF8 based with newlines * only works with lines up to 255 characters METHODS constructor IMPORTING iv_local TYPE xstring iv_remote TYPE xstring. METHODS get RETURNING VALUE(rt_diff) TYPE ty_diffs_tt. METHODS stats RETURNING VALUE(rs_count) TYPE ty_count. PRIVATE SECTION. DATA mt_diff TYPE ty_diffs_tt. CLASS-METHODS: unpack IMPORTING iv_local TYPE xstring iv_remote TYPE xstring EXPORTING et_local TYPE abaptxt255_tab et_remote TYPE abaptxt255_tab. CLASS-METHODS: render IMPORTING it_local TYPE abaptxt255_tab it_remote TYPE abaptxt255_tab it_delta TYPE vxabapt255_tab RETURNING VALUE(rt_diff) TYPE ty_diffs_tt. CLASS-METHODS: compute IMPORTING it_local TYPE abaptxt255_tab it_remote TYPE abaptxt255_tab RETURNING VALUE(rt_delta) TYPE vxabapt255_tab. ENDCLASS. "lcl_diff DEFINITION *----------------------------------------------------------------------* * CLASS lcl_diff IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_diff IMPLEMENTATION. METHOD get. rt_diff = mt_diff. ENDMETHOD. "get METHOD stats. FIELD-SYMBOLS: LIKE LINE OF mt_diff. LOOP AT mt_diff ASSIGNING . CASE -result. WHEN lcl_diff=>c_diff-insert. rs_count-insert = rs_count-insert + 1. WHEN lcl_diff=>c_diff-delete. rs_count-delete = rs_count-delete + 1. WHEN lcl_diff=>c_diff-update. rs_count-update = rs_count-update + 1. ENDCASE. ENDLOOP. ENDMETHOD. "count METHOD unpack. DATA: lv_local TYPE string, lv_remote TYPE string. lv_local = lcl_convert=>xstring_to_string_utf8( iv_local ). lv_remote = lcl_convert=>xstring_to_string_utf8( iv_remote ). SPLIT lv_local AT gc_newline INTO TABLE et_local. SPLIT lv_remote AT gc_newline INTO TABLE et_remote. ENDMETHOD. "unpack METHOD compute. DATA: lt_trdirtab_old TYPE TABLE OF trdir, lt_trdirtab_new TYPE TABLE OF trdir, lt_trdir_delta TYPE TABLE OF xtrdir. CALL FUNCTION 'SVRS_COMPUTE_DELTA_REPS' TABLES texttab_old = it_remote texttab_new = it_local trdirtab_old = lt_trdirtab_old trdirtab_new = lt_trdirtab_new trdir_delta = lt_trdir_delta text_delta = rt_delta. ENDMETHOD. "compute METHOD constructor. DATA: lt_delta TYPE vxabapt255_tab, lt_local TYPE abaptxt255_tab, lt_remote TYPE abaptxt255_tab. unpack( EXPORTING iv_local = iv_local iv_remote = iv_remote IMPORTING et_local = lt_local et_remote = lt_remote ). lt_delta = compute( it_local = lt_local it_remote = lt_remote ). mt_diff = render( it_local = lt_local it_remote = lt_remote it_delta = lt_delta ). ENDMETHOD. "diff METHOD render. DEFINE _append. CLEAR ls_diff. ls_diff-local = &1. ls_diff-result = &2. ls_diff-remote = &3. APPEND ls_diff TO rt_diff. END-OF-DEFINITION. DATA: lv_rindex TYPE i VALUE 1, lv_lindex TYPE i VALUE 1, ls_local LIKE LINE OF it_local, ls_remote LIKE LINE OF it_remote, ls_diff LIKE LINE OF rt_diff, lt_delta LIKE it_delta, ls_delta LIKE LINE OF it_delta. lt_delta = it_delta. DO. READ TABLE lt_delta INTO ls_delta WITH KEY number = lv_rindex. IF sy-subrc = 0. DELETE lt_delta INDEX sy-tabix. CASE ls_delta-vrsflag. WHEN c_diff-delete. _append '' c_diff-delete ls_delta-line. lv_rindex = lv_rindex + 1. WHEN c_diff-insert. _append ls_delta-line c_diff-insert ''. lv_lindex = lv_lindex + 1. WHEN c_diff-update. CLEAR ls_local. READ TABLE it_local INTO ls_local INDEX lv_lindex. ASSERT sy-subrc = 0. _append ls_local c_diff-update ls_delta-line. lv_lindex = lv_lindex + 1. lv_rindex = lv_rindex + 1. WHEN OTHERS. ASSERT 0 = 1. ENDCASE. ELSE. CLEAR ls_local. READ TABLE it_local INTO ls_local INDEX lv_lindex. "#EC CI_SUBRC lv_lindex = lv_lindex + 1. CLEAR ls_remote. READ TABLE it_remote INTO ls_remote INDEX lv_rindex. "#EC CI_SUBRC lv_rindex = lv_rindex + 1. _append ls_local '' ls_remote. ENDIF. IF lv_lindex > lines( it_local ) AND lv_rindex > lines( it_remote ). EXIT. " current loop ENDIF. ENDDO. ENDMETHOD. "render ENDCLASS. "lcl_diff IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_pack DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_git_pack DEFINITION FINAL. PUBLIC SECTION. TYPES: BEGIN OF ty_node, chmod TYPE string, name TYPE string, sha1 TYPE ty_sha1, END OF ty_node. TYPES: ty_nodes_tt TYPE STANDARD TABLE OF ty_node WITH DEFAULT KEY. TYPES: BEGIN OF ty_object, sha1 TYPE ty_sha1, type TYPE ty_type, data TYPE xstring, END OF ty_object. TYPES: ty_objects_tt TYPE STANDARD TABLE OF ty_object WITH DEFAULT KEY. TYPES: BEGIN OF ty_commit, tree TYPE ty_sha1, parent TYPE ty_sha1, author TYPE string, committer TYPE string, body TYPE string, END OF ty_commit. CLASS-METHODS decode IMPORTING iv_data TYPE xstring RETURNING VALUE(rt_objects) TYPE ty_objects_tt RAISING lcx_exception. CLASS-METHODS decode_tree IMPORTING iv_data TYPE xstring RETURNING VALUE(rt_nodes) TYPE ty_nodes_tt RAISING lcx_exception. CLASS-METHODS decode_deltas CHANGING ct_objects TYPE ty_objects_tt RAISING lcx_exception. CLASS-METHODS decode_commit IMPORTING iv_data TYPE xstring RETURNING VALUE(rs_commit) TYPE ty_commit RAISING lcx_exception. CLASS-METHODS encode IMPORTING it_objects TYPE ty_objects_tt RETURNING VALUE(rv_data) TYPE xstring RAISING lcx_exception. CLASS-METHODS encode_tree IMPORTING it_nodes TYPE ty_nodes_tt RETURNING VALUE(rv_data) TYPE xstring. CLASS-METHODS encode_commit IMPORTING is_commit TYPE ty_commit RETURNING VALUE(rv_data) TYPE xstring. PRIVATE SECTION. CONSTANTS: c_pack_start TYPE x LENGTH 4 VALUE '5041434B', " PACK c_zlib TYPE x LENGTH 2 VALUE '789C', c_zlib_hmm TYPE x LENGTH 2 VALUE '7801', c_version TYPE x LENGTH 4 VALUE '00000002'. CLASS-METHODS type_and_length IMPORTING is_object TYPE ty_object RETURNING VALUE(rv_xstring) TYPE xstring RAISING lcx_exception. CLASS-METHODS delta IMPORTING is_object TYPE ty_object CHANGING ct_objects TYPE ty_objects_tt RAISING lcx_exception. CLASS-METHODS delta_header EXPORTING ev_header TYPE i CHANGING cv_delta TYPE xstring. CLASS-METHODS get_type IMPORTING iv_x TYPE x RETURNING VALUE(rv_type) TYPE ty_type RAISING lcx_exception. CLASS-METHODS get_length EXPORTING ev_length TYPE i CHANGING cv_data TYPE xstring. ENDCLASS. "lcl_pack DEFINITION CLASS lcl_objects_activation DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS add IMPORTING iv_type TYPE trobjtype iv_name TYPE clike RAISING lcx_exception. CLASS-METHODS add_item IMPORTING is_item TYPE ty_item RAISING lcx_exception. CLASS-METHODS activate RAISING lcx_exception. CLASS-METHODS clear. PRIVATE SECTION. CLASS-DATA: gt_ddic TYPE TABLE OF dwinactiv, gt_programs TYPE TABLE OF dwinactiv. ENDCLASS. CLASS lcl_objects_activation IMPLEMENTATION. METHOD add_item. add( iv_type = is_item-obj_type iv_name = is_item-obj_name ). ENDMETHOD. METHOD clear. CLEAR: gt_ddic, gt_programs. ENDMETHOD. METHOD activate. * ddic IF NOT gt_ddic IS INITIAL. CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE' EXPORTING activate_ddic_objects = abap_true with_popup = abap_true TABLES objects = gt_ddic EXCEPTIONS excecution_error = 1 cancelled = 2 insert_into_corr_error = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'error from RS_WORKING_OBJECTS_ACTIVATE'. ENDIF. ENDIF. * programs IF NOT gt_programs IS INITIAL. CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE' EXPORTING activate_ddic_objects = abap_false with_popup = abap_true TABLES objects = gt_programs EXCEPTIONS excecution_error = 1 cancelled = 2 insert_into_corr_error = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'error from RS_WORKING_OBJECTS_ACTIVATE'. ENDIF. ENDIF. ENDMETHOD. "activate METHOD add. * function group SEWORKINGAREA * function module RS_INSERT_INTO_WORKING_AREA * class CL_WB_ACTIVATION_WORK_AREA DATA: lt_objects TYPE dwinactiv_tab, lv_obj_name TYPE dwinactiv-obj_name. FIELD-SYMBOLS: LIKE LINE OF lt_objects. lv_obj_name = iv_name. * todo, refactoring CASE iv_type. WHEN 'CLAS' OR 'WDYN'. CALL FUNCTION 'RS_INACTIVE_OBJECTS_IN_OBJECT' EXPORTING obj_name = lv_obj_name object = iv_type TABLES inactive_objects = lt_objects EXCEPTIONS object_not_found = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Error from RS_INACTIVE_OBJECTS_IN_OBJECT'. ENDIF. APPEND LINES OF lt_objects TO gt_programs. WHEN 'DOMA' OR 'DTEL' OR 'TABL' OR 'INDX' OR 'TTYP' OR 'VIEW' OR 'SHLP' OR 'ENQU'. * todo also insert_into_working_area? APPEND INITIAL LINE TO gt_ddic ASSIGNING . -object = iv_type. -obj_name = lv_obj_name. WHEN 'REPS' OR 'DYNP' OR 'CUAD' OR 'REPT' OR 'INTF' OR 'FUNC' OR 'ENHO' OR 'TYPE'. * these seem to go into the workarea automatically APPEND INITIAL LINE TO gt_programs ASSIGNING . -object = iv_type. -obj_name = lv_obj_name. WHEN OTHERS. _raise 'activate, unknown type'. ENDCASE. ENDMETHOD. "activate ENDCLASS. CLASS lcl_objects_files DEFINITION FINAL. PUBLIC SECTION. METHODS: constructor IMPORTING is_item TYPE ty_item, add_html IMPORTING iv_html TYPE string RAISING lcx_exception, read_html RETURNING VALUE(rv_html) TYPE string RAISING lcx_exception, add_xml IMPORTING iv_extra TYPE clike OPTIONAL io_xml TYPE REF TO lcl_xml_output iv_normalize TYPE sap_bool DEFAULT abap_true RAISING lcx_exception, * needed since type-check during dynamic call fails even if the object is compatible add_xml_from_plugin IMPORTING iv_extra TYPE clike OPTIONAL io_xml TYPE REF TO object iv_normalize TYPE sap_bool DEFAULT abap_true RAISING lcx_exception ##CALLED, read_xml IMPORTING iv_extra TYPE clike OPTIONAL RETURNING VALUE(ro_xml) TYPE REF TO lcl_xml_input RAISING lcx_exception, read_abap IMPORTING iv_extra TYPE clike OPTIONAL iv_error TYPE sap_bool DEFAULT abap_true RETURNING VALUE(rt_abap) TYPE abaptxt255_tab RAISING lcx_exception, add_abap IMPORTING iv_extra TYPE clike OPTIONAL it_abap TYPE STANDARD TABLE RAISING lcx_exception, add IMPORTING is_file TYPE ty_file, get_files RETURNING VALUE(rt_files) TYPE ty_files_tt, set_files IMPORTING it_files TYPE ty_files_tt. PRIVATE SECTION. DATA: ms_item TYPE ty_item, mt_files TYPE ty_files_tt. METHODS: filename IMPORTING iv_extra TYPE clike OPTIONAL iv_ext TYPE string RETURNING VALUE(rv_filename) TYPE string. ENDCLASS. INTERFACE lif_object. TYPES: BEGIN OF ty_metadata, class TYPE string, version TYPE string, END OF ty_metadata. METHODS: serialize RAISING lcx_exception, deserialize IMPORTING iv_package TYPE devclass RAISING lcx_exception, delete RAISING lcx_exception, exists RETURNING VALUE(rv_bool) TYPE abap_bool RAISING lcx_exception, jump RAISING lcx_exception, get_metadata RETURNING VALUE(rs_metadata) TYPE ty_metadata. DATA: mo_files TYPE REF TO lcl_objects_files. ENDINTERFACE. CLASS lcl_objects_files IMPLEMENTATION. METHOD constructor. ms_item = is_item. ENDMETHOD. METHOD add. APPEND is_file TO mt_files. ENDMETHOD. METHOD get_files. rt_files = mt_files. ENDMETHOD. METHOD set_files. mt_files = it_files. ENDMETHOD. METHOD read_html. DATA: lv_filename TYPE string. FIELD-SYMBOLS: LIKE LINE OF mt_files. lv_filename = filename( 'html' ). "#EC NOTEXT READ TABLE mt_files ASSIGNING WITH KEY filename = lv_filename. IF sy-subrc <> 0. _raise 'html not found'. ENDIF. rv_html = lcl_convert=>xstring_to_string_utf8( -data ). ENDMETHOD. METHOD read_abap. DATA: lv_filename TYPE string, lv_abap TYPE string. FIELD-SYMBOLS: LIKE LINE OF mt_files. CLEAR rt_abap. lv_filename = filename( iv_extra = iv_extra iv_ext = 'abap' ). "#EC NOTEXT READ TABLE mt_files ASSIGNING WITH KEY filename = lv_filename. IF sy-subrc <> 0. IF iv_error = abap_true. _raise 'abap not found'. ELSE. RETURN. ENDIF. ENDIF. lv_abap = lcl_convert=>xstring_to_string_utf8( -data ). SPLIT lv_abap AT gc_newline INTO TABLE rt_abap. ENDMETHOD. "read_abap METHOD add_abap. DATA: lv_source TYPE string, ls_file TYPE ty_file. CONCATENATE LINES OF it_abap INTO lv_source SEPARATED BY gc_newline. ls_file-path = '/'. ls_file-filename = filename( iv_extra = iv_extra iv_ext = 'abap' ). "#EC NOTEXT ls_file-data = lcl_convert=>string_to_xstring_utf8( lv_source ). APPEND ls_file TO mt_files. ENDMETHOD. "abap_to_file METHOD add_html. DATA: ls_file TYPE ty_file. ls_file-path = '/'. ls_file-filename = filename( 'html' ). "#EC NOTEXT ls_file-data = lcl_convert=>string_to_xstring_utf8( iv_html ). APPEND ls_file TO mt_files. ENDMETHOD. METHOD add_xml. DATA: lv_xml TYPE string, ls_file TYPE ty_file. lv_xml = io_xml->render( iv_normalize = iv_normalize ). ls_file-path = '/'. ls_file-filename = filename( iv_extra = iv_extra iv_ext = 'xml' ). "#EC NOTEXT REPLACE FIRST OCCURRENCE OF '' IN lv_xml WITH ''. ls_file-data = lcl_convert=>string_to_xstring_utf8( lv_xml ). APPEND ls_file TO mt_files. ENDMETHOD. "do METHOD read_xml. DATA: lv_filename TYPE string, lv_xml TYPE string. FIELD-SYMBOLS: LIKE LINE OF mt_files. lv_filename = filename( iv_extra = iv_extra iv_ext = 'xml' ). "#EC NOTEXT READ TABLE mt_files ASSIGNING WITH KEY filename = lv_filename. IF sy-subrc <> 0. _raise 'xml not found'. ENDIF. lv_xml = lcl_convert=>xstring_to_string_utf8( -data ). CREATE OBJECT ro_xml EXPORTING iv_xml = lv_xml. ENDMETHOD. METHOD filename. DATA: lv_obj_name TYPE string. IF ms_item-obj_type = 'SICF'. * multiple SICF nodes with same name cannot be added to repository lv_obj_name = ms_item-obj_name(15). ELSE. lv_obj_name = ms_item-obj_name. ENDIF. * handle namespaces REPLACE ALL OCCURRENCES OF '/' IN lv_obj_name WITH '#'. IF iv_extra IS INITIAL. CONCATENATE lv_obj_name '.' ms_item-obj_type '.' iv_ext INTO rv_filename. "#EC NOTEXT ELSE. CONCATENATE lv_obj_name '.' ms_item-obj_type '.' iv_extra '.' iv_ext INTO rv_filename. "#EC NOTEXT ENDIF. TRANSLATE rv_filename TO LOWER CASE. ENDMETHOD. "filename METHOD add_xml_from_plugin. * this method wraps add_xml as in the plugin. This is necessary as the wrapped * xml-object in the plugin can only be typed to object. * ABAP does not perform implicit type casts (also if compatible) in signatures, * therefore this method's signature is typed ref to object DATA lo_xml TYPE REF TO lcl_xml_output. lo_xml ?= io_xml. me->add_xml( iv_extra = iv_extra io_xml = lo_xml iv_normalize = iv_normalize ). ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_objects_super DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_objects_super DEFINITION ABSTRACT. PUBLIC SECTION. METHODS: constructor IMPORTING is_item TYPE ty_item. PROTECTED SECTION. DATA: ms_item TYPE ty_item. METHODS: get_metadata RETURNING VALUE(rs_metadata) TYPE lif_object=>ty_metadata, corr_insert IMPORTING iv_package TYPE devclass RAISING lcx_exception, jump_se11 IMPORTING iv_radio TYPE string iv_field TYPE string RAISING lcx_exception. ENDCLASS. "lcl_objects_super DEFINITION ********************************************************************** * Enable plugins CLASS lcl_objects_bridge DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. CLASS-METHODS class_constructor. METHODS constructor IMPORTING is_item TYPE ty_item RAISING cx_sy_create_object_error. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. DATA: mo_plugin TYPE REF TO object. TYPES: BEGIN OF ty_s_objtype_map, obj_typ TYPE trobjtype, plugin_class TYPE seoclsname, END OF ty_s_objtype_map, ty_t_objtype_map TYPE SORTED TABLE OF ty_s_objtype_map WITH UNIQUE KEY obj_typ. CLASS-DATA gt_objtype_map TYPE ty_t_objtype_map. ENDCLASS. CLASS lcl_objects_bridge IMPLEMENTATION. METHOD lif_object~get_metadata. CALL METHOD mo_plugin->('ZIF_ABAPGIT_PLUGIN~GET_METADATA') RECEIVING rs_metadata = rs_metadata. ENDMETHOD. METHOD constructor. DATA ls_objtype_map LIKE LINE OF gt_objtype_map. super->constructor( is_item ). * determine the responsible plugin READ TABLE gt_objtype_map INTO ls_objtype_map WITH TABLE KEY obj_typ = is_item-obj_type. IF sy-subrc = 0. CREATE OBJECT mo_plugin TYPE (ls_objtype_map-plugin_class). CALL METHOD mo_plugin->('SET_ITEM') EXPORTING iv_obj_type = is_item-obj_type iv_obj_name = is_item-obj_name. ELSE. RAISE EXCEPTION TYPE cx_sy_create_object_error EXPORTING classname = 'LCL_OBJECTS_BRIDGE'. ENDIF. ENDMETHOD. METHOD lif_object~serialize. DATA: lo_files TYPE REF TO object, lo_wrapped_files TYPE REF TO object. CALL METHOD mo_plugin->('ZIF_ABAPGIT_PLUGIN~SERIALIZE'). CALL METHOD mo_plugin->('GET_FILES') RECEIVING ro_files_proxy = lo_files. "Returns a proxy wrapping a files-object CALL METHOD lo_files->('GET_WRAPPED_OBJECT') RECEIVING ro_objects_files = lo_wrapped_files. mo_files ?= lo_wrapped_files. ENDMETHOD. METHOD lif_object~deserialize. DATA: lx_plugin TYPE REF TO cx_static_check. TRY. CALL METHOD mo_plugin->('SET_FILES') EXPORTING io_objects_files = mo_files. CALL METHOD mo_plugin->('ZIF_ABAPGIT_PLUGIN~DESERIALIZE') EXPORTING iv_package = iv_package. CATCH cx_static_check INTO lx_plugin. RAISE EXCEPTION TYPE lcx_exception EXPORTING ix_previous = lx_plugin iv_text = lx_plugin->get_text( ). ENDTRY. ENDMETHOD. METHOD lif_object~delete. DATA lx_plugin TYPE REF TO cx_static_check. TRY. CALL METHOD mo_plugin->('ZIF_ABAPGIT_PLUGIN~DELETE'). CATCH cx_static_check INTO lx_plugin. RAISE EXCEPTION TYPE lcx_exception EXPORTING ix_previous = lx_plugin iv_text = lx_plugin->get_text( ). ENDTRY. ENDMETHOD. METHOD lif_object~exists. CALL METHOD mo_plugin->('ZIF_ABAPGIT_PLUGIN~EXISTS') RECEIVING rv_bool = rv_bool. ENDMETHOD. METHOD lif_object~jump. CALL METHOD mo_plugin->('ZIF_ABAPGIT_PLUGIN~JUMP'). ENDMETHOD. METHOD class_constructor. DATA lt_plugin_class TYPE STANDARD TABLE OF seoclsname WITH DEFAULT KEY. DATA lv_plugin_class LIKE LINE OF lt_plugin_class. DATA lo_plugin TYPE REF TO object. DATA lt_plugin_obj_type TYPE objtyptable. DATA ls_objtype_map LIKE LINE OF gt_objtype_map. SELECT ext~clsname FROM vseoextend AS ext INTO TABLE lt_plugin_class WHERE ext~refclsname LIKE 'ZCL_ABAPGIT_OBJECT%' AND ext~version = '1'. "#EC CI_SUBRC CLEAR gt_objtype_map. LOOP AT lt_plugin_class INTO lv_plugin_class WHERE table_line NE 'ZCL_ABAPGIT_OBJECT_BY_SOBJ'. "have the generic plugin only as fallback TRY. CREATE OBJECT lo_plugin TYPE (lv_plugin_class). CATCH cx_sy_create_object_error. CONTINUE. ">>>>>>>>>>>>>> ENDTRY. CALL METHOD lo_plugin->('GET_SUPPORTED_OBJ_TYPES') IMPORTING rt_obj_type = lt_plugin_obj_type. ls_objtype_map-plugin_class = lv_plugin_class. LOOP AT lt_plugin_obj_type INTO ls_objtype_map-obj_typ. INSERT ls_objtype_map INTO TABLE gt_objtype_map. IF sy-subrc <> 0. "No exception in class-contructor possible. Anyway, a shortdump is more appropriate in this case ASSERT 'There must not be' = |multiple ABAPGit-Plugins for the same object type { ls_objtype_map-obj_typ }|. ENDIF. ENDLOOP. ENDLOOP. "at plugins * and the same for the generic plugin if exists LOOP AT lt_plugin_class INTO lv_plugin_class WHERE table_line = 'ZCL_ABAPGIT_OBJECT_BY_SOBJ'. "have the generic plugin only as fallback CREATE OBJECT lo_plugin TYPE (lv_plugin_class). CALL METHOD lo_plugin->('GET_SUPPORTED_OBJ_TYPES') RECEIVING rt_obj_type = lt_plugin_obj_type. ls_objtype_map-plugin_class = lv_plugin_class. LOOP AT lt_plugin_obj_type INTO ls_objtype_map-obj_typ. INSERT ls_objtype_map INTO TABLE gt_objtype_map. "knowingly ignore the subrc ENDLOOP. ENDLOOP. "at plugins ENDMETHOD. ENDCLASS. ********************************************************************** CLASS lcl_objects_program DEFINITION INHERITING FROM lcl_objects_super. PUBLIC SECTION. TYPES: BEGIN OF ty_progdir, name TYPE progdir-name, state TYPE progdir-state, sqlx TYPE progdir-sqlx, edtx TYPE progdir-edtx, varcl TYPE progdir-varcl, dbapl TYPE progdir-dbapl, dbna TYPE progdir-dbna, clas TYPE progdir-clas, type TYPE progdir-type, occurs TYPE progdir-occurs, subc TYPE progdir-subc, appl TYPE progdir-appl, secu TYPE progdir-secu, cnam TYPE progdir-cnam, cdat TYPE progdir-cdat, unam TYPE progdir-unam, udat TYPE progdir-udat, vern TYPE progdir-vern, levl TYPE progdir-levl, rstat TYPE progdir-rstat, rmand TYPE progdir-rmand, rload TYPE progdir-rload, fixpt TYPE progdir-fixpt, sset TYPE progdir-sset, sdate TYPE progdir-sdate, stime TYPE progdir-stime, idate TYPE progdir-idate, itime TYPE progdir-itime, ldbname TYPE progdir-ldbname, uccheck TYPE progdir-uccheck, END OF ty_progdir. CLASS-METHODS serialize_program IMPORTING is_item TYPE ty_item io_files TYPE REF TO lcl_objects_files iv_program TYPE programm OPTIONAL iv_extra TYPE clike OPTIONAL RAISING lcx_exception. CLASS-METHODS read_progdir IMPORTING iv_program TYPE programm RETURNING VALUE(rs_progdir) TYPE ty_progdir. CLASS-METHODS deserialize_program IMPORTING is_progdir TYPE ty_progdir it_source TYPE abaptxt255_tab it_tpool TYPE textpool_table iv_package TYPE devclass RAISING lcx_exception. PROTECTED SECTION. TYPES: BEGIN OF ty_dynpro, header TYPE rpy_dyhead, containers TYPE dycatt_tab, fields TYPE dyfatc_tab, flow_logic TYPE swydyflow, END OF ty_dynpro. TYPES: ty_dynpro_tt TYPE STANDARD TABLE OF ty_dynpro WITH DEFAULT KEY. TYPES: BEGIN OF ty_cua, adm TYPE rsmpe_adm, sta TYPE STANDARD TABLE OF rsmpe_stat WITH DEFAULT KEY, fun TYPE STANDARD TABLE OF rsmpe_funt WITH DEFAULT KEY, men TYPE STANDARD TABLE OF rsmpe_men WITH DEFAULT KEY, mtx TYPE STANDARD TABLE OF rsmpe_mnlt WITH DEFAULT KEY, act TYPE STANDARD TABLE OF rsmpe_act WITH DEFAULT KEY, but TYPE STANDARD TABLE OF rsmpe_but WITH DEFAULT KEY, pfk TYPE STANDARD TABLE OF rsmpe_pfk WITH DEFAULT KEY, set TYPE STANDARD TABLE OF rsmpe_staf WITH DEFAULT KEY, doc TYPE STANDARD TABLE OF rsmpe_atrt WITH DEFAULT KEY, tit TYPE STANDARD TABLE OF rsmpe_titt WITH DEFAULT KEY, biv TYPE STANDARD TABLE OF rsmpe_buts WITH DEFAULT KEY, END OF ty_cua. PRIVATE SECTION. CLASS-METHODS serialize_dynpros IMPORTING iv_program_name TYPE programm RETURNING VALUE(rt_dynpro) TYPE ty_dynpro_tt RAISING lcx_exception. CLASS-METHODS serialize_cua IMPORTING iv_program_name TYPE programm RETURNING VALUE(rs_cua) TYPE ty_cua RAISING lcx_exception. ENDCLASS. CLASS lcl_objects_program IMPLEMENTATION. METHOD serialize_program. DATA: ls_progdir TYPE ty_progdir, lv_program_name TYPE programm, lt_dynpros TYPE ty_dynpro_tt, ls_cua TYPE ty_cua, lt_source TYPE TABLE OF abaptxt255, lt_tpool TYPE textpool_table, ls_tpool LIKE LINE OF lt_tpool, lo_xml TYPE REF TO lcl_xml_output. IF iv_program IS INITIAL. lv_program_name = is_item-obj_name. ELSE. lv_program_name = iv_program. ENDIF. CALL FUNCTION 'RPY_PROGRAM_READ' EXPORTING program_name = lv_program_name with_lowercase = abap_true TABLES source_extended = lt_source textelements = lt_tpool EXCEPTIONS cancelled = 1 not_found = 2 permission_error = 3 OTHERS = 4. IF sy-subrc = 2. RETURN. ELSEIF sy-subrc <> 0. _raise 'Error reading program'. ENDIF. ls_progdir = read_progdir( lv_program_name ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'PROGDIR' ig_data = ls_progdir ). IF ls_progdir-subc = '1'. lt_dynpros = serialize_dynpros( lv_program_name ). lo_xml->add( iv_name = 'DYNPROS' ig_data = lt_dynpros ). ls_cua = serialize_cua( lv_program_name ). lo_xml->add( iv_name = 'CUA' ig_data = ls_cua ). ENDIF. IF lines( lt_tpool ) = 1. READ TABLE lt_tpool INDEX 1 INTO ls_tpool. ASSERT sy-subrc = 0. IF ls_tpool-id = 'R' AND ls_tpool-key = '' AND ls_tpool-length = 0. DELETE lt_tpool INDEX 1. ENDIF. ENDIF. lo_xml->add( iv_name = 'TPOOL' ig_data = lt_tpool ). io_files->add_xml( iv_extra = iv_extra io_xml = lo_xml ). io_files->add_abap( iv_extra = iv_extra it_abap = lt_source ). ENDMETHOD. "serialize_program METHOD deserialize_program. DATA: lv_exists TYPE sap_bool, lv_progname TYPE reposrc-progname, ls_tpool LIKE LINE OF it_tpool, lv_title TYPE rglif-title, ls_progdir_new TYPE progdir. CALL FUNCTION 'RS_CORR_INSERT' EXPORTING object = is_progdir-name object_class = 'ABAP' devclass = iv_package master_language = gc_english mode = 'INSERT' EXCEPTIONS cancelled = 1 permission_failure = 2 unknown_objectclass = 3 OTHERS = 4. IF sy-subrc = 1. _raise 'Cancelled'. ELSEIF sy-subrc <> 0. _raise 'error from RS_CORR_INSERT'. ENDIF. READ TABLE it_tpool INTO ls_tpool WITH KEY id = 'R'. "#EC CI_SUBRC lv_title = ls_tpool-entry. SELECT SINGLE progname FROM reposrc INTO lv_progname WHERE progname = is_progdir-name AND r3state = 'A'. IF sy-subrc = 0. lv_exists = abap_true. ELSE. lv_exists = abap_false. ENDIF. IF lv_exists = abap_true. CALL FUNCTION 'RPY_PROGRAM_UPDATE' EXPORTING program_name = is_progdir-name title_string = lv_title save_inactive = 'I' TABLES source_extended = it_source EXCEPTIONS cancelled = 1 permission_error = 2 not_found = 3 OTHERS = 4. IF sy-subrc <> 0. IF sy-msgid = 'EU' AND sy-msgno = '510'. _raise 'User is currently editing program'. ELSE. _raise 'PROG, error updating'. ENDIF. ENDIF. ELSE. * function module RPY_PROGRAM_INSERT cannot handle function group includes INSERT REPORT is_progdir-name FROM it_source STATE 'I' PROGRAM TYPE is_progdir-subc. IF sy-subrc <> 0. _raise 'error from INSERT REPORT'. ENDIF. IF NOT it_tpool[] IS INITIAL. INSERT TEXTPOOL is_progdir-name FROM it_tpool LANGUAGE gc_english STATE 'I'. IF sy-subrc <> 0. _raise 'error from INSERT TEXTPOOL'. ENDIF. ENDIF. ENDIF. CALL FUNCTION 'READ_PROGDIR' EXPORTING i_progname = is_progdir-name i_state = 'I' IMPORTING e_progdir = ls_progdir_new EXCEPTIONS not_exists = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'not found in PROGDIR'. ENDIF. * todo, package? ls_progdir_new-ldbname = is_progdir-ldbname. ls_progdir_new-dbna = is_progdir-dbna. ls_progdir_new-dbapl = is_progdir-dbapl. ls_progdir_new-rload = is_progdir-rload. ls_progdir_new-fixpt = is_progdir-fixpt. ls_progdir_new-varcl = is_progdir-varcl. ls_progdir_new-appl = is_progdir-appl. CALL FUNCTION 'UPDATE_PROGDIR' EXPORTING i_progdir = ls_progdir_new i_progname = ls_progdir_new-name i_state = ls_progdir_new-state EXCEPTIONS not_executed = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'PROG, error inserting'. ENDIF. lcl_objects_activation=>add( iv_type = 'REPS' iv_name = is_progdir-name ). ENDMETHOD. "deserialize_program METHOD read_progdir. DATA: ls_sapdir TYPE progdir. CALL FUNCTION 'READ_PROGDIR' EXPORTING i_progname = iv_program i_state = 'A' IMPORTING e_progdir = ls_sapdir. MOVE-CORRESPONDING ls_sapdir TO rs_progdir. CLEAR: rs_progdir-edtx, rs_progdir-cnam, rs_progdir-cdat, rs_progdir-unam, rs_progdir-udat, rs_progdir-vern, rs_progdir-rmand, rs_progdir-sdate, rs_progdir-stime, rs_progdir-idate, rs_progdir-itime. ENDMETHOD. "read_progdir METHOD serialize_cua. CALL FUNCTION 'RS_CUA_INTERNAL_FETCH' EXPORTING program = iv_program_name language = gc_english state = 'A' IMPORTING adm = rs_cua-adm TABLES sta = rs_cua-sta fun = rs_cua-fun men = rs_cua-men mtx = rs_cua-mtx act = rs_cua-act but = rs_cua-but pfk = rs_cua-pfk set = rs_cua-set doc = rs_cua-doc tit = rs_cua-tit biv = rs_cua-biv EXCEPTIONS not_found = 1 unknown_version = 2 OTHERS = 3. IF sy-subrc <> 0. _raise 'error from RS_CUA_INTERNAL_FETCH'. ENDIF. ENDMETHOD. "serialize_cua METHOD serialize_dynpros. DATA: ls_header TYPE rpy_dyhead, lt_containers TYPE dycatt_tab, lt_fields_to_containers TYPE dyfatc_tab, lt_flow_logic TYPE swydyflow, lt_d020s TYPE TABLE OF d020s. FIELD-SYMBOLS: LIKE LINE OF lt_d020s, LIKE LINE OF rt_dynpro. CALL FUNCTION 'RS_SCREEN_LIST' EXPORTING dynnr = '' progname = iv_program_name TABLES dynpros = lt_d020s EXCEPTIONS not_found = 1 OTHERS = 2. IF sy-subrc = 2. _raise 'error from screen_list'. ENDIF. * loop dynpros and skip generated selection screens LOOP AT lt_d020s ASSIGNING WHERE type <> 'S'. CALL FUNCTION 'RPY_DYNPRO_READ' EXPORTING progname = iv_program_name dynnr = -dnum IMPORTING header = ls_header TABLES containers = lt_containers fields_to_containers = lt_fields_to_containers flow_logic = lt_flow_logic EXCEPTIONS cancelled = 1 not_found = 2 permission_error = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'Error while reading dynpro'. ENDIF. APPEND INITIAL LINE TO rt_dynpro ASSIGNING . -header = ls_header. -containers = lt_containers. -fields = lt_fields_to_containers. -flow_logic = lt_flow_logic. ENDLOOP. ENDMETHOD. "serialize_dynpros ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_objects_super IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_objects_super IMPLEMENTATION. METHOD constructor. ms_item = is_item. ENDMETHOD. METHOD jump_se11. DATA: lt_bdcdata TYPE TABLE OF bdcdata. FIELD-SYMBOLS: LIKE LINE OF lt_bdcdata. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -program = 'SAPLSD_ENTRY'. -dynpro = '1000'. -dynbegin = abap_true. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = 'BDC_OKCODE'. -fval = '=WB_DISPLAY'. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = iv_radio. -fval = abap_true. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = iv_field. -fval = ms_item-obj_name. CALL FUNCTION 'ABAP4_CALL_TRANSACTION' STARTING NEW TASK 'GIT' EXPORTING tcode = 'SE11' mode_val = 'E' TABLES using_tab = lt_bdcdata EXCEPTIONS system_failure = 1 communication_failure = 2 resource_failure = 3 OTHERS = 4 ##fm_subrc_ok. "#EC CI_SUBRC ENDMETHOD. "jump_se11 METHOD get_metadata. rs_metadata-class = cl_abap_classdescr=>describe_by_object_ref( me )->absolute_name. rs_metadata-version = 'v1.0.0'. ENDMETHOD. METHOD corr_insert. DATA: ls_object TYPE ddenqs. ls_object-objtype = ms_item-obj_type. ls_object-objname = ms_item-obj_name. CALL FUNCTION 'RS_CORR_INSERT' EXPORTING object = ls_object object_class = 'DICT' devclass = iv_package master_language = gc_english mode = 'INSERT' EXCEPTIONS cancelled = 1 permission_failure = 2 unknown_objectclass = 3 OTHERS = 4. IF sy-subrc = 1. _raise 'Cancelled'. ELSEIF sy-subrc <> 0. _raise 'error from RS_CORR_INSERT'. ENDIF. ENDMETHOD. "corr_insert ENDCLASS. "lcl_objects_super IMPLEMENTATION CLASS lcl_object_acid DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS: create_object RETURNING VALUE(ro_aab) TYPE REF TO cl_aab_id RAISING lcx_exception. ENDCLASS. CLASS lcl_object_acid IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD create_object. DATA: lv_name TYPE aab_id_name. lv_name = ms_item-obj_name. CREATE OBJECT ro_aab EXPORTING im_name = lv_name EXCEPTIONS name_not_allowed = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error creating CL_AAB_ID object'. ENDIF. ENDMETHOD. METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, lo_aab TYPE REF TO cl_aab_id, lv_description TYPE aab_id_descript. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. lo_aab = create_object( ). lo_aab->get_descript( IMPORTING ex_descript = lv_description ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DESCRIPTION' ig_data = lv_description ). mo_files->add_xml( lo_xml ). ENDMETHOD. METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_description TYPE aab_id_descript, lo_aab TYPE REF TO cl_aab_id. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DESCRIPTION' CHANGING cg_data = lv_description ). lo_aab = create_object( ). lo_aab->enqueue( ). lo_aab->set_descript( lv_description ). lo_aab->save( ). ENDMETHOD. METHOD lif_object~delete. DATA: lo_aab TYPE REF TO cl_aab_id. lo_aab = create_object( ). lo_aab->enqueue( ). lo_aab->delete( EXCEPTIONS prop_error = 1 propt_error = 2 act_error = 3 cts_error = 4 cts_devclass = 5 id_not_found = 6 no_authorization = 7 id_still_used = 8 where_used_error = 9 OTHERS = 10 ). IF sy-subrc <> 0. _raise 'error deleting ACID object'. ENDIF. lo_aab->dequeue( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_state TYPE flag, lo_aab TYPE REF TO cl_aab_id. lo_aab = create_object( ). lo_aab->get_state( IMPORTING ex_state = lv_state ). rv_bool = boolc( lv_state = abap_true ). ENDMETHOD. METHOD lif_object~jump. _raise 'todo, jump, ACID'. ENDMETHOD. ENDCLASS. * todo, to be removed later INCLUDE zabapgit_gateway IF FOUND. CLASS lcl_object_auth DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. CLASS lcl_object_auth IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_authx TYPE authx. SELECT SINGLE * FROM authx INTO ls_authx WHERE fieldname = ms_item-obj_name. "#EC CI_GENBUFF IF sy-subrc <> 0. RETURN. ENDIF. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'AUTHX' ig_data = ls_authx ). mo_files->add_xml( lo_xml ). ENDMETHOD. METHOD lif_object~deserialize. * see include LSAUT_FIELDF02 DATA: lo_xml TYPE REF TO lcl_xml_input, ls_authx TYPE authx, lo_auth TYPE REF TO cl_auth_tools. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'AUTHX' CHANGING cg_data = ls_authx ). CREATE OBJECT lo_auth. IF lo_auth->add_afield_to_trkorr( ls_authx-fieldname ) <> 0. _raise 'Error deserializing AUTH'. ENDIF. MODIFY authx FROM ls_authx. IF sy-subrc <> 0. _raise 'Error deserializing AUTH'. ENDIF. CALL FUNCTION 'DB_COMMIT'. lo_auth->set_authfld_info_from_db( ls_authx-fieldname ). ENDMETHOD. METHOD lif_object~delete. DATA: lv_fieldname TYPE authx-fieldname. lv_fieldname = ms_item-obj_name. * there is a bug in SAP standard, the TADIR entries are not deleted * when the AUTH object is deleted in transaction SU20 CALL FUNCTION 'SUSR_AUTF_DELETE_FIELD' EXPORTING fieldname = lv_fieldname EXCEPTIONS delete_not_possible = 1 field_in_use = 2 not_existing = 3 no_authority = 4 OTHERS = 5. IF sy-subrc <> 0. _raise 'error from SUSR_AUTF_DELETE_FIELD'. ENDIF. ENDMETHOD. METHOD lif_object~exists. DATA: lv_fieldname TYPE authx-fieldname. SELECT SINGLE fieldname FROM authx INTO lv_fieldname WHERE fieldname = ms_item-obj_name. "#EC CI_GENBUFF rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. _raise 'todo, AUTH jump'. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_object_doma DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_doma DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_doma DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_doma IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_doma IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_domname TYPE dd01l-domname. SELECT SINGLE domname FROM dd01l INTO lv_domname WHERE domname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. jump_se11( iv_radio = 'RSRD1-DOMA' iv_field = 'RSRD1-DOMA_VAL' ). ENDMETHOD. "jump METHOD lif_object~delete. * see class CL_WB_DDIC DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_true objname = lv_objname objtype = 'D' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. _raise 'error from RS_DD_DELETE_OBJ, DOMA'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. DATA: lv_name TYPE ddobjname, ls_dd01v TYPE dd01v, lt_dd07v TYPE TABLE OF dd07v, lo_xml TYPE REF TO lcl_xml_output. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_DOMA_GET' EXPORTING name = lv_name langu = gc_english IMPORTING dd01v_wa = ls_dd01v TABLES dd07v_tab = lt_dd07v EXCEPTIONS illegal_input = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from DDIF_DOMA_GET'. ENDIF. IF ls_dd01v IS INITIAL. RETURN. " does not exist ENDIF. CLEAR: ls_dd01v-as4user, ls_dd01v-as4date, ls_dd01v-as4time. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DD01V' ig_data = ls_dd01v ). lo_xml->add( iv_name = 'DD07V_TAB' ig_data = lt_dd07v ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. * package SEDD * package SDIC * fm TR_TADIR_INTERFACE * fm RS_CORR_INSERT ? DATA: lo_xml TYPE REF TO lcl_xml_input, ls_dd01v TYPE dd01v, lv_name TYPE ddobjname, lt_dd07v TYPE TABLE OF dd07v. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DD01V' CHANGING cg_data = ls_dd01v ). lo_xml->read( EXPORTING iv_name = 'DD07V_TAB' CHANGING cg_data = lt_dd07v ). corr_insert( iv_package ). lv_name = ms_item-obj_name. " type conversion CALL FUNCTION 'DDIF_DOMA_PUT' EXPORTING name = lv_name dd01v_wa = ls_dd01v TABLES dd07v_tab = lt_dd07v EXCEPTIONS doma_not_found = 1 name_inconsistent = 2 doma_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from DDIF_DOMA_PUT'. ENDIF. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_doma IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_iarp DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_iarp DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS: read EXPORTING es_attr TYPE w3resoattr et_parameters TYPE w3resopara_tabletype RAISING lcx_exception, save IMPORTING is_attr TYPE w3resoattr it_parameters TYPE w3resopara_tabletype RAISING lcx_exception. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_iarp IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_iarp IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD read. DATA: li_resource TYPE REF TO if_w3_api_resource, ls_name TYPE w3resokey. ls_name = ms_item-obj_name. cl_w3_api_resource=>if_w3_api_resource~load( EXPORTING p_resource_name = ls_name IMPORTING p_resource = li_resource EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc <> 0. _raise 'error from w3api_resource~load'. ENDIF. li_resource->get_attributes( IMPORTING p_attributes = es_attr ). CLEAR: es_attr-chname, es_attr-tdate, es_attr-ttime, es_attr-devclass. li_resource->get_parameters( IMPORTING p_parameters = et_parameters ). ENDMETHOD. METHOD lif_object~serialize. DATA: ls_attr TYPE w3resoattr, lo_xml TYPE REF TO lcl_xml_output, lt_parameters TYPE w3resopara_tabletype. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. read( IMPORTING es_attr = ls_attr et_parameters = lt_parameters ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'ATTR' ig_data = ls_attr ). lo_xml->add( iv_name = 'PARAMETERS' ig_data = lt_parameters ). mo_files->add_xml( lo_xml ). ENDMETHOD. METHOD save. DATA: li_resource TYPE REF TO if_w3_api_resource. cl_w3_api_resource=>if_w3_api_resource~create_new( EXPORTING p_resource_data = is_attr IMPORTING p_resource = li_resource ). li_resource->set_attributes( is_attr ). li_resource->set_parameters( it_parameters ). li_resource->if_w3_api_object~save( ). ENDMETHOD. METHOD lif_object~deserialize. DATA: ls_attr TYPE w3resoattr, lo_xml TYPE REF TO lcl_xml_input, lt_parameters TYPE w3resopara_tabletype. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'ATTR' CHANGING cg_data = ls_attr ). lo_xml->read( EXPORTING iv_name = 'PARAMETERS' CHANGING cg_data = lt_parameters ). ls_attr-devclass = iv_package. save( is_attr = ls_attr it_parameters = lt_parameters ). ENDMETHOD. METHOD lif_object~delete. DATA: li_resource TYPE REF TO if_w3_api_resource, ls_name TYPE w3resokey. ls_name = ms_item-obj_name. cl_w3_api_resource=>if_w3_api_resource~load( EXPORTING p_resource_name = ls_name IMPORTING p_resource = li_resource EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc <> 0. _raise 'error from if_w3_api_resource~load'. ENDIF. li_resource->if_w3_api_object~set_changeable( abap_true ). li_resource->if_w3_api_object~delete( ). li_resource->if_w3_api_object~save( ). ENDMETHOD. METHOD lif_object~exists. DATA: ls_name TYPE w3resokey. ls_name = ms_item-obj_name. cl_w3_api_resource=>if_w3_api_resource~load( EXPORTING p_resource_name = ls_name EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc = 1. rv_bool = abap_false. ELSEIF sy-subrc <> 0. _raise 'error from w3_api_resource~load'. ELSE. rv_bool = abap_true. ENDIF. ENDMETHOD. METHOD lif_object~jump. _raise 'todo, IARP, jump'. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_object_iasp DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_iasp DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS: read EXPORTING es_attr TYPE w3servattr et_parameters TYPE w3servpara_tabletype RAISING lcx_exception, save IMPORTING is_attr TYPE w3servattr it_parameters TYPE w3servpara_tabletype RAISING lcx_exception. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_iasp IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_iasp IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD read. DATA: li_service TYPE REF TO if_w3_api_service, lv_name TYPE itsappl. lv_name = ms_item-obj_name. cl_w3_api_service=>if_w3_api_service~load( EXPORTING p_service_name = lv_name IMPORTING p_service = li_service EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc <> 0. _raise 'error from w3api_service~load'. ENDIF. li_service->get_attributes( IMPORTING p_attributes = es_attr ). CLEAR: es_attr-chname, es_attr-tdate, es_attr-ttime, es_attr-devclass. li_service->get_parameters( IMPORTING p_parameters = et_parameters ). ENDMETHOD. METHOD lif_object~serialize. DATA: ls_attr TYPE w3servattr, lo_xml TYPE REF TO lcl_xml_output, lt_parameters TYPE w3servpara_tabletype. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. read( IMPORTING es_attr = ls_attr et_parameters = lt_parameters ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'ATTR' ig_data = ls_attr ). lo_xml->add( iv_name = 'PARAMETERS' ig_data = lt_parameters ). mo_files->add_xml( lo_xml ). ENDMETHOD. METHOD save. DATA: li_service TYPE REF TO if_w3_api_service. cl_w3_api_service=>if_w3_api_service~create_new( EXPORTING p_service_data = is_attr IMPORTING p_service = li_service ). li_service->set_attributes( is_attr ). li_service->set_parameters( it_parameters ). li_service->if_w3_api_object~save( ). ENDMETHOD. METHOD lif_object~deserialize. DATA: ls_attr TYPE w3servattr, lo_xml TYPE REF TO lcl_xml_input, lt_parameters TYPE w3servpara_tabletype. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'ATTR' CHANGING cg_data = ls_attr ). lo_xml->read( EXPORTING iv_name = 'PARAMETERS' CHANGING cg_data = lt_parameters ). ls_attr-devclass = iv_package. save( is_attr = ls_attr it_parameters = lt_parameters ). ENDMETHOD. METHOD lif_object~delete. DATA: li_service TYPE REF TO if_w3_api_service, lv_name TYPE itsappl. lv_name = ms_item-obj_name. cl_w3_api_service=>if_w3_api_service~load( EXPORTING p_service_name = lv_name IMPORTING p_service = li_service EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc <> 0. _raise 'error from if_w3_api_service~load'. ENDIF. li_service->if_w3_api_object~set_changeable( abap_true ). li_service->if_w3_api_object~delete( ). li_service->if_w3_api_object~save( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_name TYPE itsappl. lv_name = ms_item-obj_name. cl_w3_api_service=>if_w3_api_service~load( EXPORTING p_service_name = lv_name EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc = 1. rv_bool = abap_false. ELSEIF sy-subrc <> 0. _raise 'error from w3_api_service~load'. ELSE. rv_bool = abap_true. ENDIF. ENDMETHOD. METHOD lif_object~jump. _raise 'todo, IASP, jump'. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_object_iatu DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_iatu DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS: read EXPORTING es_attr TYPE w3tempattr ev_source TYPE string RAISING lcx_exception, save IMPORTING is_attr TYPE w3tempattr iv_source TYPE string RAISING lcx_exception. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_object_iatu IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_iatu IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD read. DATA: li_template TYPE REF TO if_w3_api_template, lt_source TYPE w3htmltabtype, ls_name TYPE iacikeyt. ls_name = ms_item-obj_name. cl_w3_api_template=>if_w3_api_template~load( EXPORTING p_template_name = ls_name IMPORTING p_template = li_template EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc <> 0. _raise 'error from w3api_template~load'. ENDIF. li_template->get_attributes( IMPORTING p_attributes = es_attr ). CLEAR: es_attr-chname, es_attr-tdate, es_attr-ttime, es_attr-devclass. li_template->get_source( IMPORTING p_source = lt_source ). CONCATENATE LINES OF lt_source INTO ev_source RESPECTING BLANKS. ENDMETHOD. METHOD lif_object~serialize. DATA: ls_attr TYPE w3tempattr, lv_source TYPE string, lo_xml TYPE REF TO lcl_xml_output. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. read( IMPORTING es_attr = ls_attr ev_source = lv_source ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'ATTR' ig_data = ls_attr ). mo_files->add_xml( lo_xml ). mo_files->add_html( lv_source ). ENDMETHOD. METHOD save. DATA: lt_source TYPE w3htmltabtype, lv_source TYPE string, li_template TYPE REF TO if_w3_api_template. cl_w3_api_template=>if_w3_api_template~create_new( EXPORTING p_template_data = is_attr p_program_name = is_attr-programm IMPORTING p_template = li_template ). li_template->set_attributes( is_attr ). lv_source = iv_source. WHILE strlen( lv_source ) >= 255. APPEND lv_source(255) TO lt_source. lv_source = lv_source+255. ENDWHILE. IF NOT lv_source IS INITIAL. APPEND lv_source TO lt_source. ENDIF. li_template->set_source( lt_source ). li_template->if_w3_api_object~save( ). ENDMETHOD. METHOD lif_object~deserialize. DATA: ls_attr TYPE w3tempattr, lv_source TYPE string, lo_xml TYPE REF TO lcl_xml_input. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'ATTR' CHANGING cg_data = ls_attr ). lv_source = mo_files->read_html( ). ls_attr-devclass = iv_package. save( is_attr = ls_attr iv_source = lv_source ). ENDMETHOD. METHOD lif_object~delete. DATA: li_template TYPE REF TO if_w3_api_template, ls_name TYPE iacikeyt. ls_name = ms_item-obj_name. cl_w3_api_template=>if_w3_api_template~load( EXPORTING p_template_name = ls_name IMPORTING p_template = li_template EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc <> 0. _raise 'error from if_w3_api_template~load'. ENDIF. li_template->if_w3_api_object~set_changeable( abap_true ). li_template->if_w3_api_object~delete( ). li_template->if_w3_api_object~save( ). ENDMETHOD. METHOD lif_object~exists. DATA: ls_name TYPE iacikeyt. ls_name = ms_item-obj_name. cl_w3_api_template=>if_w3_api_template~load( EXPORTING p_template_name = ls_name EXCEPTIONS object_not_existing = 1 permission_failure = 2 error_occured = 3 OTHERS = 4 ). IF sy-subrc = 1. rv_bool = abap_false. ELSEIF sy-subrc <> 0. _raise 'error from w3_api_template~load'. ELSE. rv_bool = abap_true. ENDIF. ENDMETHOD. METHOD lif_object~jump. _raise 'todo, IATU, jump'. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_dtel DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_dtel IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_rollname TYPE dd04l-rollname. SELECT SINGLE rollname FROM dd04l INTO lv_rollname WHERE rollname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. jump_se11( iv_radio = 'RSRD1-DDTYPE' iv_field = 'RSRD1-DDTYPE_VAL' ). ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_true objname = lv_objname objtype = 'E' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. _raise 'error from RS_DD_DELETE_OBJ, DTEL'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. DATA: lv_name TYPE ddobjname, ls_dd04v TYPE dd04v, ls_tpara TYPE tpara, lo_xml TYPE REF TO lcl_xml_output. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_DTEL_GET' EXPORTING name = lv_name langu = gc_english IMPORTING dd04v_wa = ls_dd04v tpara_wa = ls_tpara EXCEPTIONS illegal_input = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Error from DDIF_DTEL_GET'. ENDIF. IF ls_dd04v IS INITIAL. RETURN. " does not exist ENDIF. CLEAR: ls_dd04v-as4user, ls_dd04v-as4date, ls_dd04v-as4time. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DD04V' ig_data = ls_dd04v ). lo_xml->add( iv_name = 'TPARA' ig_data = ls_tpara ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, ls_dd04v TYPE dd04v, lv_name TYPE ddobjname, ls_tpara TYPE tpara. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DD04V' CHANGING cg_data = ls_dd04v ). lo_xml->read( EXPORTING iv_name = 'TPARA' CHANGING cg_data = ls_tpara ). corr_insert( iv_package ). lv_name = ms_item-obj_name. " type conversion CALL FUNCTION 'DDIF_DTEL_PUT' EXPORTING name = lv_name dd04v_wa = ls_dd04v EXCEPTIONS dtel_not_found = 1 name_inconsistent = 2 dtel_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from DDIF_DTEL_PUT'. ENDIF. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_clas DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. DATA mv_skip_testclass TYPE abap_bool. METHODS deserialize_abap IMPORTING io_xml TYPE REF TO lcl_xml_input iv_package TYPE devclass RAISING lcx_exception. METHODS deserialize_textpool IMPORTING io_xml TYPE REF TO lcl_xml_input RAISING lcx_exception. METHODS deserialize_docu IMPORTING io_xml TYPE REF TO lcl_xml_input RAISING lcx_exception. METHODS serialize_abap IMPORTING is_clskey TYPE seoclskey RETURNING VALUE(rt_source) TYPE ty_string_tt RAISING lcx_exception. METHODS serialize_locals_imp IMPORTING is_clskey TYPE seoclskey RETURNING VALUE(rt_source) TYPE ty_string_tt RAISING lcx_exception. METHODS serialize_locals_def IMPORTING is_clskey TYPE seoclskey RETURNING VALUE(rt_source) TYPE ty_string_tt RAISING lcx_exception. METHODS serialize_testclasses IMPORTING is_clskey TYPE seoclskey RETURNING VALUE(rt_source) TYPE ty_string_tt RAISING lcx_exception. METHODS serialize_macros IMPORTING is_clskey TYPE seoclskey RETURNING VALUE(rt_source) TYPE ty_string_tt RAISING lcx_exception. METHODS serialize_xml RAISING lcx_exception. METHODS remove_signatures CHANGING ct_source TYPE ty_string_tt. METHODS reduce CHANGING ct_source TYPE ty_string_tt. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_clas IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: ls_clskey TYPE seoclskey. ls_clskey-clsname = ms_item-obj_name. CALL FUNCTION 'SEO_CLASS_EXISTENCE_CHECK' EXPORTING clskey = ls_clskey EXCEPTIONS not_specified = 1 not_existing = 2 is_interface = 3 no_text = 4 inconsistent = 5 OTHERS = 6. rv_bool = boolc( sy-subrc <> 2 ). ENDMETHOD. METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = 'CLAS' in_new_window = abap_true. ENDMETHOD. "jump METHOD lif_object~delete. DATA: ls_clskey TYPE seoclskey. ls_clskey-clsname = ms_item-obj_name. CASE ms_item-obj_type. WHEN 'CLAS'. CALL FUNCTION 'SEO_CLASS_DELETE_COMPLETE' EXPORTING clskey = ls_clskey EXCEPTIONS not_existing = 1 is_interface = 2 db_error = 3 no_access = 4 other = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'Error from SEO_CLASS_DELETE_COMPLETE'. ENDIF. WHEN 'INTF'. CALL FUNCTION 'SEO_INTERFACE_DELETE_COMPLETE' EXPORTING intkey = ls_clskey EXCEPTIONS not_existing = 1 is_class = 2 db_error = 3 no_access = 4 other = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'Error from SEO_INTERFACE_DELETE_COMPLETE'. ENDIF. WHEN OTHERS. _raise 'class delete, unknown type'. ENDCASE. ENDMETHOD. "delete METHOD reduce. DATA: lv_source LIKE LINE OF ct_source, lv_found TYPE sap_bool. * skip files that only contain the standard comments lv_found = abap_false. LOOP AT ct_source INTO lv_source. IF strlen( lv_source ) >= 3 AND lv_source(3) <> '*"*'. lv_found = abap_true. ENDIF. ENDLOOP. IF lv_found = abap_false. CLEAR ct_source[]. ENDIF. ENDMETHOD. "reduce METHOD serialize_locals_imp. CALL FUNCTION 'SEO_CLASS_GET_INCLUDE_SOURCE' EXPORTING clskey = is_clskey inctype = seop_ext_class_locals_imp IMPORTING source_expanded = rt_source EXCEPTIONS _internal_class_not_existing = 1 not_existing = 2 OTHERS = 3. IF sy-subrc <> 0 AND sy-subrc <> 2. _raise 'Error from get_include_source, imp'. ENDIF. reduce( CHANGING ct_source = rt_source ). ENDMETHOD. "serialize_local METHOD serialize_locals_def. CALL FUNCTION 'SEO_CLASS_GET_INCLUDE_SOURCE' EXPORTING clskey = is_clskey inctype = seop_ext_class_locals_def IMPORTING source_expanded = rt_source EXCEPTIONS _internal_class_not_existing = 1 not_existing = 2 OTHERS = 3. IF sy-subrc <> 0 AND sy-subrc <> 2. _raise 'Error from get_include_source, def'. ENDIF. reduce( CHANGING ct_source = rt_source ). ENDMETHOD. "serialize_locals_def METHOD serialize_testclasses. DATA: lv_line1 LIKE LINE OF rt_source, lv_line2 LIKE LINE OF rt_source. CALL FUNCTION 'SEO_CLASS_GET_INCLUDE_SOURCE' EXPORTING clskey = is_clskey inctype = seop_ext_class_testclasses IMPORTING source_expanded = rt_source EXCEPTIONS _internal_class_not_existing = 1 not_existing = 2 OTHERS = 3. IF sy-subrc <> 0 AND sy-subrc <> 2. _raise 'Error from get_include_source, test'. ENDIF. * when creating classes in Eclipse it automatically generates the * testclass include, but it is not needed, so skip to avoid * creating an extra file in the repository. * Also remove it if the content is manually removed, but * the class still thinks it contains tests mv_skip_testclass = abap_false. IF lines( rt_source ) = 2. READ TABLE rt_source INDEX 1 INTO lv_line1. ASSERT sy-subrc = 0. READ TABLE rt_source INDEX 2 INTO lv_line2. ASSERT sy-subrc = 0. IF lv_line1(3) = '*"*' AND lv_line2 IS INITIAL. mv_skip_testclass = abap_true. ENDIF. ELSEIF lines( rt_source ) = 1. READ TABLE rt_source INDEX 1 INTO lv_line1. ASSERT sy-subrc = 0. IF lv_line1(3) = '*"*' OR lv_line1 IS INITIAL. mv_skip_testclass = abap_true. ENDIF. ELSEIF lines( rt_source ) = 0. mv_skip_testclass = abap_true. ENDIF. ENDMETHOD. "serialize_test METHOD serialize_macros. CALL FUNCTION 'SEO_CLASS_GET_INCLUDE_SOURCE' EXPORTING clskey = is_clskey inctype = seop_ext_class_macros IMPORTING source_expanded = rt_source EXCEPTIONS _internal_class_not_existing = 1 not_existing = 2 OTHERS = 3. IF sy-subrc <> 0 AND sy-subrc <> 2. _raise 'Error from get_include_source, macros'. ENDIF. reduce( CHANGING ct_source = rt_source ). ENDMETHOD. "serialize_macro METHOD serialize_abap. DATA: lo_source TYPE REF TO cl_oo_source. CREATE OBJECT lo_source EXPORTING clskey = is_clskey EXCEPTIONS class_not_existing = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from CL_OO_SOURCE'. ENDIF. lo_source->read( 'A' ). rt_source = lo_source->get_old_source( ). remove_signatures( CHANGING ct_source = rt_source ). ENDMETHOD. "serialize_abap METHOD remove_signatures. * signatures messes up in CL_OO_SOURCE when deserializing and serializing * within same session DATA: lv_begin TYPE string, lv_end TYPE string, lv_remove TYPE sap_bool, lv_source LIKE LINE OF ct_source. CONCATENATE '* ------------------------------------' '---------------------------------------------------+' INTO lv_begin. CONCATENATE '* +------------------------------------------------' '--------------------------------------' INTO lv_end. lv_remove = abap_false. LOOP AT ct_source INTO lv_source. IF lv_source = lv_begin. lv_remove = abap_true. ENDIF. IF lv_remove = abap_true. DELETE ct_source INDEX sy-tabix. ENDIF. IF lv_source = lv_end. lv_remove = abap_false. ENDIF. ENDLOOP. ENDMETHOD. "remove_signatures METHOD lif_object~serialize. DATA: lt_source TYPE seop_source_string, ls_clskey TYPE seoclskey. ls_clskey-clsname = ms_item-obj_name. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. CALL FUNCTION 'SEO_BUFFER_REFRESH' EXPORTING version = seoc_version_active force = seox_true. CALL FUNCTION 'SEO_BUFFER_REFRESH' EXPORTING version = seoc_version_inactive force = seox_true. lt_source = serialize_abap( ls_clskey ). mo_files->add_abap( lt_source ). IF ms_item-obj_type = 'CLAS'. lt_source = serialize_locals_def( ls_clskey ). IF NOT lt_source[] IS INITIAL. mo_files->add_abap( iv_extra = 'locals_def' it_abap = lt_source ). "#EC NOTEXT ENDIF. lt_source = serialize_locals_imp( ls_clskey ). IF NOT lt_source[] IS INITIAL. mo_files->add_abap( iv_extra = 'locals_imp' it_abap = lt_source ). "#EC NOTEXT ENDIF. lt_source = serialize_testclasses( ls_clskey ). IF NOT lt_source[] IS INITIAL AND mv_skip_testclass = abap_false. mo_files->add_abap( iv_extra = 'testclasses' it_abap = lt_source ). "#EC NOTEXT ENDIF. lt_source = serialize_macros( ls_clskey ). IF NOT lt_source[] IS INITIAL. mo_files->add_abap( iv_extra = 'macros' it_abap = lt_source ). "#EC NOTEXT ENDIF. ENDIF. serialize_xml( ). ENDMETHOD. "serialize METHOD serialize_xml. DATA: ls_vseoclass TYPE vseoclass, lv_cp TYPE program, lt_tpool TYPE textpool_table, lo_xml TYPE REF TO lcl_xml_output, lv_object TYPE dokhl-object, lv_state TYPE dokhl-dokstate, ls_vseointerf TYPE vseointerf, ls_clskey TYPE seoclskey, lt_lines TYPE tlinetab. ls_clskey-clsname = ms_item-obj_name. CALL FUNCTION 'SEO_CLIF_GET' EXPORTING cifkey = ls_clskey version = seoc_version_active IMPORTING class = ls_vseoclass interface = ls_vseointerf EXCEPTIONS not_existing = 1 deleted = 2 model_only = 3 OTHERS = 4. IF sy-subrc = 1. RETURN. " in case only inactive version exists ELSEIF sy-subrc <> 0. _raise 'error from seo_clif_get'. ENDIF. CLEAR: ls_vseoclass-uuid, ls_vseoclass-author, ls_vseoclass-createdon, ls_vseoclass-changedby, ls_vseoclass-changedon, ls_vseoclass-r3release, ls_vseoclass-chgdanyby, ls_vseoclass-chgdanyon. IF mv_skip_testclass = abap_true. CLEAR ls_vseoclass-with_unit_tests. ENDIF. CLEAR: ls_vseointerf-uuid, ls_vseointerf-author, ls_vseointerf-createdon, ls_vseointerf-changedby, ls_vseointerf-changedon, ls_vseointerf-r3release. CREATE OBJECT lo_xml. CASE ms_item-obj_type. WHEN 'CLAS'. lo_xml->add( iv_name = 'VSEOCLASS' ig_data = ls_vseoclass ). lv_cp = cl_oo_classname_service=>get_classpool_name( ls_clskey-clsname ). READ TEXTPOOL lv_cp INTO lt_tpool LANGUAGE gc_english. "#EC CI_READ_REP lo_xml->add( iv_name = 'TPOOL' ig_data = lt_tpool ). WHEN 'INTF'. lo_xml->add( iv_name = 'VSEOINTERF' ig_data = ls_vseointerf ). WHEN OTHERS. ASSERT 0 = 1. ENDCASE. lv_object = ls_clskey-clsname. CALL FUNCTION 'DOCU_GET' EXPORTING id = 'CL' langu = gc_english object = lv_object IMPORTING dokstate = lv_state TABLES line = lt_lines EXCEPTIONS no_docu_on_screen = 1 no_docu_self_def = 2 no_docu_temp = 3 ret_code = 4 OTHERS = 5. IF sy-subrc = 0 AND lv_state = 'R'. lo_xml->add( iv_name = 'LINES' ig_data = lt_lines ). ENDIF. mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize_xml METHOD lif_object~deserialize. * function group SEOK * function group SEOQ * function group SEOP * class CL_OO_CLASSNAME_SERVICE * class CL_OO_SOURCE DATA: lo_xml TYPE REF TO lcl_xml_input. lo_xml = mo_files->read_xml( ). deserialize_abap( io_xml = lo_xml iv_package = iv_package ). IF ms_item-obj_type = 'CLAS'. deserialize_textpool( lo_xml ). ENDIF. deserialize_docu( lo_xml ). ENDMETHOD. "deserialize METHOD deserialize_docu. DATA: lt_lines TYPE tlinetab, lv_object TYPE dokhl-object. io_xml->read( EXPORTING iv_name = 'LINES' CHANGING cg_data = lt_lines ). IF lt_lines[] IS INITIAL. RETURN. ENDIF. lv_object = ms_item-obj_name. CALL FUNCTION 'DOCU_UPD' EXPORTING id = 'CL' langu = gc_english object = lv_object TABLES line = lt_lines EXCEPTIONS ret_code = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from DOCU_UPD'. ENDIF. ENDMETHOD. "deserialize_doku METHOD deserialize_textpool. DATA: lv_cp TYPE program, lv_clsname TYPE seoclsname, lt_tpool TYPE textpool_table. io_xml->read( EXPORTING iv_name = 'TPOOL' CHANGING cg_data = lt_tpool ). IF lt_tpool[] IS INITIAL. RETURN. ENDIF. lv_clsname = ms_item-obj_name. lv_cp = cl_oo_classname_service=>get_classpool_name( lv_clsname ). INSERT TEXTPOOL lv_cp FROM lt_tpool LANGUAGE gc_english STATE 'I'. IF sy-subrc <> 0. _raise 'error from INSERT TEXTPOOL'. ENDIF. lcl_objects_activation=>add( iv_type = 'REPT' iv_name = lv_cp ). ENDMETHOD. "deserialize_textpool METHOD deserialize_abap. DATA: ls_vseoclass TYPE vseoclass, ls_vseointerf TYPE vseointerf, lt_source TYPE seop_source_string, lo_source TYPE REF TO cl_oo_source, lt_locals_def TYPE seop_source_string, lt_locals_imp TYPE seop_source_string, lt_locals_mac TYPE seop_source_string, lt_testclasses TYPE seop_source_string, ls_clskey TYPE seoclskey. lt_source = mo_files->read_abap( ). lt_locals_def = mo_files->read_abap( iv_extra = 'locals_def' iv_error = abap_false ). "#EC NOTEXT lt_locals_imp = mo_files->read_abap( iv_extra = 'locals_imp' iv_error = abap_false ). "#EC NOTEXT lt_locals_mac = mo_files->read_abap( iv_extra = 'macros' iv_error = abap_false ). "#EC NOTEXT lt_testclasses = mo_files->read_abap( iv_extra = 'testclasses' iv_error = abap_false ). "#EC NOTEXT ls_clskey-clsname = ms_item-obj_name. CASE ms_item-obj_type. WHEN 'CLAS'. io_xml->read( EXPORTING iv_name = 'VSEOCLASS' CHANGING cg_data = ls_vseoclass ). CALL FUNCTION 'SEO_CLASS_CREATE_COMPLETE' EXPORTING devclass = iv_package overwrite = seox_true CHANGING class = ls_vseoclass EXCEPTIONS existing = 1 is_interface = 2 db_error = 3 component_error = 4 no_access = 5 other = 6 OTHERS = 7. IF sy-subrc <> 0. _raise 'error from SEO_CLASS_CREATE_COMPLETE'. ENDIF. WHEN 'INTF'. io_xml->read( EXPORTING iv_name = 'VSEOINTERF' CHANGING cg_data = ls_vseointerf ). CALL FUNCTION 'SEO_INTERFACE_CREATE_COMPLETE' EXPORTING devclass = iv_package overwrite = seox_true CHANGING interface = ls_vseointerf EXCEPTIONS existing = 1 is_class = 2 db_error = 3 component_error = 4 no_access = 5 other = 6 OTHERS = 7. IF sy-subrc <> 0. _raise 'Error from SEO_INTERFACE_CREATE_COMPLETE'. ENDIF. WHEN OTHERS. ASSERT 0 = 1. ENDCASE. IF ms_item-obj_type = 'CLAS'. CALL FUNCTION 'SEO_CLASS_GENERATE_LOCALS' EXPORTING clskey = ls_clskey force = seox_true locals_def = lt_locals_def locals_imp = lt_locals_imp locals_mac = lt_locals_mac locals_testclasses = lt_testclasses EXCEPTIONS not_existing = 1 model_only = 2 locals_not_generated = 3 locals_not_initialised = 4 OTHERS = 5. IF sy-subrc <> 0. _raise 'error from generate_locals'. ENDIF. ENDIF. CREATE OBJECT lo_source EXPORTING clskey = ls_clskey EXCEPTIONS class_not_existing = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from CL_OO_SOURCE'. ENDIF. TRY. lo_source->access_permission( seok_access_modify ). lo_source->set_source( lt_source ). lo_source->save( ). lo_source->access_permission( seok_access_free ). CATCH cx_oo_access_permission. _raise 'permission error'. CATCH cx_oo_source_save_failure. _raise 'save failure'. ENDTRY. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_CLAS IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_smim DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_smim DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS get_filename IMPORTING iv_url TYPE string RETURNING VALUE(rv_filename) TYPE string. METHODS find_content IMPORTING iv_url TYPE string RETURNING VALUE(rv_content) TYPE xstring RAISING lcx_exception. METHODS build_filename IMPORTING iv_filename TYPE string RETURNING VALUE(rv_filename) TYPE string. METHODS get_url_for_io EXPORTING ev_url TYPE string ev_is_folder TYPE boole_d RAISING lcx_not_found lcx_exception. ENDCLASS. "lcl_object_smim DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_smim IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_smim IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. TRY. get_url_for_io( ). rv_bool = abap_true. CATCH lcx_not_found. rv_bool = abap_false. ENDTRY. ENDMETHOD. METHOD get_url_for_io. DATA: ls_io TYPE skwf_io, lv_url TYPE skwf_url, ls_smimloio TYPE smimloio, lv_loio TYPE sdok_docid. lv_loio = ms_item-obj_name. CLEAR ev_url. CLEAR ev_is_folder. SELECT SINGLE * FROM smimloio INTO ls_smimloio WHERE loio_id = lv_loio. "#EC CI_GENBUFF IF sy-subrc <> 0. RAISE EXCEPTION TYPE lcx_not_found. ENDIF. IF ls_smimloio-lo_class = wbmr_c_skwf_folder_class. ev_is_folder = abap_true. ls_io-objtype = skwfc_obtype_folder. ELSE. ls_io-objtype = skwfc_obtype_loio. ENDIF. ls_io-class = ls_smimloio-lo_class. ls_io-objid = ls_smimloio-loio_id. CALL FUNCTION 'SKWF_NMSPC_IO_ADDRESS_GET' EXPORTING io = ls_io IMPORTING url = lv_url. ev_url = lv_url. ENDMETHOD. "get_url_for_io METHOD build_filename. CONCATENATE ms_item-obj_name ms_item-obj_type iv_filename INTO rv_filename SEPARATED BY '.'. TRANSLATE rv_filename TO LOWER CASE. ENDMETHOD. "build_filename METHOD find_content. DATA: lv_filename TYPE string, lt_files TYPE ty_files_tt. FIELD-SYMBOLS: LIKE LINE OF lt_files. lv_filename = get_filename( iv_url ). lv_filename = build_filename( lv_filename ). lt_files = mo_files->get_files( ). READ TABLE lt_files ASSIGNING WITH KEY filename = lv_filename. IF sy-subrc <> 0. _raise 'SMIM, file not found'. ENDIF. rv_content = -data. ENDMETHOD. "find_content METHOD get_filename. DATA: lv_lines TYPE i, lt_strings TYPE TABLE OF string. SPLIT iv_url AT '/' INTO TABLE lt_strings. lv_lines = lines( lt_strings ). ASSERT lv_lines > 0. READ TABLE lt_strings INDEX lv_lines INTO rv_filename. ASSERT sy-subrc = 0. ENDMETHOD. "get_filename METHOD lif_object~serialize. DATA: lv_url TYPE string, lv_folder TYPE abap_bool, lv_filename TYPE string, ls_file TYPE ty_file, lv_content TYPE xstring, lo_xml TYPE REF TO lcl_xml_output, li_api TYPE REF TO if_mr_api. TRY. get_url_for_io( IMPORTING ev_url = lv_url ev_is_folder = lv_folder ). CATCH lcx_not_found. RETURN. ENDTRY. IF lv_folder = abap_false. li_api = cl_mime_repository_api=>if_mr_api~get_api( ). li_api->get( EXPORTING i_url = lv_url IMPORTING e_content = lv_content EXCEPTIONS parameter_missing = 1 error_occured = 2 not_found = 3 permission_failure = 4 OTHERS = 5 ). IF sy-subrc <> 0. _raise 'error from mime api->get'. ENDIF. lv_filename = get_filename( lv_url ). CLEAR ls_file. ls_file-filename = build_filename( lv_filename ). ls_file-path = '/'. ls_file-data = lv_content. mo_files->add( ls_file ). ENDIF. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'URL' ig_data = lv_url ). lo_xml->add( iv_name = 'FOLDER' ig_data = lv_folder ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lv_url TYPE string, lv_folder TYPE abap_bool, lo_xml TYPE REF TO lcl_xml_input, lv_content TYPE xstring, lv_filename TYPE skwf_filnm, lv_io TYPE sdok_docid, ls_skwf_io TYPE skwf_io, li_api TYPE REF TO if_mr_api. li_api = cl_mime_repository_api=>if_mr_api~get_api( ). lv_io = ms_item-obj_name. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'URL' CHANGING cg_data = lv_url ). lo_xml->read( EXPORTING iv_name = 'FOLDER' CHANGING cg_data = lv_folder ). ls_skwf_io-objid = lv_io. IF lv_folder = abap_true. li_api->create_folder( EXPORTING i_url = lv_url i_language = sy-langu i_dev_package = iv_package i_folder_loio = ls_skwf_io EXCEPTIONS parameter_missing = 1 error_occured = 2 cancelled = 3 permission_failure = 4 folder_exists = 5 OTHERS = 6 ). IF sy-subrc <> 5 AND sy-subrc <> 0. _raise 'error frrom SMIM create_folder'. ENDIF. ELSE. lv_filename = get_filename( lv_url ). cl_wb_mime_repository=>determine_io_class( EXPORTING filename = lv_filename IMPORTING io_class = ls_skwf_io-class ). CONCATENATE ls_skwf_io-class '_L' INTO ls_skwf_io-class. lv_content = find_content( lv_url ). li_api->put( EXPORTING i_url = lv_url i_content = lv_content i_dev_package = iv_package i_new_loio = ls_skwf_io EXCEPTIONS parameter_missing = 1 error_occured = 2 cancelled = 3 permission_failure = 4 data_inconsistency = 5 new_loio_already_exists = 6 is_folder = 7 OTHERS = 8 ). IF sy-subrc <> 0. _raise 'error from SMIM put'. ENDIF. ENDIF. ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: li_api TYPE REF TO if_mr_api, lv_url TYPE string. TRY. get_url_for_io( IMPORTING ev_url = lv_url ). CATCH lcx_not_found. RETURN. ENDTRY. li_api = cl_mime_repository_api=>if_mr_api~get_api( ). li_api->delete( EXPORTING i_url = lv_url i_delete_children = abap_true EXCEPTIONS parameter_missing = 1 error_occured = 2 cancelled = 3 permission_failure = 4 not_found = 5 OTHERS = 6 ). IF sy-subrc <> 0. _raise 'error from delete'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. _raise 'todo, SMIM, jump'. ENDMETHOD. "jump ENDCLASS. "lcl_object_smim IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_sicf DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_sicf DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. TYPES: ty_icfhandler_tt TYPE STANDARD TABLE OF icfhandler WITH DEFAULT KEY. TYPES: BEGIN OF ty_sicf_key, icf_name TYPE icfservice-icf_name, icfparguid TYPE icfservice-icfparguid, END OF ty_sicf_key. METHODS read EXPORTING es_icfservice TYPE icfservice es_icfdocu TYPE icfdocu et_icfhandler TYPE ty_icfhandler_tt ev_url TYPE string RAISING lcx_exception. METHODS insert_sicf IMPORTING is_icfservice TYPE icfservice is_icfdocu TYPE icfdocu it_icfhandler TYPE ty_icfhandler_tt iv_package TYPE devclass iv_url TYPE string RAISING lcx_exception. METHODS change_sicf IMPORTING is_icfservice TYPE icfservice is_icfdocu TYPE icfdocu it_icfhandler TYPE ty_icfhandler_tt iv_package TYPE devclass iv_parent TYPE icfparguid RAISING lcx_exception. METHODS to_icfhndlist IMPORTING it_list TYPE ty_icfhandler_tt RETURNING VALUE(rt_list) TYPE icfhndlist. METHODS find_parent IMPORTING iv_url TYPE string RETURNING VALUE(rv_parent) TYPE icfparguid RAISING lcx_exception. ENDCLASS. "lcl_object_sicf DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_sicf IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_sicf IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: ls_icfservice TYPE icfservice. read( IMPORTING es_icfservice = ls_icfservice ). rv_bool = boolc( NOT ls_icfservice IS INITIAL ). ENDMETHOD. METHOD lif_object~serialize. DATA: ls_icfservice TYPE icfservice, ls_icfdocu TYPE icfdocu, lv_url TYPE string, lo_xml TYPE REF TO lcl_xml_output, lt_icfhandler TYPE TABLE OF icfhandler. read( IMPORTING es_icfservice = ls_icfservice es_icfdocu = ls_icfdocu et_icfhandler = lt_icfhandler ev_url = lv_url ). IF ls_icfservice IS INITIAL. RETURN. ENDIF. CLEAR ls_icfservice-icfnodguid. CLEAR ls_icfservice-icfparguid. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'URL' ig_data = lv_url ). lo_xml->add( iv_name = 'ICFSERVICE' ig_data = ls_icfservice ). lo_xml->add( iv_name = 'ICFDOCU' ig_data = ls_icfdocu ). lo_xml->add( iv_name = 'ICFHANDLER_TABLE' ig_data = lt_icfhandler ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD read. DATA: lt_serv_info TYPE icfservtbl, ls_serv_info LIKE LINE OF lt_serv_info, ls_key TYPE ty_sicf_key. FIELD-SYMBOLS: LIKE LINE OF et_icfhandler. CLEAR es_icfservice. CLEAR es_icfdocu. CLEAR et_icfhandler. CLEAR ev_url. ls_key = ms_item-obj_name. IF ls_key-icfparguid IS INITIAL. * limitation: name must be unique SELECT SINGLE icfparguid FROM icfservice INTO ls_key-icfparguid WHERE icf_name = ls_key-icf_name AND icf_cuser <> 'SAP' ##warn_ok. IF sy-subrc <> 0. RETURN. ENDIF. ENDIF. cl_icf_tree=>if_icf_tree~get_info_from_serv( EXPORTING icf_name = ls_key-icf_name icfparguid = ls_key-icfparguid icf_langu = gc_english IMPORTING serv_info = lt_serv_info icfdocu = es_icfdocu url = ev_url EXCEPTIONS wrong_name = 1 wrong_parguid = 2 incorrect_service = 3 no_authority = 4 OTHERS = 5 ). IF sy-subrc <> 0. _raise 'error from get_info_from_serv'. ENDIF. ASSERT lines( lt_serv_info ) = 1. READ TABLE lt_serv_info INDEX 1 INTO ls_serv_info. ASSERT sy-subrc = 0. MOVE-CORRESPONDING ls_serv_info-service TO es_icfservice. CLEAR es_icfservice-icf_cuser. CLEAR es_icfservice-icf_cdate. CLEAR es_icfservice-icf_muser. CLEAR es_icfservice-icf_mdate. CLEAR es_icfdocu-icfparguid. APPEND LINES OF ls_serv_info-handlertbl TO et_icfhandler. LOOP AT et_icfhandler ASSIGNING . CLEAR -icfparguid. ENDLOOP. ENDMETHOD. "read METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, ls_icfservice TYPE icfservice, ls_read TYPE icfservice, ls_icfdocu TYPE icfdocu, lv_url TYPE string, lt_icfhandler TYPE TABLE OF icfhandler. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'URL' CHANGING cg_data = lv_url ). lo_xml->read( EXPORTING iv_name = 'ICFSERVICE' CHANGING cg_data = ls_icfservice ). lo_xml->read( EXPORTING iv_name = 'ICFDOCU' CHANGING cg_data = ls_icfdocu ). lo_xml->read( EXPORTING iv_name = 'ICFHANDLER_TABLE' CHANGING cg_data = lt_icfhandler ). read( IMPORTING es_icfservice = ls_read ). IF ls_read IS INITIAL. insert_sicf( is_icfservice = ls_icfservice is_icfdocu = ls_icfdocu it_icfhandler = lt_icfhandler iv_package = iv_package iv_url = lv_url ). ELSE. change_sicf( is_icfservice = ls_icfservice is_icfdocu = ls_icfdocu it_icfhandler = lt_icfhandler iv_package = iv_package iv_parent = ls_read-icfparguid ). ENDIF. ENDMETHOD. "deserialize METHOD to_icfhndlist. FIELD-SYMBOLS: LIKE LINE OF it_list. * convert to sorted table LOOP AT it_list ASSIGNING . INSERT -icfhandler INTO TABLE rt_list. ENDLOOP. ENDMETHOD. "to_icfhndlist METHOD find_parent. cl_icf_tree=>if_icf_tree~service_from_url( EXPORTING url = iv_url hostnumber = 0 IMPORTING icfnodguid = rv_parent EXCEPTIONS wrong_application = 1 no_application = 2 not_allow_application = 3 wrong_url = 4 no_authority = 5 OTHERS = 6 ). IF sy-subrc <> 0. _raise 'error from service_from_url'. ENDIF. ENDMETHOD. "find_parent METHOD insert_sicf. DATA: lt_icfhndlist TYPE icfhndlist, ls_icfserdesc TYPE icfserdesc, ls_icfdocu TYPE icfdocu, lv_parent TYPE icfparguid. lt_icfhndlist = to_icfhndlist( it_icfhandler ). lv_parent = find_parent( iv_url ). * nice, it seems that the structure should be mistreated ls_icfdocu = is_icfdocu-icf_docu. MOVE-CORRESPONDING is_icfservice TO ls_icfserdesc. cl_icf_tree=>if_icf_tree~insert_node( EXPORTING icf_name = is_icfservice-orig_name icfparguid = lv_parent icfdocu = ls_icfdocu doculang = gc_english icfhandlst = lt_icfhndlist package = iv_package application = space icfserdesc = ls_icfserdesc icfactive = abap_true EXCEPTIONS empty_icf_name = 1 no_new_virtual_host = 2 special_service_error = 3 parent_not_existing = 4 enqueue_error = 5 node_already_existing = 6 empty_docu = 7 doculang_not_installed = 8 security_info_error = 9 user_password_error = 10 password_encryption_error = 11 invalid_url = 12 invalid_otr_concept = 13 formflg401_error = 14 handler_error = 15 transport_error = 16 tadir_error = 17 package_not_found = 18 wrong_application = 19 not_allow_application = 20 no_application = 21 invalid_icfparguid = 22 alt_name_invalid = 23 alternate_name_exist = 24 wrong_icf_name = 25 no_authority = 26 OTHERS = 27 ). IF sy-subrc <> 0. _raise 'error from insert_node'. ENDIF. ENDMETHOD. "insert_sicf METHOD change_sicf. DATA: lt_icfhndlist TYPE icfhndlist, ls_icfserdesc TYPE icfserdesc. lt_icfhndlist = to_icfhndlist( it_icfhandler ). MOVE-CORRESPONDING is_icfservice TO ls_icfserdesc. cl_icf_tree=>if_icf_tree~change_node( EXPORTING icf_name = is_icfservice-orig_name icfparguid = iv_parent icfdocu = is_icfdocu doculang = gc_english icfhandlst = lt_icfhndlist package = iv_package application = space icfserdesc = ls_icfserdesc icfactive = abap_true EXCEPTIONS empty_icf_name = 1 no_new_virtual_host = 2 special_service_error = 3 parent_not_existing = 4 enqueue_error = 5 node_already_existing = 6 empty_docu = 7 doculang_not_installed = 8 security_info_error = 9 user_password_error = 10 password_encryption_error = 11 invalid_url = 12 invalid_otr_concept = 13 formflg401_error = 14 handler_error = 15 transport_error = 16 tadir_error = 17 package_not_found = 18 wrong_application = 19 not_allow_application = 20 no_application = 21 invalid_icfparguid = 22 alt_name_invalid = 23 alternate_name_exist = 24 wrong_icf_name = 25 no_authority = 26 OTHERS = 27 ). IF sy-subrc <> 0. _raise 'error from change_node'. ENDIF. ENDMETHOD. "change_sicf METHOD lif_object~delete. DATA: ls_icfservice TYPE icfservice. read( IMPORTING es_icfservice = ls_icfservice ). cl_icf_tree=>if_icf_tree~delete_node( EXPORTING icfparguid = ls_icfservice-icfparguid CHANGING icf_name = ls_icfservice-icf_name EXCEPTIONS no_virtual_host_delete = 1 special_service_error = 2 enqueue_error = 3 node_not_existing = 4 node_has_childs = 5 node_is_aliased = 6 node_not_in_original_system = 7 transport_error = 8 tadir_error = 9 db_error = 10 no_authority = 11 OTHERS = 12 ). IF sy-subrc <> 0. _raise 'error from delete_node'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. _raise 'todo, SICF, jump'. ENDMETHOD. "jump ENDCLASS. "lcl_object_sicf IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_ssst DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_ssst DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS validate_font IMPORTING iv_tdfamily TYPE tdfamily RAISING lcx_exception. ENDCLASS. "lcl_object_ssst DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_ssst IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_ssst IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_stylename TYPE stxsadm-stylename. SELECT SINGLE stylename FROM stxsadm INTO lv_stylename WHERE stylename = ms_item-obj_name. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD validate_font. DATA: lv_tdfamily TYPE tfo01-tdfamily. SELECT SINGLE tdfamily FROM tfo01 INTO lv_tdfamily WHERE tdfamily = iv_tdfamily. IF sy-subrc <> 0. _raise 'Font family not found'. ENDIF. ENDMETHOD. "validate_font METHOD lif_object~serialize. * see fm SSF_DOWNLOAD_STYLE DATA: lo_xml TYPE REF TO lcl_xml_output, lv_style_name TYPE tdssname, ls_header TYPE ssfcats, lt_paragraphs TYPE TABLE OF ssfparas, lt_strings TYPE TABLE OF ssfstrings, lt_tabstops TYPE TABLE OF stxstab. lv_style_name = ms_item-obj_name. CALL FUNCTION 'SSF_READ_STYLE' EXPORTING i_style_name = lv_style_name i_style_active_flag = 'A' i_style_variant = '%MAIN' i_style_language = gc_english IMPORTING e_header = ls_header TABLES e_paragraphs = lt_paragraphs e_strings = lt_strings e_tabstops = lt_tabstops EXCEPTIONS no_name = 1 no_style = 2 active_style_not_found = 3 inactive_style_not_found = 4 no_variant = 5 no_main_variant = 6 cancelled = 7 no_access_permission = 8 OTHERS = 9. IF sy-subrc = 2. RETURN. ELSEIF sy-subrc <> 0. _raise 'error from SSF_READ_STYLE'. ENDIF. CLEAR ls_header-version. CLEAR ls_header-firstuser. CLEAR ls_header-firstdate. CLEAR ls_header-firsttime. CLEAR ls_header-lastuser. CLEAR ls_header-lastdate. CLEAR ls_header-lasttime. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'HEADER' ig_data = ls_header ). lo_xml->add( ig_data = lt_paragraphs iv_name = 'SSFPARAS' ). lo_xml->add( ig_data = lt_strings iv_name = 'SSFSTRINGS' ). lo_xml->add( ig_data = lt_tabstops iv_name = 'STXSTAB' ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. * see fm SSF_UPLOAD_STYLE DATA: lo_xml TYPE REF TO lcl_xml_input, ls_header TYPE ssfcats, lt_paragraphs TYPE TABLE OF ssfparas, lt_strings TYPE TABLE OF ssfstrings, lt_tabstops TYPE TABLE OF stxstab. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'HEADER' CHANGING cg_data = ls_header ). lo_xml->read( EXPORTING iv_name = 'SSFPARAS' CHANGING cg_data = lt_paragraphs ). lo_xml->read( EXPORTING iv_name = 'SSFSTRINGS' CHANGING cg_data = lt_strings ). lo_xml->read( EXPORTING iv_name = 'STXSTAB' CHANGING cg_data = lt_tabstops ). validate_font( ls_header-tdfamily ). CALL FUNCTION 'SSF_SAVE_STYLE' EXPORTING i_header = ls_header TABLES i_paragraphs = lt_paragraphs i_strings = lt_strings i_tabstops = lt_tabstops. CALL FUNCTION 'SSF_ACTIVATE_STYLE' EXPORTING i_stylename = ls_header-stylename EXCEPTIONS no_name = 1 no_style = 2 cancelled = 3 no_access_permission = 4 illegal_language = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from SSF_ACTIVATE_STYLE'. ENDIF. ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lv_stylename TYPE tdssname. lv_stylename = ms_item-obj_name. CALL FUNCTION 'SSF_DELETE_STYLE' EXPORTING i_stylename = lv_stylename i_with_dialog = abap_false i_with_confirm_dialog = abap_false EXCEPTIONS no_name = 1 no_style = 2 style_locked = 3 cancelled = 4 no_access_permission = 5 illegal_language = 6 OTHERS = 7. IF sy-subrc <> 0 AND sy-subrc <> 2. _raise 'error from SSF_DELETE_STYLE'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. _raise 'todo'. ENDMETHOD. "jump ENDCLASS. "lcl_object_ssst IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_suso DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_suso DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_suso DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_wdyn DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_wdyn DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. DATA: mt_components TYPE TABLE OF wdy_ctlr_compo_vrs, mt_sources TYPE TABLE OF wdy_ctlr_compo_source_vrs. METHODS: get_limu_objects RETURNING VALUE(rt_objects) TYPE wdy_md_transport_keys, read RETURNING VALUE(rs_component) TYPE wdy_component_metadata RAISING lcx_exception, read_controller IMPORTING is_key TYPE wdy_md_controller_key RETURNING VALUE(rs_controller) TYPE wdy_md_controller_meta_data RAISING lcx_exception, read_definition IMPORTING is_key TYPE wdy_md_component_key RETURNING VALUE(rs_definition) TYPE wdy_md_component_meta_data RAISING lcx_exception, read_view IMPORTING is_key TYPE wdy_md_view_key RETURNING VALUE(rs_view) TYPE wdy_md_view_meta_data RAISING lcx_exception, recover_controller IMPORTING is_controller TYPE wdy_md_controller_meta_data RAISING lcx_exception, recover_definition IMPORTING is_definition TYPE wdy_md_component_meta_data RAISING lcx_exception, recover_view IMPORTING is_view TYPE wdy_md_view_meta_data RAISING lcx_exception, delta_controller IMPORTING is_controller TYPE wdy_md_controller_meta_data RETURNING VALUE(rs_delta) TYPE svrs2_xversionable_object RAISING lcx_exception, delta_definition IMPORTING is_definition TYPE wdy_md_component_meta_data RETURNING VALUE(rs_delta) TYPE svrs2_xversionable_object RAISING lcx_exception, delta_view IMPORTING is_view TYPE wdy_md_view_meta_data RETURNING VALUE(rs_delta) TYPE svrs2_xversionable_object RAISING lcx_exception. ENDCLASS. "lcl_object_wdyn DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_wdyn IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_wdyn IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_component_name TYPE wdy_component-component_name. SELECT SINGLE component_name FROM wdy_component INTO lv_component_name WHERE component_name = ms_item-obj_name AND version = 'A'. "#EC CI_GENBUFF rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD delta_definition. DATA: ls_key TYPE wdy_md_component_key, lv_found TYPE abap_bool, ls_obj_new TYPE svrs2_versionable_object, li_component TYPE REF TO if_wdy_md_component, ls_obj_old TYPE svrs2_versionable_object. ls_key-component_name = is_definition-definition-component_name. lv_found = cl_wdy_md_component=>check_existency( ls_key-component_name ). IF lv_found = abap_false. TRY. cl_wdy_md_component=>create_complete( EXPORTING name = ls_key-component_name IMPORTING component = li_component ). li_component->save_to_database( ). li_component->unlock( ). CATCH cx_wdy_md_exception. _raise 'error creating dummy component'. ENDTRY. ENDIF. ls_obj_new-objtype = wdyn_limu_component_definition. ls_obj_new-objname = ls_key-component_name. ls_obj_old-objtype = wdyn_limu_component_definition. ls_obj_old-objname = ls_key-component_name. APPEND is_definition-definition TO ls_obj_old-wdyd-defin. ls_obj_old-wdyd-descr = is_definition-descriptions. ls_obj_old-wdyd-cusag = is_definition-component_usages. ls_obj_old-wdyd-intrf = is_definition-interface_implementings. ls_obj_old-wdyd-libra = is_definition-library_usages. ls_obj_old-wdyd-ctuse = is_definition-ext_ctlr_usages. ls_obj_old-wdyd-ctmap = is_definition-ext_ctx_mappings. CALL FUNCTION 'SVRS_MAKE_OBJECT_DELTA' EXPORTING obj_old = ls_obj_new obj_new = ls_obj_old CHANGING delta = rs_delta EXCEPTIONS inconsistent_objects = 1. IF sy-subrc <> 0. _raise 'error from SVRS_MAKE_OBJECT_DELTA'. ENDIF. ENDMETHOD. "delta_definition METHOD delta_controller. DATA: li_controller TYPE REF TO if_wdy_md_controller, lv_found TYPE abap_bool, ls_key TYPE wdy_md_controller_key, ls_obj_new TYPE svrs2_versionable_object, ls_obj_old TYPE svrs2_versionable_object. FIELD-SYMBOLS: LIKE LINE OF mt_components, LIKE LINE OF mt_sources. ls_key-component_name = is_controller-definition-component_name. ls_key-controller_name = is_controller-definition-controller_name. lv_found = cl_wdy_md_controller=>check_existency( component_name = ls_key-component_name controller_name = ls_key-controller_name ). IF lv_found = abap_false. TRY. li_controller ?= cl_wdy_md_controller=>create_complete( component_name = ls_key-component_name controller_name = ls_key-controller_name controller_type = is_controller-definition-controller_type ). li_controller->save_to_database( ). li_controller->unlock( ). CATCH cx_wdy_md_exception. _raise 'error creating dummy controller'. ENDTRY. ENDIF. ls_obj_new-objtype = wdyn_limu_component_controller. ls_obj_new-objname = ls_key. ls_obj_old-objtype = wdyn_limu_component_controller. ls_obj_old-objname = ls_key. APPEND is_controller-definition TO ls_obj_old-wdyc-defin. LOOP AT mt_components ASSIGNING WHERE component_name = ls_key-component_name AND controller_name = ls_key-controller_name. APPEND TO ls_obj_old-wdyc-ccomp. ENDLOOP. LOOP AT mt_sources ASSIGNING WHERE component_name = ls_key-component_name AND controller_name = ls_key-controller_name. APPEND TO ls_obj_old-wdyc-ccoms. ENDLOOP. ls_obj_old-wdyc-descr = is_controller-descriptions. ls_obj_old-wdyc-cusag = is_controller-controller_usages. ls_obj_old-wdyc-ccomt = is_controller-controller_component_texts. ls_obj_old-wdyc-cpara = is_controller-controller_parameters. ls_obj_old-wdyc-cpart = is_controller-controller_parameter_texts. ls_obj_old-wdyc-cnode = is_controller-context_nodes. ls_obj_old-wdyc-cattr = is_controller-context_attributes. ls_obj_old-wdyc-cmapp = is_controller-context_mappings. ls_obj_old-wdyc-excp = is_controller-controller_exceptions. ls_obj_old-wdyc-excpt = is_controller-controller_exception_texts. ls_obj_old-wdyc-fgrps = is_controller-fieldgroups. CALL FUNCTION 'SVRS_MAKE_OBJECT_DELTA' EXPORTING obj_old = ls_obj_new obj_new = ls_obj_old CHANGING delta = rs_delta EXCEPTIONS inconsistent_objects = 1. IF sy-subrc <> 0. _raise 'error from SVRS_MAKE_OBJECT_DELTA'. ENDIF. ENDMETHOD. "delta_controller METHOD delta_view. DATA: ls_key TYPE wdy_md_view_key, ls_obj_new TYPE svrs2_versionable_object, ls_obj_old TYPE svrs2_versionable_object, lv_found TYPE abap_bool, li_view TYPE REF TO if_wdy_md_abstract_view. FIELD-SYMBOLS: LIKE LINE OF ls_obj_old-wdyv-defin. ls_key-component_name = is_view-definition-component_name. ls_key-view_name = is_view-definition-view_name. lv_found = cl_wdy_md_abstract_view=>check_existency( component_name = ls_key-component_name name = ls_key-view_name ). IF lv_found = abap_false. TRY. li_view = cl_wdy_md_abstract_view=>create( component_name = is_view-definition-component_name view_name = is_view-definition-view_name type = is_view-definition-type ). li_view->save_to_database( ). li_view->unlock( ). CATCH cx_wdy_md_exception. _raise 'error creating dummy view'. ENDTRY. ENDIF. ls_obj_new-objtype = wdyn_limu_component_view. ls_obj_new-objname = ls_key. ls_obj_old-objtype = wdyn_limu_component_view. ls_obj_old-objname = ls_key. APPEND INITIAL LINE TO ls_obj_old-wdyv-defin ASSIGNING . MOVE-CORRESPONDING is_view-definition TO . ls_obj_old-wdyv-descr = is_view-descriptions. ls_obj_old-wdyv-vcont = is_view-view_containers. ls_obj_old-wdyv-vcntt = is_view-view_container_texts. ls_obj_old-wdyv-ibplg = is_view-iobound_plugs. ls_obj_old-wdyv-ibplt = is_view-iobound_plug_texts. ls_obj_old-wdyv-plpar = is_view-plug_parameters. ls_obj_old-wdyv-plprt = is_view-plug_parameter_texts. ls_obj_old-wdyv-uiele = is_view-ui_elements. ls_obj_old-wdyv-uicon = is_view-ui_context_bindings. ls_obj_old-wdyv-uievt = is_view-ui_event_bindings. ls_obj_old-wdyv-uiddc = is_view-ui_ddic_bindings. ls_obj_old-wdyv-uiprp = is_view-ui_properties. ls_obj_old-wdyv-navil = is_view-navigation_links. ls_obj_old-wdyv-navit = is_view-navigation_target_refs. ls_obj_old-wdyv-vshno = is_view-vsh_nodes. ls_obj_old-wdyv-vshpl = is_view-vsh_placeholders. ls_obj_old-wdyv-views = is_view-viewset_properties. CALL FUNCTION 'SVRS_MAKE_OBJECT_DELTA' EXPORTING obj_old = ls_obj_new obj_new = ls_obj_old CHANGING delta = rs_delta EXCEPTIONS inconsistent_objects = 1. IF sy-subrc <> 0. _raise 'error from SVRS_MAKE_OBJECT_DELTA'. ENDIF. ENDMETHOD. "delta_view METHOD recover_definition. DATA: ls_key TYPE wdy_md_component_key, lv_corrnr TYPE trkorr, ls_delta TYPE svrs2_xversionable_object. ls_delta = delta_definition( is_definition ). ls_key-component_name = is_definition-definition-component_name. cl_wdy_md_component=>recover_version( EXPORTING component_key = ls_key delta = ls_delta-wdyd CHANGING corrnr = lv_corrnr ). ENDMETHOD. "recover_definition METHOD recover_controller. DATA: ls_key TYPE wdy_controller_key, lv_corrnr TYPE trkorr, ls_delta TYPE svrs2_xversionable_object. ls_delta = delta_controller( is_controller ). ls_key-component_name = is_controller-definition-component_name. ls_key-controller_name = is_controller-definition-controller_name. cl_wdy_md_controller=>recover_version( EXPORTING controller_key = ls_key delta = ls_delta-wdyc CHANGING corrnr = lv_corrnr ). ENDMETHOD. "recover_controller METHOD recover_view. DATA: ls_key TYPE wdy_md_view_key, lv_corrnr TYPE trkorr, ls_delta TYPE svrs2_xversionable_object. ls_delta = delta_view( is_view ). ls_key-component_name = is_view-definition-component_name. ls_key-view_name = is_view-definition-view_name. cl_wdy_md_abstract_view=>recover_version( EXPORTING view_key = ls_key delta = ls_delta-wdyv CHANGING corrnr = lv_corrnr ). ENDMETHOD. "recover_view METHOD read_controller. DATA: lt_components TYPE TABLE OF wdy_ctlr_compo_vrs, lt_sources TYPE TABLE OF wdy_ctlr_compo_source_vrs, lt_definition TYPE TABLE OF wdy_controller, lt_psmodilog TYPE TABLE OF smodilog, lt_psmodisrc TYPE TABLE OF smodisrc. CALL FUNCTION 'WDYC_GET_OBJECT' EXPORTING controller_key = is_key get_all_translations = abap_false TABLES definition = lt_definition descriptions = rs_controller-descriptions controller_usages = rs_controller-controller_usages controller_components = lt_components controller_component_sources = lt_sources controller_component_texts = rs_controller-controller_component_texts controller_parameters = rs_controller-controller_parameters controller_parameter_texts = rs_controller-controller_parameter_texts context_nodes = rs_controller-context_nodes context_attributes = rs_controller-context_attributes context_mappings = rs_controller-context_mappings fieldgroups = rs_controller-fieldgroups controller_exceptions = rs_controller-controller_exceptions controller_exception_texts = rs_controller-controller_exception_texts psmodilog = lt_psmodilog " not optional in all versions psmodisrc = lt_psmodisrc " not optional in all versions EXCEPTIONS not_existing = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from WDYC_GET_OBJECT'. ENDIF. APPEND LINES OF lt_components TO mt_components. APPEND LINES OF lt_sources TO mt_sources. READ TABLE lt_definition INDEX 1 INTO rs_controller-definition. IF sy-subrc <> 0. _raise 'WDYC, definition not found'. ENDIF. CLEAR: rs_controller-definition-author, rs_controller-definition-createdon, rs_controller-definition-changedby, rs_controller-definition-changedon. ENDMETHOD. "read_controller METHOD read_definition. DATA: lt_definition TYPE TABLE OF wdy_component, lt_psmodilog TYPE TABLE OF smodilog, lt_psmodisrc TYPE TABLE OF smodisrc. CALL FUNCTION 'WDYD_GET_OBJECT' EXPORTING component_key = is_key get_all_translations = abap_false TABLES definition = lt_definition descriptions = rs_definition-descriptions component_usages = rs_definition-component_usages interface_implementings = rs_definition-interface_implementings library_usages = rs_definition-library_usages ext_ctlr_usages = rs_definition-ext_ctlr_usages ext_ctx_mappings = rs_definition-ext_ctx_mappings psmodilog = lt_psmodilog " not optional in all versions psmodisrc = lt_psmodisrc " not optional in all versions EXCEPTIONS not_existing = 1 OTHERS = 2. IF sy-subrc = 1. RETURN. ELSEIF sy-subrc <> 0. _raise 'error from WDYD_GET_OBJECT'. ENDIF. READ TABLE lt_definition INDEX 1 INTO rs_definition-definition. IF sy-subrc <> 0. _raise 'WDYD, definition not found'. ENDIF. CLEAR: rs_definition-definition-author, rs_definition-definition-createdon, rs_definition-definition-changedby, rs_definition-definition-changedon, rs_definition-definition-gendate, rs_definition-definition-gentime. ENDMETHOD. "read_definition METHOD read_view. DATA: lt_definition TYPE TABLE OF wdy_view_vrs, lt_psmodilog TYPE TABLE OF smodilog, lt_psmodisrc TYPE TABLE OF smodisrc. FIELD-SYMBOLS: LIKE LINE OF lt_definition. CALL FUNCTION 'WDYV_GET_OBJECT' EXPORTING view_key = is_key get_all_translations = abap_false TABLES definition = lt_definition descriptions = rs_view-descriptions view_containers = rs_view-view_containers view_container_texts = rs_view-view_container_texts iobound_plugs = rs_view-iobound_plugs iobound_plug_texts = rs_view-iobound_plug_texts plug_parameters = rs_view-plug_parameters plug_parameter_texts = rs_view-plug_parameter_texts ui_elements = rs_view-ui_elements ui_context_bindings = rs_view-ui_context_bindings ui_event_bindings = rs_view-ui_event_bindings ui_ddic_bindings = rs_view-ui_ddic_bindings ui_properties = rs_view-ui_properties navigation_links = rs_view-navigation_links navigation_target_refs = rs_view-navigation_target_refs vsh_nodes = rs_view-vsh_nodes vsh_placeholders = rs_view-vsh_placeholders viewset_properties = rs_view-viewset_properties psmodilog = lt_psmodilog psmodisrc = lt_psmodisrc EXCEPTIONS not_existing = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from WDYV_GET_OBJECT'. ENDIF. READ TABLE lt_definition INDEX 1 ASSIGNING . ASSERT sy-subrc = 0. MOVE-CORRESPONDING TO rs_view-definition. CLEAR: rs_view-definition-author, rs_view-definition-createdon, rs_view-definition-changedby, rs_view-definition-changedon. ENDMETHOD. "read_view METHOD get_limu_objects. DATA: lv_name TYPE wdy_component_name. lv_name = ms_item-obj_name. CALL FUNCTION 'WDYN_GET_LIMU_OBJECTS' EXPORTING component_name = lv_name IMPORTING limu_objects = rt_objects. ENDMETHOD. "get_limu_objects METHOD read. DATA: lt_objects TYPE wdy_md_transport_keys, ls_controller_key TYPE wdy_md_controller_key, ls_component_key TYPE wdy_md_component_key, ls_view_key TYPE wdy_md_view_key. FIELD-SYMBOLS: LIKE LINE OF lt_objects. CLEAR mt_components. CLEAR mt_sources. lt_objects = get_limu_objects( ). LOOP AT lt_objects ASSIGNING . CASE -sub_type. WHEN wdyn_limu_component_controller. ls_controller_key = -sub_name. APPEND read_controller( ls_controller_key ) TO rs_component-ctlr_metadata. WHEN wdyn_limu_component_definition. ls_component_key = -sub_name. rs_component-comp_metadata = read_definition( ls_component_key ). WHEN wdyn_limu_component_view. ls_view_key = -sub_name. APPEND read_view( ls_view_key ) TO rs_component-view_metadata. WHEN OTHERS. ASSERT 0 = 1. ENDCASE. ENDLOOP. SORT rs_component-ctlr_metadata BY definition-component_name ASCENDING definition-controller_name ASCENDING. SORT mt_components BY component_name ASCENDING controller_name ASCENDING cmpname ASCENDING. SORT mt_sources BY component_name ASCENDING controller_name ASCENDING cmpname ASCENDING line_number ASCENDING. ENDMETHOD. "read METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_component TYPE wdy_component_metadata. ls_component = read( ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'COMPONENT' ig_data = ls_component ). lo_xml->add( ig_data = mt_components iv_name = 'COMPONENTS' ). lo_xml->add( ig_data = mt_sources iv_name = 'SOURCES' ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, ls_component TYPE wdy_component_metadata. FIELD-SYMBOLS: LIKE LINE OF ls_component-view_metadata, LIKE LINE OF ls_component-ctlr_metadata. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'COMPONENT' CHANGING cg_data = ls_component ). lo_xml->read( EXPORTING iv_name = 'COMPONENTS' CHANGING cg_data = mt_components ). lo_xml->read( EXPORTING iv_name = 'SOURCES' CHANGING cg_data = mt_sources ). ls_component-comp_metadata-definition-author = sy-uname. ls_component-comp_metadata-definition-createdon = sy-datum. recover_definition( ls_component-comp_metadata ). LOOP AT ls_component-ctlr_metadata ASSIGNING . -definition-author = sy-uname. -definition-createdon = sy-datum. recover_controller( ). ENDLOOP. LOOP AT ls_component-view_metadata ASSIGNING . -definition-author = sy-uname. -definition-createdon = sy-datum. recover_view( ). ENDLOOP. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lo_component TYPE REF TO cl_wdy_wb_component, lo_request TYPE REF TO cl_wb_request, li_state TYPE REF TO if_wb_program_state, lv_object_name TYPE seu_objkey. CREATE OBJECT lo_component. lv_object_name = ms_item-obj_name. CREATE OBJECT lo_request EXPORTING p_object_type = 'YC' p_object_name = lv_object_name p_operation = swbm_c_op_delete_no_dialog. lo_component->if_wb_program~process_wb_request( p_wb_request = lo_request p_wb_program_state = li_state ). ENDMETHOD. "delete METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = ms_item-obj_type in_new_window = abap_true. ENDMETHOD. "jump ENDCLASS. "lcl_object_wdyn IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_wdca DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_wdca DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. METHODS constructor IMPORTING is_item TYPE ty_item RAISING cx_sy_create_object_error. PRIVATE SECTION. METHODS read EXPORTING es_outline TYPE wdy_cfg_outline_data et_data TYPE wdy_cfg_persist_data_appl_tab RAISING lcx_exception. METHODS save IMPORTING is_outline TYPE wdy_cfg_outline_data it_data TYPE wdy_cfg_persist_data_appl_tab iv_package TYPE devclass RAISING lcx_exception. ENDCLASS. "lcl_object_wdca DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_wdca IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_wdca IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD constructor. super->constructor( is_item = is_item ). RAISE EXCEPTION TYPE cx_sy_create_object_error. * This serializer is currently not yet functional. * Prevent instantiation in order to enable handling of WDCA by plugins ENDMETHOD. METHOD lif_object~exists. DATA: ls_outline TYPE wdy_cfg_outline_data. read( IMPORTING es_outline = ls_outline ). rv_bool = boolc( NOT ls_outline IS INITIAL ). ENDMETHOD. METHOD save. _raise 'WDCA, save not implemented'. * below code are ideas, does not seem to work though * DATA: lo_cfg TYPE REF TO cl_wdr_cfg_persistence_appl, * ls_key TYPE wdy_config_key, * ls_data LIKE LINE OF it_data, * lv_operation TYPE i, * lv_name TYPE wdy_md_object_name. * * * MOVE-CORRESPONDING is_outline TO ls_key. * * TRY. * CREATE OBJECT lo_cfg * EXPORTING * config_key = ls_key * object_name = lv_name. * * READ TABLE it_data INDEX 1 INTO ls_data. * ASSERT sy-subrc = 0. * * lo_cfg->set_save_data( ls_data ). * * lv_operation = if_wdr_cfg_constants=>c_cts_operation-e_save. * lo_cfg->do_next_step( CHANGING c_operation = lv_operation ). * * CATCH cx_wd_configuration. * _raise 'WDCA, save error'. * ENDTRY. ENDMETHOD. "save METHOD read. DATA: lo_cfg TYPE REF TO cl_wdr_cfg_persistence_appl, ls_key TYPE wdy_config_key, lv_exists TYPE abap_bool, lx_err TYPE REF TO cx_wd_configuration, lv_name TYPE wdy_md_object_name. CLEAR et_data. ls_key = ms_item-obj_name. TRY. CREATE OBJECT lo_cfg EXPORTING config_key = ls_key object_name = lv_name. MOVE-CORRESPONDING ls_key TO es_outline. lo_cfg->check_config_existent( EXPORTING i_outline_data = es_outline i_only_current_layer = abap_false i_is_original = abap_true IMPORTING e_is_existent = lv_exists ). IF lv_exists = abap_false. CLEAR es_outline. RETURN. ENDIF. es_outline = lo_cfg->read_outline_data( ). CATCH cx_wd_configuration INTO lx_err. IF lx_err->textid = cx_wd_configuration=>conf_config_not_exist. CLEAR es_outline. RETURN. ELSE. _raise 'WDCA, read error'. ENDIF. ENDTRY. CLEAR: es_outline-devclass, es_outline-author, es_outline-createdon, es_outline-changedby, es_outline-changedon. et_data = lo_cfg->read_data( ). ENDMETHOD. "read METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_outline TYPE wdy_cfg_outline_data, lt_data TYPE wdy_cfg_persist_data_appl_tab. read( IMPORTING es_outline = ls_outline et_data = lt_data ). IF ls_outline IS INITIAL. RETURN. ENDIF. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'OUTLINE' ig_data = ls_outline ). lo_xml->add( iv_name = 'DATA' ig_data = lt_data ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, ls_outline TYPE wdy_cfg_outline_data, lt_data TYPE wdy_cfg_persist_data_appl_tab. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'OUTLINE' CHANGING cg_data = ls_outline ). lo_xml->read( EXPORTING iv_name = 'DATA' CHANGING cg_data = lt_data ). save( is_outline = ls_outline it_data = lt_data iv_package = iv_package ). ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: ls_key TYPE wdy_config_key. ls_key = ms_item-obj_name. cl_wdr_configuration_utils=>delete_config_4_appl( ls_key ). ENDMETHOD. "delete METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = ms_item-obj_type in_new_window = abap_true. ENDMETHOD. "jump ENDCLASS. "lcl_object_wdca IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_wdya DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_wdya DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS read EXPORTING es_app TYPE wdy_application et_properties TYPE wdy_app_property_table RAISING lcx_exception. METHODS save IMPORTING is_app TYPE wdy_application it_properties TYPE wdy_app_property_table iv_package TYPE devclass RAISING lcx_exception. ENDCLASS. "lcl_object_wdya DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_wdya IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_wdya IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_name TYPE wdy_application_name. lv_name = ms_item-obj_name. TRY. cl_wdy_md_application=>get_object_by_key( name = lv_name version = 'A' ). rv_bool = abap_true. CATCH cx_wdy_md_not_existing. rv_bool = abap_false. CATCH cx_wdy_md_permission_failure. _raise 'WDYA, permission failure'. ENDTRY. ENDMETHOD. METHOD read. DATA: li_app TYPE REF TO if_wdy_md_application, li_map TYPE REF TO if_object_map, lo_prop TYPE REF TO cl_wdy_md_application_property, ls_prop LIKE LINE OF et_properties, lv_name TYPE wdy_application_name. CLEAR es_app. CLEAR et_properties. lv_name = ms_item-obj_name. TRY. li_app = cl_wdy_md_application=>get_object_by_key( name = lv_name version = 'A' ). CATCH cx_wdy_md_not_existing. RETURN. CATCH cx_wdy_md_permission_failure. _raise 'WDYA, permission failure'. ENDTRY. li_app->if_wdy_md_object~get_definition( IMPORTING definition = es_app ). CLEAR: es_app-author, es_app-createdon, es_app-changedby, es_app-changedon. li_map = li_app->get_properties( ). DO li_map->size( ) TIMES. lo_prop ?= li_map->get_by_position( sy-index ). lo_prop->get_definition( IMPORTING definition = ls_prop ). APPEND ls_prop TO et_properties. ENDDO. ENDMETHOD. "read METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_app TYPE wdy_application, lt_properties TYPE wdy_app_property_table. read( IMPORTING es_app = ls_app et_properties = lt_properties ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'APP' ig_data = ls_app ). lo_xml->add( iv_name = 'PROPERTIES' ig_data = lt_properties ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD save. DATA: li_prop TYPE REF TO if_wdy_md_application_property, lo_app TYPE REF TO cl_wdy_md_application. FIELD-SYMBOLS: LIKE LINE OF it_properties. TRY. CREATE OBJECT lo_app EXPORTING name = is_app-application_name definition = is_app devclass = iv_package. LOOP AT it_properties ASSIGNING . li_prop = lo_app->if_wdy_md_application~create_property( -name ). li_prop->set_value( -value ). ENDLOOP. lo_app->if_wdy_md_lockable_object~save_to_database( ). CATCH cx_wdy_md_exception. _raise 'error saving WDYA'. ENDTRY. ENDMETHOD. "save METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, ls_app TYPE wdy_application, lt_properties TYPE wdy_app_property_table. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'APP' CHANGING cg_data = ls_app ). lo_xml->read( EXPORTING iv_name = 'PROPERTIES' CHANGING cg_data = lt_properties ). save( is_app = ls_app it_properties = lt_properties iv_package = iv_package ). ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: li_app TYPE REF TO if_wdy_md_application, lv_objkey TYPE wdy_wb_appl_name, lv_type TYPE seu_type, lv_name TYPE wdy_application_name. lv_name = ms_item-obj_name. TRY. li_app = cl_wdy_md_application=>get_object_by_key( name = lv_name version = 'A' ). li_app->if_wdy_md_object~delete( ). li_app->if_wdy_md_lockable_object~save_to_database( ). * method save_to_database calls function module TR_TADIR_INTERFACE * with test mode = X, so it does not delete the TADIR entry. * Instead the standard code uses RS_TREE_OBJECT_PLACEMENT to delete * the TADIR entry lv_objkey = ms_item-obj_name. CONCATENATE 'O' swbm_c_type_wdy_application INTO lv_type. CALL FUNCTION 'RS_TREE_OBJECT_PLACEMENT' EXPORTING object = lv_objkey type = lv_type operation = 'DELETE'. CATCH cx_wdy_md_not_existing. RETURN. CATCH cx_wdy_md_exception. _raise 'WDYA, error deleting'. ENDTRY. ENDMETHOD. "delete METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = ms_item-obj_type in_new_window = abap_true. ENDMETHOD. "jump ENDCLASS. "lcl_object_wdya IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_susc DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_susc DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_susc DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_suso IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_suso IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_objct TYPE tobj-objct. SELECT SINGLE objct FROM tobj INTO lv_objct WHERE objct = ms_item-obj_name. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_tobj TYPE tobj, ls_tobjt TYPE tobjt, ls_tobjvorflg TYPE tobjvorflg, lt_tactz TYPE TABLE OF tactz, lt_tobjvordat TYPE TABLE OF tobjvordat, lt_tobjvor TYPE TABLE OF tobjvor. SELECT SINGLE * FROM tobj INTO ls_tobj WHERE objct = ms_item-obj_name. IF sy-subrc <> 0. RETURN. ENDIF. CLEAR ls_tobj-bname. SELECT SINGLE * FROM tobjt INTO ls_tobjt WHERE object = ms_item-obj_name AND langu = gc_english. "#EC CI_GENBUFF IF sy-subrc <> 0. _raise 'TOBJT no english description'. ENDIF. SELECT SINGLE * FROM tobjvorflg INTO ls_tobjvorflg WHERE objct = ms_item-obj_name. "#EC CI_SUBRC SELECT * FROM tactz INTO TABLE lt_tactz WHERE brobj = ms_item-obj_name ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF SELECT * FROM tobjvordat INTO TABLE lt_tobjvordat WHERE objct = ms_item-obj_name ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF SELECT * FROM tobjvor INTO TABLE lt_tobjvor WHERE objct = ms_item-obj_name ORDER BY PRIMARY KEY. "#EC CI_SUBRC CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'TOBJ' ig_data = ls_tobj ). lo_xml->add( iv_name = 'TOBJT' ig_data = ls_tobjt ). lo_xml->add( iv_name = 'TOBJVORFLG' ig_data = ls_tobjvorflg ). lo_xml->add( ig_data = lt_tactz iv_name = 'TACTZ' ). lo_xml->add( ig_data = lt_tobjvordat iv_name = 'TOBJVORDAT' ). lo_xml->add( ig_data = lt_tobjvor iv_name = 'TOBJVOR' ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. * see function group SUSA DATA: lo_xml TYPE REF TO lcl_xml_input, lv_objectname TYPE e071-obj_name, ls_tobj TYPE tobj, ls_tobjt TYPE tobjt, ls_tobjvorflg TYPE tobjvorflg, lt_tactz TYPE TABLE OF tactz, lt_tobjvordat TYPE TABLE OF tobjvordat, lt_tobjvor TYPE TABLE OF tobjvor. ASSERT NOT ms_item-obj_name IS INITIAL. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'TOBJ' CHANGING cg_data = ls_tobj ). ls_tobj-bname = sy-uname. lo_xml->read( EXPORTING iv_name = 'TOBJT' CHANGING cg_data = ls_tobjt ). lo_xml->read( EXPORTING iv_name = 'TOBJVORFLG' CHANGING cg_data = ls_tobjvorflg ). lo_xml->read( EXPORTING iv_name = 'TACTZ' CHANGING cg_data = lt_tactz ). lo_xml->read( EXPORTING iv_name = 'TOBJVORDAT' CHANGING cg_data = lt_tobjvordat ). lo_xml->read( EXPORTING iv_name = 'TOBJVOR' CHANGING cg_data = lt_tobjvor ). lv_objectname = ms_item-obj_name. CALL FUNCTION 'SUSR_COMMEDITCHECK' EXPORTING objectname = lv_objectname transobjecttype = 'O'. MODIFY tobj FROM ls_tobj. "#EC CI_SUBRC MODIFY tobjt FROM ls_tobjt. "#EC CI_SUBRC MODIFY tobjvorflg FROM ls_tobjvorflg. "#EC CI_SUBRC DELETE FROM tactz WHERE brobj = ms_item-obj_name. "#EC CI_SUBRC INSERT tactz FROM TABLE lt_tactz. "#EC CI_SUBRC DELETE FROM tobjvordat WHERE objct = ms_item-obj_name. "#EC CI_SUBRC INSERT tobjvordat FROM TABLE lt_tobjvordat. "#EC CI_SUBRC DELETE FROM tobjvor WHERE objct = ms_item-obj_name. "#EC CI_SUBRC INSERT tobjvor FROM TABLE lt_tobjvor. "#EC CI_SUBRC ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lv_object TYPE tobj-objct. lv_object = ms_item-obj_name. CALL FUNCTION 'SUSR_DELETE_OBJECT' EXPORTING object = lv_object. ENDMETHOD. "delete METHOD lif_object~jump. DATA: lv_object TYPE tobj-objct. lv_object = ms_item-obj_name. CALL FUNCTION 'SUSR_SHOW_OBJECT' EXPORTING object = lv_object. ENDMETHOD. "jump ENDCLASS. "lcl_object_suso IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_susc IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_susc IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_oclss TYPE tobc-oclss. SELECT SINGLE oclss FROM tobc INTO lv_oclss WHERE oclss = ms_item-obj_name. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_tobc TYPE tobc, ls_tobct TYPE tobct. SELECT SINGLE * FROM tobc INTO ls_tobc WHERE oclss = ms_item-obj_name. IF sy-subrc <> 0. RETURN. ENDIF. SELECT SINGLE * FROM tobct INTO ls_tobct WHERE oclss = ms_item-obj_name AND langu = gc_english. IF sy-subrc <> 0. _raise 'TOBCT no english description'. ENDIF. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'TOBC' ig_data = ls_tobc ). lo_xml->add( iv_name = 'TOBCT' ig_data = ls_tobct ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. * see function group SUSA DATA: lo_xml TYPE REF TO lcl_xml_input, ls_tobc TYPE tobc, lv_objectname TYPE e071-obj_name, ls_tobct TYPE tobct. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'TOBC' CHANGING cg_data = ls_tobc ). lo_xml->read( EXPORTING iv_name = 'TOBCT' CHANGING cg_data = ls_tobct ). lv_objectname = ms_item-obj_name. CALL FUNCTION 'SUSR_COMMEDITCHECK' EXPORTING objectname = lv_objectname transobjecttype = 'C'. INSERT tobc FROM ls_tobc. "#EC CI_SUBRC * ignore sy-subrc as all fields are key fields MODIFY tobct FROM ls_tobct. "#EC CI_SUBRC ASSERT sy-subrc = 0. ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lv_objclass TYPE tobc-oclss. lv_objclass = ms_item-obj_name. CALL FUNCTION 'SUSR_DELETE_OBJECT_CLASS' EXPORTING objclass = lv_objclass. ENDMETHOD. "delete METHOD lif_object~jump. DATA: lv_objclass TYPE tobc-oclss. lv_objclass = ms_item-obj_name. CALL FUNCTION 'SUSR_SHOW_OBJECT_CLASS' EXPORTING objclass = lv_objclass. ENDMETHOD. "jump ENDCLASS. "lcl_object_susc IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_type DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_type DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS read EXPORTING ev_ddtext TYPE ddtypet-ddtext et_source TYPE abaptxt255_tab RAISING lcx_exception lcx_not_found. METHODS create IMPORTING iv_ddtext TYPE ddtypet-ddtext it_source TYPE abaptxt255_tab iv_devclass TYPE devclass RAISING lcx_exception. ENDCLASS. "lcl_object_type DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_type IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_type IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. TRY. read( ). rv_bool = abap_true. CATCH lcx_not_found. rv_bool = abap_false. ENDTRY. ENDMETHOD. METHOD read. DATA: lv_typdname TYPE rsedd0-typegroup, lt_psmodisrc TYPE TABLE OF smodisrc, lt_psmodilog TYPE TABLE OF smodilog, lt_ptrdir TYPE TABLE OF trdir. SELECT SINGLE ddtext FROM ddtypet INTO ev_ddtext WHERE typegroup = ms_item-obj_name AND ddlanguage = gc_english. IF sy-subrc <> 0. RAISE EXCEPTION TYPE lcx_not_found. ENDIF. lv_typdname = ms_item-obj_name. CALL FUNCTION 'TYPD_GET_OBJECT' EXPORTING typdname = lv_typdname TABLES psmodisrc = lt_psmodisrc psmodilog = lt_psmodilog psource = et_source ptrdir = lt_ptrdir EXCEPTIONS version_not_found = 1 reps_not_exist = 2 OTHERS = 3. IF sy-subrc <> 0. _raise 'error from TYPD_GET_OBJECT'. ENDIF. ENDMETHOD. "read METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, lv_ddtext TYPE ddtypet-ddtext, lt_source TYPE abaptxt255_tab. TRY. read( IMPORTING ev_ddtext = lv_ddtext et_source = lt_source ). CATCH lcx_not_found. RETURN. ENDTRY. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DDTEXT' ig_data = lv_ddtext ). mo_files->add_xml( lo_xml ). mo_files->add_abap( lt_source ). ENDMETHOD. "serialize METHOD create. DATA: lv_progname TYPE reposrc-progname, lv_typegroup TYPE rsedd0-typegroup. lv_typegroup = ms_item-obj_name. CALL FUNCTION 'RS_DD_TYGR_INSERT_SOURCES' EXPORTING typegroupname = lv_typegroup ddtext = iv_ddtext corrnum = '' devclass = iv_devclass TABLES source = it_source EXCEPTIONS already_exists = 1 not_executed = 2 permission_failure = 3 object_not_specified = 4 illegal_name = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from RS_DD_TYGR_INSERT_SOURCES'. ENDIF. CONCATENATE '%_C' lv_typegroup INTO lv_progname. UPDATE progdir SET uccheck = abap_true WHERE name = lv_progname. IF sy-subrc <> 0. _raise 'error setting uccheck'. ENDIF. ENDMETHOD. "create METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_ddtext TYPE ddtypet-ddtext, lt_source TYPE abaptxt255_tab. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DDTEXT' CHANGING cg_data = lv_ddtext ). lt_source = mo_files->read_abap( ). create( iv_ddtext = lv_ddtext it_source = lt_source iv_devclass = iv_package ). lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_true objname = lv_objname objtype = 'G' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4 dialog_needed = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error deleting TYPE'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. jump_se11( iv_radio = 'RSRD1-TYMA' iv_field = 'RSRD1-TYMA_VAL' ). ENDMETHOD. "jump ENDCLASS. "lcl_object_type IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_para DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_para DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_para DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_para IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_para IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_paramid TYPE tpara-paramid. SELECT SINGLE paramid FROM tpara INTO lv_paramid WHERE paramid = ms_item-obj_name. "#EC CI_GENBUFF rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_tpara TYPE tpara, ls_tparat TYPE tparat. SELECT SINGLE * FROM tpara INTO ls_tpara WHERE paramid = ms_item-obj_name. "#EC CI_GENBUFF IF sy-subrc <> 0. RETURN. ENDIF. SELECT SINGLE * FROM tparat INTO ls_tparat WHERE paramid = ms_item-obj_name AND sprache = gc_english. "#EC CI_GENBUFF IF sy-subrc <> 0. _raise 'PARA no english description'. ENDIF. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'TPARA' ig_data = ls_tpara ). lo_xml->add( iv_name = 'TPARAT' ig_data = ls_tparat ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. * see fm RS_PARAMETER_ADD and RS_PARAMETER_EDIT DATA: lo_xml TYPE REF TO lcl_xml_input, lv_mode TYPE c LENGTH 1, ls_tpara TYPE tpara, ls_tparat TYPE tparat. SELECT SINGLE * FROM tpara INTO ls_tpara WHERE paramid = ms_item-obj_name. "#EC CI_GENBUFF IF sy-subrc = 0. lv_mode = 'M'. ELSE. lv_mode = 'I'. ENDIF. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'TPARA' CHANGING cg_data = ls_tpara ). lo_xml->read( EXPORTING iv_name = 'TPARAT' CHANGING cg_data = ls_tparat ). CALL FUNCTION 'RS_CORR_INSERT' EXPORTING object = ms_item-obj_name object_class = 'PARA' mode = lv_mode global_lock = abap_true devclass = iv_package master_language = gc_english EXCEPTIONS cancelled = 1 permission_failure = 2 unknown_objectclass = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'error from RS_CORR_INSERT, PARA'. ENDIF. MODIFY tpara FROM ls_tpara. "#EC CI_SUBRC ASSERT sy-subrc = 0. MODIFY tparat FROM ls_tparat. "#EC CI_SUBRC ASSERT sy-subrc = 0. ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lv_paramid TYPE tpara-paramid. lv_paramid = ms_item-obj_name. CALL FUNCTION 'RS_PARAMETER_DELETE' EXPORTING objectname = lv_paramid EXCEPTIONS cancelled = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from RS_PRAMETER_DELETE'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = 'PARA' in_new_window = abap_true. ENDMETHOD. "jump ENDCLASS. "lcl_object_para IMPLEMENTATION CLASS lcl_object_splo DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. CLASS lcl_object_splo IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, ls_tsp1t TYPE tsp1t, ls_tsp1d TYPE tsp1d, ls_tsp0p TYPE tsp0p. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. SELECT SINGLE * FROM tsp1t INTO ls_tsp1t WHERE papart = ms_item-obj_name AND spras = gc_english. "#EC CI_GENBUFF "#EC CI_SUBRC SELECT SINGLE * FROM tsp1d INTO ls_tsp1d WHERE papart = ms_item-obj_name. "#EC CI_SUBRC SELECT SINGLE * FROM tsp0p INTO ls_tsp0p WHERE pdpaper = ms_item-obj_name. "#EC CI_SUBRC CLEAR: ls_tsp1d-chgname1, ls_tsp1d-chgtstmp1, ls_tsp1d-chgsaprel1, ls_tsp1d-chgsapsys1. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'TSPLT' ig_data = ls_tsp1t ). lo_xml->add( iv_name = 'TSPLD' ig_data = ls_tsp1d ). lo_xml->add( iv_name = 'TSP0P' ig_data = ls_tsp0p ). mo_files->add_xml( lo_xml ). ENDMETHOD. METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_obj_name TYPE e071-obj_name, ls_tsp1t TYPE tsp1t, ls_tsp1d TYPE tsp1d, ls_tsp0p TYPE tsp0p. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'TSPLT' CHANGING cg_data = ls_tsp1t ). lo_xml->read( EXPORTING iv_name = 'TSPLD' CHANGING cg_data = ls_tsp1d ). lo_xml->read( EXPORTING iv_name = 'TSP0P' CHANGING cg_data = ls_tsp0p ). MODIFY tsp1t FROM ls_tsp1t. "#EC CI_SUBRC MODIFY tsp1d FROM ls_tsp1d. "#EC CI_SUBRC MODIFY tsp0p FROM ls_tsp0p. "#EC CI_SUBRC lv_obj_name = ms_item-obj_name. CALL FUNCTION 'TR_TADIR_POPUP_ENTRY_E071' EXPORTING wi_e071_pgmid = 'R3TR' wi_e071_object = ms_item-obj_type wi_e071_obj_name = lv_obj_name wi_tadir_devclass = iv_package. ENDMETHOD. METHOD lif_object~delete. DELETE FROM tsp1t WHERE papart = ms_item-obj_name. "#EC CI_NOFIRST "#EC CI_SUBRC DELETE FROM tsp1d WHERE papart = ms_item-obj_name. "#EC CI_SUBRC DELETE FROM tsp0p WHERE pdpaper = ms_item-obj_name. "#EC CI_SUBRC CALL FUNCTION 'TR_TADIR_INTERFACE' EXPORTING wi_delete_tadir_entry = abap_true wi_tadir_pgmid = 'R3TR' wi_tadir_object = ms_item-obj_type wi_tadir_obj_name = ms_item-obj_name wi_test_modus = abap_false. ENDMETHOD. METHOD lif_object~exists. DATA: lv_papart TYPE tsp1d-papart. SELECT SINGLE papart INTO lv_papart FROM tsp1d WHERE papart = ms_item-obj_name. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. _raise 'todo, jump, SPLO'. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_object_ssfo DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_ssfo DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_ssfo IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_formname TYPE stxfadm-formname. SELECT SINGLE formname FROM stxfadm INTO lv_formname WHERE formname = ms_item-obj_name. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. DATA: lt_bdcdata TYPE TABLE OF bdcdata. FIELD-SYMBOLS: LIKE LINE OF lt_bdcdata. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -program = 'SAPMSSFO'. -dynpro = '0100'. -dynbegin = abap_true. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = 'BDC_OKCODE'. -fval = '=DISPLAY'. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = 'RB_SF'. -fval = abap_true. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = 'SSFSCREEN-FNAME'. -fval = ms_item-obj_name. CALL FUNCTION 'ABAP4_CALL_TRANSACTION' STARTING NEW TASK 'GIT' EXPORTING tcode = 'SMARTFORMS' mode_val = 'E' TABLES using_tab = lt_bdcdata EXCEPTIONS system_failure = 1 communication_failure = 2 resource_failure = 3 OTHERS = 4 ##fm_subrc_ok. "#EC CI_SUBRC ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_formname TYPE tdsfname. lv_formname = ms_item-obj_name. CALL FUNCTION 'FB_DELETE_FORM' EXPORTING i_formname = lv_formname i_with_dialog = abap_false i_with_confirm_dialog = abap_false EXCEPTIONS no_name = 1 no_form = 2 form_locked = 3 no_access_permission = 4 illegal_language = 5 illegal_formtype = 6 OTHERS = 7. IF sy-subrc <> 0 AND sy-subrc <> 2. _raise 'Error from FB_DELETE_FORM'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. * see function module FB_DOWNLOAD_FORM DATA: lo_sf TYPE REF TO cl_ssf_fb_smart_form, lo_output TYPE REF TO lcl_xml_output, lv_name TYPE string, li_node TYPE REF TO if_ixml_node, li_element TYPE REF TO if_ixml_element, li_iterator TYPE REF TO if_ixml_node_iterator, li_attr TYPE REF TO if_ixml_named_node_map, lv_formname TYPE tdsfname, li_ixml TYPE REF TO if_ixml, li_xml_doc TYPE REF TO if_ixml_document. li_ixml = cl_ixml=>create( ). li_xml_doc = li_ixml->create_document( ). CREATE OBJECT lo_sf. lv_formname = ms_item-obj_name. " convert type TRY. lo_sf->load( im_formname = lv_formname im_language = '' ). CATCH cx_ssf_fb. * the smartform is not present in system, or other error occured RETURN. ENDTRY. lo_sf->xml_download( EXPORTING parent = li_xml_doc CHANGING document = li_xml_doc ). li_iterator = li_xml_doc->create_iterator( ). li_node = li_iterator->get_next( ). WHILE NOT li_node IS INITIAL. lv_name = li_node->get_name( ). IF lv_name = 'DEVCLASS' OR lv_name = 'LASTDATE' OR lv_name = 'LASTTIME'. li_node->set_value( '' ). ENDIF. IF lv_name = 'FIRSTUSER' OR lv_name = 'LASTUSER'. li_node->set_value( 'DUMMY' ). ENDIF. * remove IDs it seems that they are not used for anything * the IDs are "random" so it caused diff files IF lv_name = 'NODE' OR lv_name = 'WINDOW'. li_attr = li_node->get_attributes( ). li_attr->remove_named_item( 'ID' ). ENDIF. li_node = li_iterator->get_next( ). ENDWHILE. li_element = li_xml_doc->get_root_element( ). li_element->set_attribute( name = 'sf' namespace = 'xmlns' value = 'urn:sap-com:SmartForms:2000:internal-structure' ). "#EC NOTEXT li_element->set_attribute( name = 'xmlns' value = 'urn:sap-com:sdixml-ifr:2000' ). "#EC NOTEXT * the upload fails when the smartform is normalized CREATE OBJECT lo_output. lo_output->set_raw( li_xml_doc->get_root_element( ) ). mo_files->add_xml( io_xml = lo_output iv_normalize = abap_false ). ENDMETHOD. "serialize METHOD lif_object~deserialize. * see function module FB_UPLOAD_FORM DATA: lo_input TYPE REF TO lcl_xml_input, li_node TYPE REF TO if_ixml_node, lv_formname TYPE tdsfname, lv_name TYPE string, li_iterator TYPE REF TO if_ixml_node_iterator, lo_sf TYPE REF TO cl_ssf_fb_smart_form, lo_res TYPE REF TO cl_ssf_fb_smart_form. CREATE OBJECT lo_sf. lo_input = mo_files->read_xml( ). * set "created by" and "changed by" to current user li_iterator = lo_input->get_raw( )->create_iterator( ). li_node = li_iterator->get_next( ). WHILE NOT li_node IS INITIAL. lv_name = li_node->get_name( ). CASE lv_name. WHEN 'LASTDATE'. li_node->set_value( sy-datum(4) && '-' && sy-datum+4(2) && '-' && sy-datum+6(2) ). WHEN 'LASTTIME'. li_node->set_value( sy-uzeit(2) && ':' && sy-uzeit+2(2) && ':' && sy-uzeit+4(2) ). WHEN 'FIRSTUSER' OR 'LASTUSER'. li_node->set_value( sy-uname && '' ). ENDCASE. li_node = li_iterator->get_next( ). ENDWHILE. * todo, iv_package? lv_formname = ms_item-obj_name. lo_sf->enqueue( suppress_corr_check = space master_language = gc_english mode = 'INSERT' formname = lv_formname ). lo_sf->xml_upload( EXPORTING dom = lo_input->get_raw( ) formname = lv_formname language = gc_english CHANGING sform = lo_res ). lo_res->store( im_formname = lo_res->header-formname im_language = gc_english im_active = abap_true ). lo_sf->dequeue( lv_formname ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_ssfo IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_tabl DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_tabl IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_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 lif_object~jump. jump_se11( iv_radio = 'RSRD1-DDTYPE' iv_field = 'RSRD1-DDTYPE_VAL' ). ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_false objname = lv_objname objtype = 'T' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. _raise 'error from RS_DD_DELETE_OBJ, TABL'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. DATA: lv_name TYPE ddobjname, lo_xml TYPE REF TO lcl_xml_output, 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, lt_dd35v TYPE TABLE OF dd35v, lt_dd36m TYPE dd36mttyp. FIELD-SYMBOLS: LIKE LINE OF lt_dd12v, LIKE LINE OF lt_dd03p. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_TABL_GET' EXPORTING name = lv_name langu = gc_english 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. _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. CLEAR: ls_dd09l-as4user, ls_dd09l-as4date, ls_dd09l-as4time. LOOP AT lt_dd12v ASSIGNING . CLEAR: -as4user, -as4date, -as4time. ENDLOOP. LOOP AT lt_dd03p ASSIGNING WHERE NOT rollname IS INITIAL. CLEAR: -ddlanguage, -dtelmaster, -ddtext, -reptext, -scrtext_s, -scrtext_m, -scrtext_l. ENDLOOP. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DD02V' ig_data = ls_dd02v ). lo_xml->add( iv_name = 'DD09L' ig_data = ls_dd09l ). lo_xml->add( ig_data = lt_dd03p iv_name = 'DD03P_TABLE' ). lo_xml->add( ig_data = lt_dd05m iv_name = 'DD05M_TABLE' ). lo_xml->add( ig_data = lt_dd08v iv_name = 'DD08V_TABLE' ). lo_xml->add( iv_name = 'DD12V' ig_data = lt_dd12v ). lo_xml->add( iv_name = 'DD17V' ig_data = lt_dd17v ). lo_xml->add( ig_data = lt_dd35v iv_name = 'DD35V_TALE' ). lo_xml->add( iv_name = 'DD36M' ig_data = lt_dd36m ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lv_name TYPE ddobjname, lv_tname TYPE trobj_name, lo_xml TYPE REF TO lcl_xml_input, 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. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DD02V' CHANGING cg_data = ls_dd02v ). lo_xml->read( EXPORTING iv_name = 'DD09L' CHANGING cg_data = ls_dd09l ). lo_xml->read( EXPORTING iv_name = 'DD03P_TABLE' CHANGING cg_data = lt_dd03p ). lo_xml->read( EXPORTING iv_name = 'DD05M_TABLE' CHANGING cg_data = lt_dd05m ). lo_xml->read( EXPORTING iv_name = 'DD08V_TABLE' CHANGING cg_data = lt_dd08v ). lo_xml->read( EXPORTING iv_name = 'DD12V' CHANGING cg_data = lt_dd12v ). lo_xml->read( EXPORTING iv_name = 'DD17V' CHANGING cg_data = lt_dd17v ). lo_xml->read( EXPORTING iv_name = 'DD35V_TALE' CHANGING cg_data = lt_dd35v ). lo_xml->read( EXPORTING iv_name = 'DD36M' CHANGING cg_data = lt_dd36m ). corr_insert( iv_package ). 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. _raise 'error from DDIF_TABL_PUT'. ENDIF. lcl_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. _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. lcl_objects_activation=>add( iv_type = 'INDX' iv_name = lv_tname ). ENDLOOP. ENDMETHOD. "deserialize ENDCLASS. "lcl_object_TABL IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_enho DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_enho DEFINITION INHERITING FROM lcl_objects_super FINAL. * For complete list of tool_type - see ENHTOOLS table PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS deserialize_badi IMPORTING io_xml TYPE REF TO lcl_xml_input iv_package TYPE devclass RAISING lcx_exception. METHODS deserialize_hook IMPORTING io_xml TYPE REF TO lcl_xml_input iv_package TYPE devclass RAISING lcx_exception. METHODS serialize_badi IMPORTING iv_tool TYPE enhtooltype ii_enh_tool TYPE REF TO if_enh_tool RAISING lcx_exception. METHODS serialize_hook IMPORTING iv_tool TYPE enhtooltype ii_enh_tool TYPE REF TO if_enh_tool RAISING lcx_exception. ENDCLASS. "lcl_object_enho DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_enho IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_enho IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: ls_tadir TYPE tadir. * todo, it should look up in the ENHO database tables or call some methods * to see if the object exists, looking in TADIR will not work ls_tadir = lcl_tadir=>read_single( iv_object = ms_item-obj_type iv_obj_name = ms_item-obj_name ). IF ls_tadir IS NOT INITIAL. rv_bool = abap_true. ENDIF. ENDMETHOD. METHOD lif_object~serialize. DATA: lv_enh_id TYPE enhname, lv_tool TYPE enhtooltype, li_enh_tool TYPE REF TO if_enh_tool. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. lv_enh_id = ms_item-obj_name. TRY. li_enh_tool = cl_enh_factory=>get_enhancement( lv_enh_id ). CATCH cx_enh_root. _raise 'Error from CL_ENH_FACTORY'. ENDTRY. lv_tool = li_enh_tool->get_tool( ). CASE lv_tool. WHEN cl_enh_tool_badi_impl=>tooltype. serialize_badi( iv_tool = lv_tool ii_enh_tool = li_enh_tool ). WHEN cl_enh_tool_hook_impl=>tooltype. serialize_hook( iv_tool = lv_tool ii_enh_tool = li_enh_tool ). * ToDo: * WHEN cl_enh_tool_class=>tooltype. * WHEN 'ENHFUGRDATA'. "cl_enh_tool_fugr * WHEN cl_enh_tool_intf=>tooltype. * WHEN cl_wdr_cfg_enhancement=>tooltype. * WHEN 'ENHWDYN'. "cl_enh_tool_wdy WHEN OTHERS. _raise 'Unsupported ENHO type'. ENDCASE. ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_tool TYPE enhtooltype. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'TOOL' CHANGING cg_data = lv_tool ). CASE lv_tool. WHEN cl_enh_tool_badi_impl=>tooltype. deserialize_badi( io_xml = lo_xml iv_package = iv_package ). WHEN cl_enh_tool_hook_impl=>tooltype. deserialize_hook( io_xml = lo_xml iv_package = iv_package ). * ToDo: * WHEN cl_enh_tool_class=>tooltype. * WHEN 'ENHFUGRDATA'. "cl_enh_tool_fugr * WHEN cl_enh_tool_intf=>tooltype. * WHEN cl_wdr_cfg_enhancement=>tooltype. * WHEN 'ENHWDYN'. "cl_enh_tool_wdy WHEN OTHERS. _raise 'Unsupported ENHO type'. ENDCASE. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize METHOD deserialize_badi. DATA: lv_spot_name TYPE enhspotname, lv_shorttext TYPE string, lv_enhname TYPE enhname, lo_badi TYPE REF TO cl_enh_tool_badi_impl, li_tool TYPE REF TO if_enh_tool, lv_package TYPE devclass, lt_impl TYPE enh_badi_impl_data_it. FIELD-SYMBOLS: LIKE LINE OF lt_impl. io_xml->read( EXPORTING iv_name = 'SHORTTEXT' CHANGING cg_data = lv_shorttext ). io_xml->read( EXPORTING iv_name = 'SPOT_NAME' CHANGING cg_data = lv_spot_name ). io_xml->read( EXPORTING iv_name = 'IMPL' CHANGING cg_data = lt_impl ). lv_enhname = ms_item-obj_name. lv_package = iv_package. TRY. cl_enh_factory=>create_enhancement( EXPORTING enhname = lv_enhname enhtype = cl_abstract_enh_tool_redef=>credefinition enhtooltype = cl_enh_tool_badi_impl=>tooltype IMPORTING enhancement = li_tool CHANGING devclass = lv_package ). lo_badi ?= li_tool. lo_badi->set_spot_name( lv_spot_name ). lo_badi->if_enh_object_docu~set_shorttext( lv_shorttext ). LOOP AT lt_impl ASSIGNING . lo_badi->add_implementation( ). ENDLOOP. lo_badi->if_enh_object~save( ). lo_badi->if_enh_object~unlock( ). CATCH cx_enh_root. _raise 'error deserializing ENHO badi'. ENDTRY. ENDMETHOD. "deserialize_badi METHOD deserialize_hook. DATA: lv_shorttext TYPE string, lo_hook_impl TYPE REF TO cl_enh_tool_hook_impl, li_tool TYPE REF TO if_enh_tool, lv_enhname TYPE enhname, lv_package TYPE devclass, ls_original_object TYPE enh_hook_admin, lt_enhancements TYPE enh_hook_impl_it. FIELD-SYMBOLS: LIKE LINE OF lt_enhancements. io_xml->read( EXPORTING iv_name = 'SHORTTEXT' CHANGING cg_data = lv_shorttext ). io_xml->read( EXPORTING iv_name = 'ORIGINAL_OBJECT' CHANGING cg_data = ls_original_object ). io_xml->read( EXPORTING iv_name = 'ENHANCEMENTS' CHANGING cg_data = lt_enhancements ). lv_enhname = ms_item-obj_name. lv_package = iv_package. TRY. cl_enh_factory=>create_enhancement( EXPORTING enhname = lv_enhname enhtype = cl_abstract_enh_tool_redef=>credefinition enhtooltype = cl_enh_tool_hook_impl=>tooltype IMPORTING enhancement = li_tool CHANGING devclass = lv_package ). lo_hook_impl ?= li_tool. lo_hook_impl->if_enh_object_docu~set_shorttext( lv_shorttext ). lo_hook_impl->set_original_object( pgmid = ls_original_object-pgmid obj_name = ls_original_object-org_obj_name obj_type = ls_original_object-org_obj_type program = ls_original_object-programname main_type = ls_original_object-org_main_type main_name = ls_original_object-org_main_name ). lo_hook_impl->set_include_bound( ls_original_object-include_bound ). LOOP AT lt_enhancements ASSIGNING . lo_hook_impl->add_hook_impl( overwrite = -overwrite method = -method enhmode = -enhmode full_name = -full_name source = -source spot = -spotname parent_full_name = -parent_full_name ). ENDLOOP. lo_hook_impl->if_enh_object~save( ). lo_hook_impl->if_enh_object~unlock( ). CATCH cx_enh_root. _raise 'error deserializing ENHO hook'. ENDTRY. ENDMETHOD. "deserialize_hook METHOD serialize_badi. DATA: lo_badi_impl TYPE REF TO cl_enh_tool_badi_impl, lv_spot_name TYPE enhspotname, lo_xml TYPE REF TO lcl_xml_output, lv_shorttext TYPE string, lt_impl TYPE enh_badi_impl_data_it. lo_badi_impl ?= ii_enh_tool. lv_shorttext = lo_badi_impl->if_enh_object_docu~get_shorttext( ). lv_spot_name = lo_badi_impl->get_spot_name( ). lt_impl = lo_badi_impl->get_implementations( ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'TOOL' ig_data = iv_tool ). lo_xml->add( ig_data = lv_shorttext iv_name = 'SHORTTEXT' ). lo_xml->add( iv_name = 'SPOT_NAME' ig_data = lv_spot_name ). lo_xml->add( iv_name = 'IMPL' ig_data = lt_impl ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize_badi METHOD serialize_hook. DATA: lv_shorttext TYPE string, lo_xml TYPE REF TO lcl_xml_output, lo_hook_impl TYPE REF TO cl_enh_tool_hook_impl, ls_original_object TYPE enh_hook_admin, lt_enhancements TYPE enh_hook_impl_it. lo_hook_impl ?= ii_enh_tool. lv_shorttext = lo_hook_impl->if_enh_object_docu~get_shorttext( ). lo_hook_impl->get_original_object( IMPORTING pgmid = ls_original_object-pgmid obj_name = ls_original_object-org_obj_name obj_type = ls_original_object-org_obj_type main_type = ls_original_object-org_main_type main_name = ls_original_object-org_main_name program = ls_original_object-programname ). ls_original_object-include_bound = lo_hook_impl->get_include_bound( ). lt_enhancements = lo_hook_impl->get_hook_impls( ). CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'TOOL' ig_data = iv_tool ). lo_xml->add( ig_data = lv_shorttext iv_name = 'SHORTTEXT' ). lo_xml->add( ig_data = ls_original_object iv_name = 'ORIGINAL_OBJECT' ). lo_xml->add( iv_name = 'ENHANCEMENTS' ig_data = lt_enhancements ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize_hook METHOD lif_object~delete. DATA: lv_enh_id TYPE enhname, li_enh_object TYPE REF TO if_enh_object. lv_enh_id = ms_item-obj_name. TRY. li_enh_object = cl_enh_factory=>get_enhancement( enhancement_id = lv_enh_id lock = abap_true ). li_enh_object->delete( ). li_enh_object->save( ). li_enh_object->unlock( ). CATCH cx_enh_root. _raise 'Error deleting ENHO'. ENDTRY. ENDMETHOD. "delete METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = 'ENHO' in_new_window = abap_true. ENDMETHOD. "jump ENDCLASS. "lcl_object_enho IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_enqu DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_enqu DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_enqu IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_viewname TYPE dd25l-viewname. SELECT SINGLE viewname FROM dd25l INTO lv_viewname WHERE viewname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. jump_se11( iv_radio = 'RSRD1-ENQU' iv_field = 'RSRD1-ENQU_VAL' ). ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_true objname = lv_objname objtype = 'L' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. _raise 'error from RS_DD_DELETE_OBJ, ENQU'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. DATA: lv_name TYPE ddobjname, lo_xml TYPE REF TO lcl_xml_output, ls_dd25v TYPE dd25v, lt_dd26e TYPE TABLE OF dd26e, lt_dd27p TYPE TABLE OF dd27p. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_ENQU_GET' EXPORTING name = lv_name state = 'A' langu = gc_english IMPORTING dd25v_wa = ls_dd25v TABLES dd26e_tab = lt_dd26e dd27p_tab = lt_dd27p EXCEPTIONS illegal_input = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from DDIF_ENQU_GET'. ENDIF. IF ls_dd25v IS INITIAL. RETURN. " does not exist in system ENDIF. CLEAR: ls_dd25v-as4user, ls_dd25v-as4date, ls_dd25v-as4time. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DD25V' ig_data = ls_dd25v ). lo_xml->add( ig_data = lt_dd26e iv_name = 'DD26E_TABLE' ). lo_xml->add( ig_data = lt_dd27p iv_name = 'DD27P_TABLE' ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_name TYPE ddobjname, ls_dd25v TYPE dd25v, lt_dd26e TYPE TABLE OF dd26e, lt_dd27p TYPE TABLE OF dd27p. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DD25V' CHANGING cg_data = ls_dd25v ). lo_xml->read( EXPORTING iv_name = 'DD26E_TABLE' CHANGING cg_data = lt_dd26e ). lo_xml->read( EXPORTING iv_name = 'DD27P_TABLE' CHANGING cg_data = lt_dd27p ). corr_insert( iv_package ). lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_ENQU_PUT' EXPORTING name = lv_name dd25v_wa = ls_dd25v TABLES dd26e_tab = lt_dd26e dd27p_tab = lt_dd27p EXCEPTIONS enqu_not_found = 1 name_inconsistent = 2 enqu_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from DDIF_ENQU_PUT'. ENDIF. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_enqu IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_shlp DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_shlp DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_shlp IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_shlpname TYPE dd30l-shlpname. SELECT SINGLE shlpname FROM dd30l INTO lv_shlpname WHERE shlpname = ms_item-obj_name AND as4local = 'A'. "#EC CI_GENBUFF rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. jump_se11( iv_radio = 'RSRD1-SHMA' iv_field = 'RSRD1-SHMA_VAL' ). ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_true objname = lv_objname objtype = 'H' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. _raise 'error from RS_DD_DELETE_OBJ, SHLP'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. DATA: lv_name TYPE ddobjname, lo_xml TYPE REF TO lcl_xml_output, ls_dd30v TYPE dd30v, lt_dd31v TYPE TABLE OF dd31v, lt_dd32p TYPE TABLE OF dd32p, lt_dd33v TYPE TABLE OF dd33v. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_SHLP_GET' EXPORTING name = lv_name state = 'A' langu = gc_english IMPORTING dd30v_wa = ls_dd30v TABLES dd31v_tab = lt_dd31v dd32p_tab = lt_dd32p dd33v_tab = lt_dd33v EXCEPTIONS illegal_input = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from DDIF_SHLP_GET'. ENDIF. IF ls_dd30v IS INITIAL. RETURN. " does not exist in system ENDIF. CLEAR: ls_dd30v-as4user, ls_dd30v-as4date, ls_dd30v-as4time. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DD30V' ig_data = ls_dd30v ). lo_xml->add( ig_data = lt_dd31v iv_name = 'DD31V_TABLE' ). lo_xml->add( ig_data = lt_dd32p iv_name = 'DD32P_TABLE' ). lo_xml->add( ig_data = lt_dd33v iv_name = 'DD33V_TABLE' ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_name TYPE ddobjname, ls_dd30v TYPE dd30v, lt_dd31v TYPE TABLE OF dd31v, lt_dd32p TYPE TABLE OF dd32p, lt_dd33v TYPE TABLE OF dd33v. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DD30V' CHANGING cg_data = ls_dd30v ). lo_xml->read( EXPORTING iv_name = 'DD31V_TABLE' CHANGING cg_data = lt_dd31v ). lo_xml->read( EXPORTING iv_name = 'DD32P_TABLE' CHANGING cg_data = lt_dd32p ). lo_xml->read( EXPORTING iv_name = 'DD33V_TABLE' CHANGING cg_data = lt_dd33v ). corr_insert( iv_package ). lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_SHLP_PUT' EXPORTING name = lv_name dd30v_wa = ls_dd30v TABLES dd31v_tab = lt_dd31v dd32p_tab = lt_dd32p dd33v_tab = lt_dd33v EXCEPTIONS shlp_not_found = 1 name_inconsistent = 2 shlp_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from DDIF_SHLP_PUT'. ENDIF. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_shlp IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_TRAN DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_tran DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_TRAN DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_msag IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_tran IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_tcode TYPE tstc-tcode. SELECT SINGLE tcode FROM tstc INTO lv_tcode WHERE tcode = ms_item-obj_name. "#EC CI_GENBUFF rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. DATA: lt_bdcdata TYPE TABLE OF bdcdata. FIELD-SYMBOLS: LIKE LINE OF lt_bdcdata. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -program = 'SAPLSEUK'. -dynpro = '0390'. -dynbegin = abap_true. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = 'BDC_OKCODE'. -fval = '=SHOW'. APPEND INITIAL LINE TO lt_bdcdata ASSIGNING . -fnam = 'TSTC-TCODE'. -fval = ms_item-obj_name. CALL FUNCTION 'ABAP4_CALL_TRANSACTION' STARTING NEW TASK 'GIT' EXPORTING tcode = 'SE93' mode_val = 'E' TABLES using_tab = lt_bdcdata EXCEPTIONS system_failure = 1 communication_failure = 2 resource_failure = 3 OTHERS = 4 ##fm_subrc_ok. "#EC CI_SUBRC ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_transaction TYPE tstc-tcode. lv_transaction = ms_item-obj_name. CALL FUNCTION 'RPY_TRANSACTION_DELETE' EXPORTING transaction = lv_transaction EXCEPTIONS not_excecuted = 1 object_not_found = 2 OTHERS = 3. IF sy-subrc <> 0. _raise 'Error from RPY_TRANSACTION_DELETE'. ENDIF. ENDMETHOD. "delete METHOD lif_object~deserialize. CONSTANTS: lc_hex_tra TYPE x VALUE '00', * c_hex_men TYPE x VALUE '01', lc_hex_par TYPE x VALUE '02', lc_hex_rep TYPE x VALUE '80'. * c_hex_rpv TYPE x VALUE '10', * c_hex_obj TYPE x VALUE '08', * c_hex_chk TYPE x VALUE '04', * c_hex_enq TYPE x VALUE '20'. DATA: lv_dynpro TYPE d020s-dnum, lo_xml TYPE REF TO lcl_xml_input, ls_tstc TYPE tstc, lv_type TYPE rglif-docutype, ls_tstct TYPE tstct, ls_tstcc TYPE tstcc. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'TSTC' CHANGING cg_data = ls_tstc ). lo_xml->read( EXPORTING iv_name = 'TSTCC' CHANGING cg_data = ls_tstcc ). lo_xml->read( EXPORTING iv_name = 'TSTCT' CHANGING cg_data = ls_tstct ). lv_dynpro = ls_tstc-dypno. CASE ls_tstc-cinfo. WHEN lc_hex_tra. lv_type = ststc_c_type_dialog. WHEN lc_hex_rep. lv_type = ststc_c_type_report. WHEN lc_hex_par. lv_type = ststc_c_type_parameters. * todo, or ststc_c_type_variant? WHEN OTHERS. _raise 'Transaction, unknown CINFO'. ENDCASE. CALL FUNCTION 'RPY_TRANSACTION_INSERT' EXPORTING transaction = ls_tstc-tcode program = ls_tstc-pgmna dynpro = lv_dynpro language = gc_english development_class = iv_package transaction_type = lv_type shorttext = ls_tstct-ttext html_enabled = ls_tstcc-s_webgui java_enabled = ls_tstcc-s_platin wingui_enabled = ls_tstcc-s_win32 EXCEPTIONS cancelled = 1 already_exist = 2 permission_error = 3 name_not_allowed = 4 name_conflict = 5 illegal_type = 6 object_inconsistent = 7 db_access_error = 8 OTHERS = 9. IF sy-subrc <> 0. _raise 'Error from RPY_TRANSACTION_INSERT'. ENDIF. ENDMETHOD. "deserialize METHOD lif_object~serialize. DATA: lv_transaction TYPE tstc-tcode, lt_tcodes TYPE TABLE OF tstc, ls_tcode LIKE LINE OF lt_tcodes, ls_tstct TYPE tstct, lt_gui_attr TYPE TABLE OF tstcc, lo_xml TYPE REF TO lcl_xml_output, ls_gui_attr LIKE LINE OF lt_gui_attr. lv_transaction = ms_item-obj_name. CALL FUNCTION 'RPY_TRANSACTION_READ' EXPORTING transaction = lv_transaction TABLES tcodes = lt_tcodes gui_attributes = lt_gui_attr EXCEPTIONS permission_error = 1 cancelled = 2 not_found = 3 object_not_found = 4 OTHERS = 5. IF sy-subrc = 4 OR sy-subrc = 3. RETURN. ENDIF. IF sy-subrc <> 0. _raise 'Error from RPY_TRANSACTION_READ'. ENDIF. SELECT SINGLE * FROM tstct INTO ls_tstct WHERE sprsl = gc_english AND tcode = lv_transaction. "#EC CI_GENBUFF IF sy-subrc <> 0. _raise 'Transaction description not found'. ENDIF. READ TABLE lt_tcodes INDEX 1 INTO ls_tcode. ASSERT sy-subrc = 0. READ TABLE lt_gui_attr INDEX 1 INTO ls_gui_attr. ASSERT sy-subrc = 0. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'TSTC' ig_data = ls_tcode ). lo_xml->add( iv_name = 'TSTCC' ig_data = ls_gui_attr ). lo_xml->add( iv_name = 'TSTCT' ig_data = ls_tstct ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize ENDCLASS. "lcl_object_msag IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_tobj DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_tobj DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_tobj DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_tobj IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_tobj IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_objectname TYPE objh-objectname. SELECT SINGLE objectname FROM objh INTO lv_objectname WHERE objectname = ms_item-obj_name(10) AND objecttype = ms_item-obj_name+10. "#EC CI_GENBUFF rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~serialize. DATA: ls_objh TYPE objh, ls_objt TYPE objt, lt_objs TYPE tt_objs, lt_objsl TYPE tt_objsl, lt_objm TYPE tt_objm, lo_xml TYPE REF TO lcl_xml_output. ls_objh-objectname = ms_item-obj_name(10). ls_objh-objecttype = ms_item-obj_name+10. CALL FUNCTION 'CTO_OBJECT_GET' EXPORTING iv_objectname = ls_objh-objectname iv_objecttype = ls_objh-objecttype iv_language = gc_english iv_sel_objt = abap_true iv_sel_objs = abap_true iv_sel_objsl = abap_true iv_sel_objm = abap_true IMPORTING es_objh = ls_objh es_objt = ls_objt TABLES tt_objs = lt_objs tt_objsl = lt_objsl tt_objm = lt_objm EXCEPTIONS object_not_defined = 1 OTHERS = 2. IF sy-subrc = 1. RETURN. ELSEIF sy-subrc <> 0. _raise 'error from CTO_OBJECT_GET'. ENDIF. CLEAR: ls_objh-luser, ls_objh-ldate. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'OBJH' ig_data = ls_objh ). lo_xml->add( iv_name = 'OBJT' ig_data = ls_objt ). lo_xml->add( iv_name = 'OBJS' ig_data = lt_objs ). lo_xml->add( iv_name = 'OBJSL' ig_data = lt_objsl ). lo_xml->add( iv_name = 'OBJM' ig_data = lt_objm ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: ls_objh TYPE objh, ls_objt TYPE objt, lt_objs TYPE tt_objs, lt_objsl TYPE tt_objsl, lt_objm TYPE tt_objm, lo_xml TYPE REF TO lcl_xml_input. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'OBJH' CHANGING cg_data = ls_objh ). lo_xml->read( EXPORTING iv_name = 'OBJT' CHANGING cg_data = ls_objt ). lo_xml->read( EXPORTING iv_name = 'OBJS' CHANGING cg_data = lt_objs ). lo_xml->read( EXPORTING iv_name = 'OBJSL' CHANGING cg_data = lt_objsl ). lo_xml->read( EXPORTING iv_name = 'OBJM' CHANGING cg_data = lt_objm ). CALL FUNCTION 'OBJ_GENERATE' EXPORTING iv_objectname = ls_objh-objectname iv_objecttype = ls_objh-objecttype iv_maint_mode = 'I' iv_objecttext = ls_objt-ddtext iv_objcateg = ls_objh-objcateg iv_objtransp = ls_objh-objtransp iv_devclass = iv_package TABLES tt_v_obj_s = lt_objs tt_objm = lt_objm EXCEPTIONS illegal_call = 1 object_not_found = 2 generate_error = 3 transport_error = 4 object_enqueue_failed = 5 OTHERS = 6. IF sy-subrc <> 0. * todo, TOBJ has to be saved/generated after the DDIC tables have been activated _raise 'error from OBJ_GENERATE'. ENDIF. ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: ls_objh TYPE objh. ls_objh-objectname = ms_item-obj_name(10). ls_objh-objecttype = ms_item-obj_name+10. CALL FUNCTION 'OBJ_GENERATE' EXPORTING iv_objectname = ls_objh-objectname iv_objecttype = ls_objh-objecttype iv_maint_mode = 'D' EXCEPTIONS illegal_call = 1 object_not_found = 2 generate_error = 3 transport_error = 4 object_enqueue_failed = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from OBJ_GENERATE'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. _raise 'todo, TOBJ jump'. ENDMETHOD. "jump ENDCLASS. "lcl_object_tobj IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_msag DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_msag DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_msag DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_view IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_msag IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_arbgb TYPE t100a-arbgb. SELECT SINGLE arbgb FROM t100a INTO lv_arbgb WHERE arbgb = ms_item-obj_name. "#EC CI_GENBUFF rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = 'MSAG' in_new_window = abap_true. ENDMETHOD. "jump METHOD lif_object~delete. * parameter SUPPRESS_DIALOG doesnt exist in all versions CALL FUNCTION 'RS_DELETE_MESSAGE_ID' EXPORTING nachrichtenklasse = ms_item-obj_name EXCEPTIONS not_executed = 1 not_found = 2 no_permission = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'Error from RS_DELETE_MESSAGE_ID'. ENDIF. ENDMETHOD. "delete METHOD lif_object~deserialize. * fm RPY_MESSAGE_ID_INSERT almost works, but not in older versions DATA: lo_xml TYPE REF TO lcl_xml_input, ls_t100a TYPE t100a, ls_t100t TYPE t100t, ls_t100u TYPE t100u, lt_t100 TYPE TABLE OF t100. FIELD-SYMBOLS: LIKE LINE OF lt_t100. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'T100A' CHANGING cg_data = ls_t100a ). lo_xml->read( EXPORTING iv_name = 'T100' CHANGING cg_data = lt_t100 ). CALL FUNCTION 'RS_CORR_INSERT' EXPORTING global_lock = abap_true devclass = iv_package object = ls_t100a-arbgb object_class = 'T100' mode = 'INSERT' EXCEPTIONS cancelled = 01 permission_failure = 02 unknown_objectclass = 03. IF sy-subrc <> 0. _raise 'Error from RS_CORR_INSERT'. ENDIF. LOOP AT lt_t100 ASSIGNING . MODIFY t100 FROM . "#EC CI_SUBRC ASSERT sy-subrc = 0. CLEAR ls_t100u. MOVE-CORRESPONDING TO ls_t100u ##enh_ok. ls_t100u-name = sy-uname. ls_t100u-datum = sy-datum. ls_t100u-selfdef = '3'. MODIFY t100u FROM ls_t100u. "#EC CI_SUBRC ASSERT sy-subrc = 0. ENDLOOP. ls_t100a-masterlang = gc_english. ls_t100a-lastuser = sy-uname. ls_t100a-respuser = sy-uname. ls_t100a-ldate = sy-datum. ls_t100a-ltime = sy-uzeit. MODIFY t100a FROM ls_t100a. "#EC CI_SUBRC ASSERT sy-subrc = 0. ls_t100t-sprsl = gc_english. ls_t100t-arbgb = ls_t100a-arbgb. ls_t100t-stext = ls_t100a-stext. MODIFY t100t FROM ls_t100t. "#EC CI_SUBRC ASSERT sy-subrc = 0. ENDMETHOD. "deserialize METHOD lif_object~serialize. DATA: lv_msg_id TYPE rglif-message_id, ls_inf TYPE t100a, lt_source TYPE TABLE OF t100, lo_xml TYPE REF TO lcl_xml_output. lv_msg_id = ms_item-obj_name. SELECT SINGLE * FROM t100a INTO ls_inf WHERE arbgb = lv_msg_id. "#EC CI_GENBUFF IF sy-subrc <> 0. RETURN. ENDIF. CLEAR ls_inf-respuser. SELECT * FROM t100 INTO TABLE lt_source WHERE sprsl = gc_english AND arbgb = lv_msg_id ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF CLEAR: ls_inf-lastuser, ls_inf-ldate, ls_inf-ltime. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'T100A' ig_data = ls_inf ). lo_xml->add( ig_data = lt_source iv_name = 'T100' ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize ENDCLASS. "lcl_object_view IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_fugr DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_fugr DEFINITION INHERITING FROM lcl_objects_program FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. TYPES: ty_rs38l_incl_tt TYPE STANDARD TABLE OF rs38l_incl WITH DEFAULT KEY. METHODS main_name RETURNING VALUE(rv_program) TYPE program RAISING lcx_exception. METHODS functions RETURNING VALUE(rt_functab) TYPE ty_rs38l_incl_tt RAISING lcx_exception. METHODS includes RETURNING VALUE(rt_includes) TYPE rso_t_objnm RAISING lcx_exception. METHODS serialize_functions RAISING lcx_exception. METHODS deserialize_functions RAISING lcx_exception. METHODS serialize_xml RAISING lcx_exception. METHODS deserialize_xml IMPORTING iv_package TYPE devclass RAISING lcx_exception. METHODS serialize_includes RAISING lcx_exception. METHODS deserialize_includes IMPORTING iv_package TYPE devclass RAISING lcx_exception. ENDCLASS. "lcl_object_fugr DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_fugr IMPLEMENTATION. * function group SEUF * function group SIFP * function group SUNI METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_pool TYPE tlibg-area. lv_pool = ms_item-obj_name. CALL FUNCTION 'RS_FUNCTION_POOL_EXISTS' EXPORTING function_pool = lv_pool EXCEPTIONS pool_not_exists = 1. rv_bool = boolc( sy-subrc <> 1 ). ENDMETHOD. METHOD deserialize_functions. DATA: lv_include TYPE rs38l-include, lv_area TYPE rs38l-area, lo_xml TYPE REF TO lcl_xml_input, lt_functab TYPE ty_rs38l_incl_tt, lt_import TYPE TABLE OF rsimp, lt_changing TYPE TABLE OF rscha, lt_export TYPE TABLE OF rsexp, lt_tables TYPE TABLE OF rstbl, lt_exception TYPE TABLE OF rsexc, lt_documentation TYPE TABLE OF rsfdo, lt_source TYPE TABLE OF rssource, lv_global_flag TYPE rs38l-global, lv_remote_call TYPE rs38l-remote, lv_update_task TYPE rs38l-utask, lv_short_text TYPE tftit-stext, lv_remote_basxml TYPE rs38l-basxml_enabled. FIELD-SYMBOLS: LIKE LINE OF lt_functab. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'FUNCTAB' CHANGING cg_data = lt_functab ). LOOP AT lt_functab ASSIGNING . lt_source = mo_files->read_abap( iv_extra = -funcname ). lo_xml = mo_files->read_xml( iv_extra = -funcname ). lo_xml->read( EXPORTING iv_name = 'GLOBAL_FLAG' CHANGING cg_data = lv_global_flag ). lo_xml->read( EXPORTING iv_name = 'REMOTE_CALL' CHANGING cg_data = lv_remote_call ). lo_xml->read( EXPORTING iv_name = 'UPDATE_TASK' CHANGING cg_data = lv_update_task ). lo_xml->read( EXPORTING iv_name = 'SHORT_TEXT' CHANGING cg_data = lv_short_text ). lo_xml->read( EXPORTING iv_name = 'REMOTE_BASXML' CHANGING cg_data = lv_remote_basxml ). lo_xml->read( EXPORTING iv_name = 'IMPORT' CHANGING cg_data = lt_import ). lo_xml->read( EXPORTING iv_name = 'CHANGING' CHANGING cg_data = lt_changing ). lo_xml->read( EXPORTING iv_name = 'EXPORT' CHANGING cg_data = lt_export ). lo_xml->read( EXPORTING iv_name = 'TABLES' CHANGING cg_data = lt_tables ). lo_xml->read( EXPORTING iv_name = 'EXCEPTION' CHANGING cg_data = lt_exception ). lo_xml->read( EXPORTING iv_name = 'DOCUMENTATION' CHANGING cg_data = lt_documentation ). lv_area = ms_item-obj_name. CALL FUNCTION 'FUNCTION_EXISTS' EXPORTING funcname = -funcname IMPORTING include = lv_include EXCEPTIONS function_not_exist = 1. IF sy-subrc = 0. * delete the function module to make sure the parameters are updated * havent found a nice way to update the paramters CALL FUNCTION 'FUNCTION_DELETE' EXPORTING funcname = -funcname suppress_success_message = abap_true EXCEPTIONS error_message = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from FUNCTION_DELETE'. ENDIF. ENDIF. CALL FUNCTION 'RS_FUNCTIONMODULE_INSERT' EXPORTING funcname = -funcname function_pool = lv_area interface_global = lv_global_flag remote_call = lv_remote_call short_text = lv_short_text * NAMESPACE = ' ' todo remote_basxml_supported = lv_remote_basxml IMPORTING function_include = lv_include TABLES import_parameter = lt_import export_parameter = lt_export tables_parameter = lt_tables changing_parameter = lt_changing exception_list = lt_exception parameter_docu = lt_documentation EXCEPTIONS double_task = 1 error_message = 2 function_already_exists = 3 invalid_function_pool = 4 invalid_name = 5 too_many_functions = 6 no_modify_permission = 7 no_show_permission = 8 enqueue_system_failure = 9 canceled_in_corr = 10 OTHERS = 11. IF sy-subrc <> 0. _raise 'error from RS_FUNCTIONMODULE_INSERT'. ENDIF. INSERT REPORT lv_include FROM lt_source. lcl_objects_activation=>add( iv_type = 'FUNC' iv_name = -funcname ). ENDLOOP. ENDMETHOD. "deserialize_functions METHOD deserialize_includes. DATA: lo_xml TYPE REF TO lcl_xml_input, ls_progdir TYPE ty_progdir, lt_includes TYPE rso_t_objnm, lt_tpool TYPE textpool_table, lt_source TYPE TABLE OF abaptxt255. FIELD-SYMBOLS: LIKE LINE OF lt_includes. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'INCLUDES' CHANGING cg_data = lt_includes ). LOOP AT lt_includes ASSIGNING . lt_source = mo_files->read_abap( iv_extra = ). lo_xml = mo_files->read_xml( iv_extra = ). lo_xml->read( EXPORTING iv_name = 'PROGDIR' CHANGING cg_data = ls_progdir ). lo_xml->read( EXPORTING iv_name = 'TPOOL' CHANGING cg_data = lt_tpool ). deserialize_program( is_progdir = ls_progdir it_source = lt_source it_tpool = lt_tpool iv_package = iv_package ). ENDLOOP. ENDMETHOD. "deserialize_includes METHOD deserialize_xml. DATA: lv_complete TYPE rs38l-area, lo_xml TYPE REF TO lcl_xml_input, lv_namespace TYPE rs38l-namespace, lv_areat TYPE tlibt-areat, lv_stext TYPE tftit-stext, lv_group TYPE rs38l-area. lv_complete = ms_item-obj_name. CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT' EXPORTING complete_area = lv_complete IMPORTING namespace = lv_namespace group = lv_group EXCEPTIONS include_not_exists = 1 group_not_exists = 2 no_selections = 3 no_function_include = 4 no_function_pool = 5 delimiter_wrong_position = 6 no_customer_function_group = 7 no_customer_function_include = 8 reserved_name_customer = 9 namespace_too_long = 10 area_length_error = 11 OTHERS = 12. IF sy-subrc <> 0. _raise 'error from FUNCTION_INCLUDE_SPLIT'. ENDIF. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'AREAT' CHANGING cg_data = lv_areat ). lv_stext = lv_areat. CALL FUNCTION 'RS_FUNCTION_POOL_INSERT' EXPORTING function_pool = lv_group short_text = lv_stext namespace = lv_namespace devclass = iv_package EXCEPTIONS name_already_exists = 1 name_not_correct = 2 function_already_exists = 3 invalid_function_pool = 4 invalid_name = 5 too_many_functions = 6 no_modify_permission = 7 no_show_permission = 8 enqueue_system_failure = 9 canceled_in_corr = 10 undefined_error = 11 OTHERS = 12. IF sy-subrc <> 0 AND sy-subrc <> 1 AND sy-subrc <> 3. * todo, change description _raise 'error from RS_FUNCTION_POOL_INSERT'. ENDIF. ENDMETHOD. "deserialize_xml METHOD serialize_xml. DATA: lo_xml TYPE REF TO lcl_xml_output, lt_functab TYPE ty_rs38l_incl_tt, lt_includes TYPE rso_t_objnm, lv_areat TYPE tlibt-areat. SELECT SINGLE areat INTO lv_areat FROM tlibt WHERE spras = gc_english AND area = ms_item-obj_name. "#EC CI_GENBUFF IF sy-subrc <> 0. _raise 'not found in TLIBT'. ENDIF. lt_functab = functions( ). lt_includes = includes( ). * todo, dynpros CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'AREAT' ig_data = lv_areat ). lo_xml->add( iv_name = 'FUNCTAB' ig_data = lt_functab ). lo_xml->add( iv_name = 'INCLUDES' ig_data = lt_includes ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize_xml METHOD includes. DATA: lv_program TYPE program, lv_cnam TYPE reposrc-cnam, lt_functab TYPE ty_rs38l_incl_tt. FIELD-SYMBOLS: LIKE LINE OF rt_includes, LIKE LINE OF lt_functab. lv_program = main_name( ). lt_functab = functions( ). CALL FUNCTION 'RS_GET_ALL_INCLUDES' EXPORTING program = lv_program * WITH_RESERVED_INCLUDES = * WITH_CLASS_INCLUDES = ' ' hmm, todo TABLES includetab = rt_includes EXCEPTIONS not_existent = 1 no_program = 2 OTHERS = 3. IF sy-subrc <> 0. _raise 'Error from RS_GET_ALL_INCLUDES'. ENDIF. LOOP AT lt_functab ASSIGNING . DELETE TABLE rt_includes FROM -include. ENDLOOP. * skip SAP standard includes LOOP AT rt_includes ASSIGNING . SELECT SINGLE cnam FROM reposrc INTO lv_cnam WHERE progname = AND r3state = 'A' AND cnam = 'SAP'. IF sy-subrc = 0. DELETE rt_includes INDEX sy-tabix. ENDIF. ENDLOOP. APPEND lv_program TO rt_includes. ENDMETHOD. "includes METHOD functions. DATA: lv_area TYPE rs38l-area. lv_area = ms_item-obj_name. CALL FUNCTION 'RS_FUNCTION_POOL_CONTENTS' EXPORTING function_pool = lv_area TABLES functab = rt_functab EXCEPTIONS function_pool_not_found = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Error from RS_FUNCTION_POOL_CONTENTS'. ENDIF. ENDMETHOD. "functions METHOD main_name. DATA: lv_area TYPE rs38l-area, lv_namespace TYPE rs38l-namespace, lv_group TYPE rs38l-area. lv_area = ms_item-obj_name. CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT' EXPORTING complete_area = lv_area IMPORTING namespace = lv_namespace group = lv_group EXCEPTIONS include_not_exists = 1 group_not_exists = 2 no_selections = 3 no_function_include = 4 no_function_pool = 5 delimiter_wrong_position = 6 no_customer_function_group = 7 no_customer_function_include = 8 reserved_name_customer = 9 namespace_too_long = 10 area_length_error = 11 OTHERS = 12. IF sy-subrc <> 0. _raise 'Error from FUNCTION_INCLUDE_SPLIT'. ENDIF. CONCATENATE lv_namespace 'SAPL' lv_group INTO rv_program. ENDMETHOD. "main_name METHOD serialize_functions. DATA: lt_import TYPE TABLE OF rsimp, lo_xml TYPE REF TO lcl_xml_output, lt_changing TYPE TABLE OF rscha, lt_export TYPE TABLE OF rsexp, lt_tables TYPE TABLE OF rstbl, lt_exception TYPE TABLE OF rsexc, lt_documentation TYPE TABLE OF rsfdo, lt_source TYPE TABLE OF rssource, lv_global_flag TYPE rs38l-global, lv_remote_call TYPE rs38l-remote, lv_update_task TYPE rs38l-utask, lv_short_text TYPE tftit-stext, lt_functab TYPE ty_rs38l_incl_tt, lt_new_source TYPE rsfb_source, lv_remote_basxml TYPE rs38l-basxml_enabled. FIELD-SYMBOLS: LIKE LINE OF lt_functab. lt_functab = functions( ). LOOP AT lt_functab ASSIGNING . * fm RPY_FUNCTIONMODULE_READ does not support source code * lines longer than 72 characters CALL FUNCTION 'RPY_FUNCTIONMODULE_READ_NEW' EXPORTING functionname = -funcname IMPORTING global_flag = lv_global_flag remote_call = lv_remote_call update_task = lv_update_task short_text = lv_short_text remote_basxml_supported = lv_remote_basxml TABLES import_parameter = lt_import changing_parameter = lt_changing export_parameter = lt_export tables_parameter = lt_tables exception_list = lt_exception documentation = lt_documentation source = lt_source CHANGING new_source = lt_new_source EXCEPTIONS error_message = 1 function_not_found = 2 invalid_name = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'Error from RPY_FUNCTIONMODULE_READ_NEW'. ENDIF. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'GLOBAL_FLAG' ig_data = lv_global_flag ). lo_xml->add( iv_name = 'REMOTE_CALL' ig_data = lv_remote_call ). lo_xml->add( iv_name = 'UPDATE_TASK' ig_data = lv_update_task ). lo_xml->add( iv_name = 'SHORT_TEXT' ig_data = lv_short_text ). lo_xml->add( iv_name = 'REMOTE_BASXML' ig_data = lv_remote_basxml ). lo_xml->add( ig_data = lt_import iv_name = 'IMPORT' ). lo_xml->add( ig_data = lt_changing iv_name = 'CHANGING' ). lo_xml->add( ig_data = lt_export iv_name = 'EXPORT' ). lo_xml->add( ig_data = lt_tables iv_name = 'TABLES' ). lo_xml->add( ig_data = lt_exception iv_name = 'EXCEPTION' ). lo_xml->add( ig_data = lt_documentation iv_name = 'DOCUMENTATION' ). mo_files->add_xml( iv_extra = -funcname io_xml = lo_xml ). IF NOT lt_new_source IS INITIAL. mo_files->add_abap( iv_extra = -funcname it_abap = lt_new_source ). ELSE. mo_files->add_abap( iv_extra = -funcname it_abap = lt_source ). ENDIF. ENDLOOP. ENDMETHOD. "serialize_functions METHOD serialize_includes. DATA: lt_includes TYPE rso_t_objnm. FIELD-SYMBOLS: LIKE LINE OF lt_includes. lt_includes = includes( ). LOOP AT lt_includes ASSIGNING . * todo, filename is not correct, a include can be used in several programs serialize_program( is_item = ms_item io_files = mo_files iv_program = iv_extra = ). ENDLOOP. ENDMETHOD. "serialize_includes METHOD lif_object~serialize. IF lif_object~exists( ) = abap_false. RETURN. ENDIF. serialize_xml( ). serialize_functions( ). serialize_includes( ). ENDMETHOD. "serialize METHOD lif_object~deserialize. deserialize_xml( iv_package ). deserialize_functions( ). deserialize_includes( iv_package ). ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lv_area TYPE rs38l-area. lv_area = ms_item-obj_name. CALL FUNCTION 'RS_FUNCTION_POOL_DELETE' EXPORTING area = lv_area suppress_popups = abap_true skip_progress_ind = abap_true EXCEPTIONS canceled_in_corr = 1 enqueue_system_failure = 2 function_exist = 3 not_executed = 4 no_modify_permission = 5 no_show_permission = 6 permission_failure = 7 pool_not_exist = 8 cancelled = 9 OTHERS = 10. IF sy-subrc <> 0. _raise 'error from RS_FUNCTION_POOL_DELETE'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = 'FUGR' in_new_window = abap_true. ENDMETHOD. "jump ENDCLASS. "lcl_object_fugr IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_view DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_dtel IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_view IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_viewname TYPE dd25l-viewname. SELECT SINGLE viewname FROM dd25l INTO lv_viewname WHERE viewname = ms_item-obj_name AND as4local = 'A' AND as4vers = '0000'. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. jump_se11( iv_radio = 'RSRD1-VIMA' iv_field = 'RSRD1-VIMA_VAL' ). ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_true objname = lv_objname objtype = 'V' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. _raise 'error from RS_DD_DELETE_OBJ, VIEW'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, lv_name TYPE ddobjname, ls_dd25v TYPE dd25v, ls_dd09l TYPE dd09l, lt_dd26v TYPE TABLE OF dd26v, lt_dd27p TYPE TABLE OF dd27p, lt_dd28j TYPE TABLE OF dd28j, lt_dd28v TYPE TABLE OF dd28v. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_VIEW_GET' EXPORTING name = lv_name state = 'A' langu = gc_english IMPORTING dd25v_wa = ls_dd25v dd09l_wa = ls_dd09l TABLES dd26v_tab = lt_dd26v dd27p_tab = lt_dd27p dd28j_tab = lt_dd28j dd28v_tab = lt_dd28v EXCEPTIONS illegal_input = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from DDIF_VIEW_GET'. ENDIF. IF ls_dd25v IS INITIAL. RETURN. " does not exist in system ENDIF. CLEAR: ls_dd25v-as4user, ls_dd25v-as4date, ls_dd25v-as4time. CLEAR: ls_dd09l-as4user, ls_dd09l-as4date, ls_dd09l-as4time. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DD25V' ig_data = ls_dd25v ). lo_xml->add( iv_name = 'DD09L' ig_data = ls_dd09l ). lo_xml->add( ig_data = lt_dd26v iv_name = 'DD26V_TABLE' ). lo_xml->add( ig_data = lt_dd27p iv_name = 'DD27P_TABLE' ). lo_xml->add( ig_data = lt_dd28j iv_name = 'DD28J_TABLE' ). lo_xml->add( ig_data = lt_dd28v iv_name = 'DD28V_TABLE' ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_name TYPE ddobjname, ls_dd25v TYPE dd25v, ls_dd09l TYPE dd09l, lt_dd26v TYPE TABLE OF dd26v, lt_dd27p TYPE TABLE OF dd27p, lt_dd28j TYPE TABLE OF dd28j, lt_dd28v TYPE TABLE OF dd28v. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DD25V' CHANGING cg_data = ls_dd25v ). lo_xml->read( EXPORTING iv_name = 'DD09L' CHANGING cg_data = ls_dd09l ). lo_xml->read( EXPORTING iv_name = 'DD26V_TABLE' CHANGING cg_data = lt_dd26v ). lo_xml->read( EXPORTING iv_name = 'DD27P_TABLE' CHANGING cg_data = lt_dd27p ). lo_xml->read( EXPORTING iv_name = 'DD28J_TABLE' CHANGING cg_data = lt_dd28j ). lo_xml->read( EXPORTING iv_name = 'DD28V_TABLE' CHANGING cg_data = lt_dd28v ). corr_insert( iv_package ). lv_name = ms_item-obj_name. " type conversion CALL FUNCTION 'DDIF_VIEW_PUT' EXPORTING name = lv_name dd25v_wa = ls_dd25v dd09l_wa = ls_dd09l TABLES dd26v_tab = lt_dd26v dd27p_tab = lt_dd27p dd28j_tab = lt_dd28j dd28v_tab = lt_dd28v EXCEPTIONS view_not_found = 1 name_inconsistent = 2 view_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from DDIF_VIEW_PUT'. ENDIF. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_view IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_nrob DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_nrob DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_nrob DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_nrob IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_nrob IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_object TYPE tnro-object. SELECT SINGLE object FROM tnro INTO lv_object WHERE object = ms_item-obj_name. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, lv_object TYPE tnro-object, ls_attributes TYPE tnro, ls_text TYPE tnrot. lv_object = ms_item-obj_name. CALL FUNCTION 'NUMBER_RANGE_OBJECT_READ' EXPORTING language = gc_english object = lv_object IMPORTING object_attributes = ls_attributes object_text = ls_text EXCEPTIONS object_not_found = 1 OTHERS = 2. IF sy-subrc = 1. RETURN. ELSEIF sy-subrc <> 0. _raise 'error from NUMBER_RANGE_OBJECT_READ'. ENDIF. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'ATTRIBUTES' ig_data = ls_attributes ). lo_xml->add( iv_name = 'TEXT' ig_data = ls_text ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lt_errors TYPE TABLE OF inoer, ls_attributes TYPE tnro, ls_text TYPE tnrot. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'ATTRIBUTES' CHANGING cg_data = ls_attributes ). lo_xml->read( EXPORTING iv_name = 'TEXT' CHANGING cg_data = ls_text ). CALL FUNCTION 'NUMBER_RANGE_OBJECT_UPDATE' EXPORTING indicator = 'I' object_attributes = ls_attributes object_text = ls_text TABLES errors = lt_errors EXCEPTIONS object_already_exists = 1 object_attributes_missing = 2 object_not_found = 3 object_text_missing = 4 wrong_indicator = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from NUMBER_RANGE_OBJECT_UPDATE'. ENDIF. CALL FUNCTION 'NUMBER_RANGE_OBJECT_CLOSE' EXPORTING object = ls_attributes-object EXCEPTIONS object_not_initialized = 1. IF sy-subrc <> 0. _raise 'error from NUMBER_RANGE_OBJECT_CLOSE'. ENDIF. CALL FUNCTION 'TR_TADIR_INTERFACE' EXPORTING wi_test_modus = abap_false wi_tadir_pgmid = 'R3TR' wi_tadir_object = 'NROB' wi_tadir_obj_name = ms_item-obj_name wi_tadir_author = sy-uname wi_tadir_devclass = iv_package wi_tadir_masterlang = gc_english wi_set_genflag = abap_true EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. _raise 'error from TR_TADIR_INTERFACE'. ENDIF. ENDMETHOD. "deserialize METHOD lif_object~delete. DATA: lv_object TYPE tnro-object. lv_object = ms_item-obj_name. CALL FUNCTION 'NUMBER_RANGE_OBJECT_DELETE' EXPORTING language = gc_english object = lv_object EXCEPTIONS delete_not_allowed = 1 object_not_found = 2 wrong_indicator = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'error from NUMBER_RANGE_OBJECT_DELETE'. ENDIF. ENDMETHOD. "delete METHOD lif_object~jump. _raise 'todo'. ENDMETHOD. "jump ENDCLASS. "lcl_object_nrob IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_ttyp DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_ttyp DEFINITION INHERITING FROM lcl_objects_super FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. ENDCLASS. "lcl_object_dtel DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_ttyp IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_ttyp IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_typename TYPE dd40l-typename. SELECT SINGLE typename FROM dd40l INTO lv_typename WHERE typename = ms_item-obj_name AND as4local = 'A'. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. jump_se11( iv_radio = 'RSRD1-DDTYPE' iv_field = 'RSRD1-DDTYPE_VAL' ). ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_objname TYPE rsedd0-ddobjname. lv_objname = ms_item-obj_name. CALL FUNCTION 'RS_DD_DELETE_OBJ' EXPORTING no_ask = abap_true objname = lv_objname objtype = 'A' EXCEPTIONS not_executed = 1 object_not_found = 2 object_not_specified = 3 permission_failure = 4. IF sy-subrc <> 0. _raise 'error from RS_DD_DELETE_OBJ, TTYP'. ENDIF. ENDMETHOD. "delete METHOD lif_object~serialize. DATA: lo_xml TYPE REF TO lcl_xml_output, lv_name TYPE ddobjname, lt_dd42v TYPE dd42v_tab, lt_dd43v TYPE dd43v_tab, ls_dd40v TYPE dd40v. lv_name = ms_item-obj_name. CALL FUNCTION 'DDIF_TTYP_GET' EXPORTING name = lv_name state = 'A' langu = gc_english IMPORTING dd40v_wa = ls_dd40v TABLES dd42v_tab = lt_dd42v dd43v_tab = lt_dd43v EXCEPTIONS illegal_input = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from DDIF_TTYP_GET'. ENDIF. IF ls_dd40v IS INITIAL. RETURN. " does not exist in system ENDIF. CLEAR: ls_dd40v-as4user, ls_dd40v-as4date, ls_dd40v-as4time. CREATE OBJECT lo_xml. lo_xml->add( iv_name = 'DD40V' ig_data = ls_dd40v ). lo_xml->add( iv_name = 'DD42V' ig_data = lt_dd42v ). lo_xml->add( iv_name = 'DD43V' ig_data = lt_dd43v ). mo_files->add_xml( lo_xml ). ENDMETHOD. "serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, lv_name TYPE ddobjname, lt_dd42v TYPE dd42v_tab, lt_dd43v TYPE dd43v_tab, ls_dd40v TYPE dd40v. lo_xml = mo_files->read_xml( ). lo_xml->read( EXPORTING iv_name = 'DD40V' CHANGING cg_data = ls_dd40v ). lo_xml->read( EXPORTING iv_name = 'DD42V' CHANGING cg_data = lt_dd42v ). lo_xml->read( EXPORTING iv_name = 'DD43V' CHANGING cg_data = lt_dd43v ). corr_insert( iv_package ). lv_name = ms_item-obj_name. " type conversion CALL FUNCTION 'DDIF_TTYP_PUT' EXPORTING name = lv_name dd40v_wa = ls_dd40v TABLES dd42v_tab = lt_dd42v dd43v_tab = lt_dd43v EXCEPTIONS ttyp_not_found = 1 name_inconsistent = 2 ttyp_inconsistent = 3 put_failure = 4 put_refused = 5 OTHERS = 6. IF sy-subrc <> 0. _raise 'error from DDIF_TTYP_PUT'. ENDIF. lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object_ttyp IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object_prog DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_prog DEFINITION INHERITING FROM lcl_objects_program FINAL. PUBLIC SECTION. INTERFACES lif_object. ALIASES mo_files FOR lif_object~mo_files. PRIVATE SECTION. METHODS deserialize_dynpros IMPORTING it_dynpros TYPE ty_dynpro_tt RAISING lcx_exception. METHODS deserialize_cua IMPORTING is_cua TYPE ty_cua RAISING lcx_exception. METHODS deserialize_textpool IMPORTING it_tpool TYPE textpool_table RAISING lcx_exception. ENDCLASS. "lcl_object_prog DEFINITION *----------------------------------------------------------------------* * CLASS lcl_object_prog IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_object_prog IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). ENDMETHOD. METHOD lif_object~exists. DATA: lv_progname TYPE reposrc-progname. SELECT SINGLE progname FROM reposrc INTO lv_progname WHERE progname = ms_item-obj_name AND r3state = 'A'. rv_bool = boolc( sy-subrc = 0 ). ENDMETHOD. METHOD lif_object~jump. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = ms_item-obj_name object_type = 'PROG' in_new_window = abap_true. ENDMETHOD. "jump METHOD lif_object~delete. DATA: lv_program LIKE sy-repid. lv_program = ms_item-obj_name. CALL FUNCTION 'RS_DELETE_PROGRAM' EXPORTING program = lv_program suppress_popup = abap_true EXCEPTIONS enqueue_lock = 1 object_not_found = 2 permission_failure = 3 reject_deletion = 4 OTHERS = 5. IF sy-subrc <> 0. _raise 'error from RS_DELETE_PROGRAM'. ENDIF. ENDMETHOD. "delete METHOD deserialize_textpool. READ TABLE it_tpool WITH KEY id = 'R' TRANSPORTING NO FIELDS. IF ( sy-subrc = 0 AND lines( it_tpool ) = 1 ) OR lines( it_tpool ) = 0. RETURN. " no action for includes ENDIF. INSERT TEXTPOOL ms_item-obj_name FROM it_tpool LANGUAGE gc_english STATE 'I'. IF sy-subrc <> 0. _raise 'error from INSERT TEXTPOOL'. ENDIF. lcl_objects_activation=>add( iv_type = 'REPT' iv_name = ms_item-obj_name ). ENDMETHOD. "deserialize_textpool METHOD deserialize_cua. DATA: ls_tr_key TYPE trkey. IF is_cua-adm IS INITIAL. RETURN. ENDIF. SELECT SINGLE devclass INTO ls_tr_key-devclass FROM tadir WHERE pgmid = 'R3TR' AND object = ms_item-obj_type AND obj_name = ms_item-obj_name. "#EC CI_GENBUFF IF sy-subrc <> 0. _raise 'not found in tadir'. ENDIF. ls_tr_key-obj_type = ms_item-obj_type. ls_tr_key-obj_name = ms_item-obj_name. ls_tr_key-sub_type = 'CUAD'. ls_tr_key-sub_name = ms_item-obj_name. CALL FUNCTION 'RS_CUA_INTERNAL_WRITE' EXPORTING program = ms_item-obj_name language = gc_english tr_key = ls_tr_key adm = is_cua-adm state = 'I' TABLES sta = is_cua-sta fun = is_cua-fun men = is_cua-men mtx = is_cua-mtx act = is_cua-act but = is_cua-but pfk = is_cua-pfk set = is_cua-set doc = is_cua-doc tit = is_cua-tit biv = is_cua-biv EXCEPTIONS not_found = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'error from RS_CUA_INTERNAL_WRITE'. ENDIF. lcl_objects_activation=>add( iv_type = 'CUAD' iv_name = ms_item-obj_name ). ENDMETHOD. "deserialize_cua METHOD lif_object~serialize. serialize_program( is_item = ms_item io_files = mo_files ). ENDMETHOD. "lif_serialize~serialize METHOD lif_object~deserialize. DATA: lo_xml TYPE REF TO lcl_xml_input, ls_progdir TYPE ty_progdir, lt_tpool TYPE textpool_table, lt_dynpros TYPE ty_dynpro_tt, ls_cua TYPE ty_cua, lt_source TYPE abaptxt255_tab. lo_xml = mo_files->read_xml( ). lt_source = mo_files->read_abap( ). lo_xml->read( EXPORTING iv_name = 'TPOOL' CHANGING cg_data = lt_tpool ). lo_xml->read( EXPORTING iv_name = 'PROGDIR' CHANGING cg_data = ls_progdir ). deserialize_program( is_progdir = ls_progdir it_source = lt_source it_tpool = lt_tpool iv_package = iv_package ). lo_xml->read( EXPORTING iv_name = 'DYNPROS' CHANGING cg_data = lt_dynpros ). deserialize_dynpros( lt_dynpros ). lo_xml->read( EXPORTING iv_name = 'CUA' CHANGING cg_data = ls_cua ). deserialize_cua( ls_cua ). deserialize_textpool( lt_tpool ). ENDMETHOD. "lif_serialize~deserialize METHOD deserialize_dynpros. DATA: lv_name TYPE dwinactiv-obj_name, ls_dynpro LIKE LINE OF it_dynpros. * ls_dynpro is changed by the function module, a field-symbol will cause * the program to dump since it_dynpros cannot be changed LOOP AT it_dynpros INTO ls_dynpro. CALL FUNCTION 'RPY_DYNPRO_INSERT' EXPORTING header = ls_dynpro-header suppress_exist_checks = abap_true TABLES containers = ls_dynpro-containers fields_to_containers = ls_dynpro-fields flow_logic = ls_dynpro-flow_logic EXCEPTIONS cancelled = 1 already_exists = 2 program_not_exists = 3 not_executed = 4 missing_required_field = 5 illegal_field_value = 6 field_not_allowed = 7 not_generated = 8 illegal_field_position = 9 OTHERS = 10. IF sy-subrc <> 2 AND sy-subrc <> 0. _raise 'error from RPY_DYNPRO_INSERT'. ENDIF. * todo, RPY_DYNPRO_UPDATE? CONCATENATE ls_dynpro-header-program ls_dynpro-header-screen INTO lv_name RESPECTING BLANKS. ASSERT NOT lv_name IS INITIAL. lcl_objects_activation=>add( iv_type = 'DYNP' iv_name = lv_name ). ENDLOOP. ENDMETHOD. "deserialize_dynpros ENDCLASS. "lcl_object_prog IMPLEMENTATION CLASS lcl_file_status DEFINITION FINAL. PUBLIC SECTION. TYPES: BEGIN OF ty_result, obj_type TYPE tadir-object, obj_name TYPE tadir-obj_name, match TYPE sap_bool, filename TYPE string, package TYPE devclass, path TYPE string, END OF ty_result. TYPES: ty_results_tt TYPE STANDARD TABLE OF ty_result WITH DEFAULT KEY. CLASS-METHODS status IMPORTING it_files TYPE ty_files_tt iv_package TYPE devclass RETURNING VALUE(rt_results) TYPE ty_results_tt RAISING lcx_exception. PRIVATE SECTION. CLASS-METHODS compare_files IMPORTING it_repo TYPE ty_files_tt is_gen TYPE ty_file RETURNING VALUE(rv_match) TYPE sap_bool RAISING lcx_exception. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_object DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_objects DEFINITION FINAL. PUBLIC SECTION. TYPES: ty_types_tt TYPE STANDARD TABLE OF tadir-object WITH DEFAULT KEY. CLASS-METHODS serialize IMPORTING is_item TYPE ty_item RETURNING VALUE(rt_files) TYPE ty_files_tt RAISING lcx_exception. CLASS-METHODS deserialize IMPORTING it_files TYPE ty_files_tt iv_package TYPE devclass RAISING lcx_exception. CLASS-METHODS delete IMPORTING it_tadir TYPE lcl_tadir=>ty_tadir_tt RAISING lcx_exception. CLASS-METHODS jump IMPORTING is_item TYPE ty_item RAISING lcx_exception. CLASS-METHODS is_supported IMPORTING is_item TYPE ty_item RETURNING VALUE(rv_bool) TYPE abap_bool. CLASS-METHODS exists IMPORTING is_item TYPE ty_item RETURNING VALUE(rv_bool) TYPE abap_bool. CLASS-METHODS supported_list RETURNING VALUE(rt_types) TYPE ty_types_tt. PRIVATE SECTION. CLASS-METHODS create_object IMPORTING is_item TYPE ty_item RETURNING VALUE(ri_obj) TYPE REF TO lif_object RAISING lcx_exception. CLASS-METHODS prioritize_deser IMPORTING it_results TYPE lcl_file_status=>ty_results_tt RETURNING VALUE(rt_results) TYPE lcl_file_status=>ty_results_tt. CLASS-METHODS class_name IMPORTING is_item TYPE ty_item RETURNING VALUE(rv_class_name) TYPE string. CLASS-METHODS resolve_ddic CHANGING ct_tadir TYPE lcl_tadir=>ty_tadir_tt RAISING lcx_exception. CLASS-METHODS check_warning IMPORTING is_item TYPE ty_item iv_package TYPE devclass RETURNING VALUE(rv_cancel) TYPE abap_bool RAISING lcx_exception. CLASS-METHODS update_package_tree IMPORTING iv_package TYPE devclass. CLASS-METHODS delete_obj IMPORTING is_item TYPE ty_item RAISING lcx_exception. CLASS-METHODS show_progress IMPORTING iv_current TYPE i iv_total TYPE i iv_obj_name TYPE tadir-obj_name. ENDCLASS. "lcl_object DEFINITION *----------------------------------------------------------------------* * CLASS lcl_tadir IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_tadir IMPLEMENTATION. METHOD read_single. DATA: lv_obj_name TYPE tadir-obj_name. IF iv_object = 'SICF'. CONCATENATE iv_obj_name '%' INTO lv_obj_name. ELSE. lv_obj_name = iv_obj_name. ENDIF. SELECT SINGLE * FROM tadir INTO rs_tadir WHERE pgmid = iv_pgmid AND object = iv_object AND obj_name LIKE lv_obj_name. "#EC CI_SUBRC "#EC CI_GENBUFF ENDMETHOD. "read_single METHOD check_exists. DATA: lv_exists TYPE abap_bool, ls_item TYPE ty_item. FIELD-SYMBOLS: LIKE LINE OF it_tadir. * rows from database table TADIR are not removed for * transportable objects until the transport is released LOOP AT it_tadir ASSIGNING . ls_item-obj_type = -object. ls_item-obj_name = -obj_name. lv_exists = lcl_objects=>exists( ls_item ). IF lv_exists = abap_true. APPEND TO rt_tadir. ENDIF. ENDLOOP. ENDMETHOD. METHOD read. * start recursion rt_tadir = build( iv_package = iv_package iv_parent = '' iv_path = '' ). rt_tadir = check_exists( rt_tadir ). ENDMETHOD. "read METHOD build. DATA: lv_index TYPE i, lt_tadir TYPE ty_tadir_tt, lt_tdevc TYPE STANDARD TABLE OF tdevc, lv_len TYPE i, lv_message TYPE string, lv_path TYPE string, lv_category TYPE seoclassdf-category. FIELD-SYMBOLS: LIKE LINE OF lt_tdevc, LIKE LINE OF rt_tadir. SELECT * FROM tadir INTO CORRESPONDING FIELDS OF TABLE rt_tadir WHERE devclass = iv_package AND object <> 'DEVC' AND object <> 'SOTR' AND delflag = abap_false ORDER BY PRIMARY KEY. "#EC CI_GENBUFF "#EC CI_SUBRC LOOP AT rt_tadir ASSIGNING . lv_index = sy-tabix. -path = iv_path. CASE -object. WHEN 'SICF'. -obj_name = -obj_name(15). WHEN 'INTF'. SELECT SINGLE category FROM seoclassdf INTO lv_category WHERE clsname = -obj_name AND ( version = '1' OR version = '0' ) ##warn_ok. "#EC CI_GENBUFF IF sy-subrc = 0 AND lv_category = seoc_category_webdynpro_class. DELETE rt_tadir INDEX lv_index. ENDIF. ENDCASE. ENDLOOP. * look for subpackages SELECT * FROM tdevc INTO TABLE lt_tdevc WHERE parentcl = iv_package ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF LOOP AT lt_tdevc ASSIGNING . lv_len = strlen( iv_package ). IF -devclass(lv_len) <> iv_package. * if abapGit project is installed in package ZZZ, all subpackages should be named * ZZZ_something. This will define the folder name in the zip file to be "something", * similarily with online projects lv_message = 'Unexpected package naming(' && -devclass && ')' ##NO_TEXT. MESSAGE lv_message TYPE 'I'. CONTINUE. ENDIF. lv_path = -devclass+lv_len. IF lv_path(1) = '_'. lv_path = lv_path+1. ENDIF. TRANSLATE lv_path TO LOWER CASE. CONCATENATE iv_path lv_path '/' INTO lv_path. lt_tadir = build( iv_package = -devclass iv_parent = iv_package iv_path = lv_path ). APPEND LINES OF lt_tadir TO rt_tadir. ENDLOOP. ENDMETHOD. "build ENDCLASS. "lcl_tadir IMPLEMENTATION CLASS lcl_file_status IMPLEMENTATION. METHOD compare_files. READ TABLE it_repo WITH KEY path = is_gen-path filename = is_gen-filename data = is_gen-data TRANSPORTING NO FIELDS. IF sy-subrc <> 0. rv_match = abap_false. ELSE. rv_match = abap_true. ENDIF. ENDMETHOD. METHOD status. DATA: lv_pre TYPE tadir-obj_name, lt_files TYPE ty_files_tt, ls_result LIKE LINE OF rt_results, lv_type TYPE string, ls_item TYPE ty_item, lt_tadir TYPE lcl_tadir=>ty_tadir_tt, ls_tadir TYPE tadir, lv_ext TYPE string. FIELD-SYMBOLS: LIKE LINE OF it_files, LIKE LINE OF lt_tadir, LIKE LINE OF rt_results, LIKE LINE OF lt_files. LOOP AT it_files ASSIGNING . SPLIT -filename AT '.' INTO lv_pre lv_type lv_ext. TRANSLATE lv_pre TO UPPER CASE. TRANSLATE lv_type TO UPPER CASE. IF lv_ext <> 'xml' OR strlen( lv_type ) <> 4. CONTINUE. " current loop ENDIF. * handle namespaces REPLACE ALL OCCURRENCES OF '#' IN lv_pre WITH '/'. CLEAR ls_result. ls_result-obj_type = lv_type. ls_result-obj_name = lv_pre. CLEAR ls_item. ls_item-obj_type = lv_type. ls_item-obj_name = lv_pre. lt_files = lcl_objects=>serialize( ls_item ). IF lt_files[] IS INITIAL. * item does not exist locally ls_result-filename = -filename. APPEND ls_result TO rt_results. CONTINUE. " current loop ENDIF. LOOP AT lt_files ASSIGNING . ls_result-filename = -filename. ls_result-match = compare_files( it_repo = it_files is_gen = ). APPEND ls_result TO rt_results. ENDLOOP. ENDLOOP. * find files only existing remotely, including non abapGit related LOOP AT it_files ASSIGNING . READ TABLE rt_results WITH KEY filename = -filename TRANSPORTING NO FIELDS. IF sy-subrc <> 0. CLEAR ls_result. ls_result-match = abap_true. ls_result-filename = -filename. APPEND ls_result TO rt_results. ENDIF. ENDLOOP. * find objects only existing locally lt_tadir = lcl_tadir=>read( iv_package ). LOOP AT lt_tadir ASSIGNING . READ TABLE rt_results WITH KEY obj_type = -object obj_name = -obj_name TRANSPORTING NO FIELDS. IF sy-subrc <> 0. CLEAR ls_result. ls_result-match = abap_true. ls_result-obj_type = -object. ls_result-obj_name = -obj_name. APPEND ls_result TO rt_results. ENDIF. ENDLOOP. * add path information for files LOOP AT it_files ASSIGNING . READ TABLE rt_results ASSIGNING WITH KEY filename = -filename. IF sy-subrc = 0. -path = -path. ENDIF. ENDLOOP. * add package information LOOP AT rt_results ASSIGNING WHERE NOT obj_type IS INITIAL. ls_tadir = lcl_tadir=>read_single( iv_object = -obj_type iv_obj_name = -obj_name ). -package = ls_tadir-devclass. ENDLOOP. SORT rt_results BY obj_type ASCENDING obj_name ASCENDING filename ASCENDING. DELETE ADJACENT DUPLICATES FROM rt_results COMPARING obj_type obj_name filename. ENDMETHOD. "status ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_package DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_sap_package DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS: check IMPORTING it_results TYPE lcl_file_status=>ty_results_tt iv_top TYPE devclass RETURNING VALUE(rv_errors) TYPE string, create. PRIVATE SECTION. CLASS-METHODS: class_to_path IMPORTING iv_top TYPE devclass iv_package TYPE devclass RETURNING VALUE(rv_path) TYPE string. ENDCLASS. "lcl_package DEFINITION *----------------------------------------------------------------------* * CLASS lcl_package IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_sap_package IMPLEMENTATION. METHOD class_to_path. DATA: lv_len TYPE i, lv_path TYPE string, lv_parentcl TYPE tdevc-parentcl. IF iv_top = iv_package. rv_path = '/'. ELSE. SELECT SINGLE parentcl FROM tdevc INTO lv_parentcl WHERE devclass = iv_package. "#EC CI_SUBRC "#EC CI_GENBUFF ASSERT sy-subrc = 0. IF lv_parentcl IS INITIAL. rv_path = 'error' ##no_text. ELSE. lv_len = strlen( lv_parentcl ). lv_path = iv_package+lv_len. IF lv_path(1) = '_'. lv_path = lv_path+1. ENDIF. TRANSLATE lv_path TO LOWER CASE. CONCATENATE lv_path '/' INTO lv_path. rv_path = class_to_path( iv_top = iv_top iv_package = lv_parentcl ). CONCATENATE rv_path lv_path INTO rv_path. ENDIF. ENDIF. ENDMETHOD. "class_to_path METHOD check. DATA: lv_path TYPE string. FIELD-SYMBOLS: LIKE LINE OF it_results, LIKE LINE OF it_results. * check files for one object is in the same folder LOOP AT it_results ASSIGNING WHERE NOT obj_type IS INITIAL. LOOP AT it_results ASSIGNING WHERE obj_type = -obj_type AND obj_name = -obj_name AND path <> -path. CONCATENATE rv_errors 'Files for object' -obj_type -obj_name 'are not placed in the same folder
' INTO rv_errors SEPARATED BY space. "#EC NOTEXT EXIT. ENDLOOP. ENDLOOP. * check that objects are created in package corresponding to folder LOOP AT it_results ASSIGNING WHERE NOT package IS INITIAL AND NOT path IS INITIAL. lv_path = class_to_path( iv_top = iv_top iv_package = -package ). IF lv_path <> -path. CONCATENATE rv_errors 'Package and path does not match for object,' -obj_type -obj_name '
' INTO rv_errors SEPARATED BY space. "#EC NOTEXT ENDIF. ENDLOOP. * check for multiple files with same filename LOOP AT it_results ASSIGNING WHERE NOT filename IS INITIAL. LOOP AT it_results ASSIGNING WHERE filename = -filename AND path <> -path. CONCATENATE rv_errors 'Multiple files with same filename,' -filename '
' INTO rv_errors SEPARATED BY space. "#EC NOTEXT EXIT. ENDLOOP. ENDLOOP. IF NOT rv_errors IS INITIAL. CONCATENATE '
' rv_errors INTO rv_errors. ENDIF. ENDMETHOD. "check METHOD create. * todo, see https://github.com/larshp/abapGit/issues/5 ENDMETHOD. "create ENDCLASS. "lcl_package IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_object IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_objects IMPLEMENTATION. METHOD show_progress. DATA: lv_pct TYPE i, lv_f TYPE f. lv_f = ( iv_current / iv_total ) * 100. lv_pct = lv_f. CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR' EXPORTING percentage = lv_pct text = iv_obj_name. ENDMETHOD. "show_progress METHOD check_warning. DATA: lv_question TYPE c LENGTH 200, lv_answer TYPE c, ls_tadir TYPE tadir. ls_tadir = lcl_tadir=>read_single( iv_object = is_item-obj_type iv_obj_name = is_item-obj_name ). IF NOT ls_tadir IS INITIAL AND ls_tadir-devclass <> iv_package. CONCATENATE 'Overwrite object' is_item-obj_type is_item-obj_name 'from package' ls_tadir-devclass INTO lv_question SEPARATED BY space. "#EC NOTEXT CALL FUNCTION 'POPUP_TO_CONFIRM' EXPORTING titlebar = 'Warning' text_question = lv_question text_button_1 = 'Ok' icon_button_1 = 'ICON_DELETE' text_button_2 = 'Cancel' icon_button_2 = 'ICON_CANCEL' default_button = '2' display_cancel_button = abap_false IMPORTING answer = lv_answer EXCEPTIONS text_not_found = 1 OTHERS = 2. "#EC NOTEXT IF sy-subrc <> 0. _raise 'error from POPUP_TO_CONFIRM'. ENDIF. IF lv_answer = '2'. rv_cancel = abap_true. ENDIF. ENDIF. ENDMETHOD. "check_warning METHOD update_package_tree. DATA: lv_tree TYPE dirtree-tname. * update package tree for SE80 lv_tree = 'EU_' && iv_package. CALL FUNCTION 'WB_TREE_ACTUALIZE' EXPORTING tree_name = lv_tree without_crossreference = abap_true with_tcode_index = abap_true. ENDMETHOD. "update_package_tree METHOD create_object. DATA: lv_message TYPE string, lv_class_name TYPE string. lv_class_name = class_name( is_item ). TRY. CREATE OBJECT ri_obj TYPE (lv_class_name) EXPORTING is_item = is_item. CATCH cx_sy_create_object_error. TRY. * 2nd step, try looking for plugins CREATE OBJECT ri_obj TYPE lcl_objects_bridge EXPORTING is_item = is_item. CATCH cx_sy_create_object_error. CONCATENATE 'Object type' is_item-obj_type 'not supported, serialize' INTO lv_message SEPARATED BY space. "#EC NOTEXT _raise lv_message. ENDTRY. ENDTRY. ENDMETHOD. METHOD is_supported. TRY. create_object( is_item ). rv_bool = abap_true. CATCH lcx_exception. rv_bool = abap_false. ENDTRY. ENDMETHOD. METHOD supported_list. DATA: lv_type LIKE LINE OF rt_types, lt_snode TYPE TABLE OF snode. FIELD-SYMBOLS: LIKE LINE OF lt_snode. CALL FUNCTION 'WB_TREE_ACTUALIZE' EXPORTING tree_name = 'PG_ZABAPGIT' without_crossreference = abap_true with_tcode_index = abap_true TABLES p_tree = lt_snode. DELETE lt_snode WHERE type <> 'OPL' OR name NP 'LCL_OBJECT_++++'. LOOP AT lt_snode ASSIGNING . lv_type = -name+11. APPEND lv_type TO rt_types. ENDLOOP. ENDMETHOD. METHOD exists. DATA: li_obj TYPE REF TO lif_object. TRY. li_obj = create_object( is_item ). rv_bool = li_obj->exists( ). CATCH lcx_exception. * ignore all errors and assume the object exists rv_bool = abap_true. ENDTRY. ENDMETHOD. METHOD class_name. CONCATENATE 'LCL_OBJECT_' is_item-obj_type INTO rv_class_name. "#EC NOTEXT IF rv_class_name = 'LCL_OBJECT_INTF'. rv_class_name = 'LCL_OBJECT_CLAS'. ENDIF. ENDMETHOD. "class_name METHOD jump. DATA: li_obj TYPE REF TO lif_object. li_obj = create_object( is_item ). li_obj->jump( ). ENDMETHOD. "jump METHOD delete. DATA: ls_item TYPE ty_item, lt_tadir LIKE it_tadir. FIELD-SYMBOLS: LIKE LINE OF it_tadir. * misuse field KORRNUM to fix deletion sequence lt_tadir[] = it_tadir[]. LOOP AT lt_tadir ASSIGNING . CASE -object. WHEN 'IATU'. -korrnum = '5500'. WHEN 'IARP'. -korrnum = '5510'. WHEN 'IASP'. -korrnum = '5520'. WHEN 'SUSC'. -korrnum = '5000'. WHEN 'TTYP' OR 'TABL' OR 'VIEW'. -korrnum = '7000'. WHEN 'DTEL'. -korrnum = '8000'. WHEN 'DOMA'. -korrnum = '9000'. WHEN 'PROG'. * delete includes after main programs SELECT COUNT(*) FROM reposrc WHERE progname = -obj_name AND r3state = 'A' AND subc = 'I'. IF sy-subrc = 0. -korrnum = '2000'. ELSE. -korrnum = '1000'. ENDIF. WHEN OTHERS. -korrnum = '1000'. ENDCASE. ENDLOOP. resolve_ddic( CHANGING ct_tadir = lt_tadir ). SORT lt_tadir BY korrnum ASCENDING. LOOP AT lt_tadir ASSIGNING . CLEAR ls_item. ls_item-obj_type = -object. ls_item-obj_name = -obj_name. delete_obj( ls_item ). ENDLOOP. ENDMETHOD. "delete METHOD resolve_ddic. * this will make sure the deletion sequence of structures/tables work * in case they have dependencies with .INCLUDE TYPES: BEGIN OF ty_edge, from TYPE ty_item, to TYPE ty_item, END OF ty_edge. DATA: lt_nodes TYPE TABLE OF ty_item, lt_edges TYPE TABLE OF ty_edge, lt_findstrings TYPE TABLE OF rsfind, lv_plus TYPE i VALUE 1, lv_find_obj_cls TYPE euobj-id, lv_index TYPE i, lv_before TYPE i, lt_founds TYPE TABLE OF rsfindlst, lt_scope TYPE STANDARD TABLE OF seu_obj. FIELD-SYMBOLS: LIKE LINE OF ct_tadir, LIKE LINE OF lt_edges, LIKE LINE OF lt_founds, LIKE LINE OF lt_nodes. * build nodes LOOP AT ct_tadir ASSIGNING WHERE object = 'TABL' OR object = 'TTYP'. APPEND INITIAL LINE TO lt_nodes ASSIGNING . -obj_name = -obj_name. -obj_type = -object. ENDLOOP. APPEND 'TABL' TO lt_scope. APPEND 'STRU' TO lt_scope. APPEND 'TTYP' TO lt_scope. * build edges LOOP AT lt_nodes ASSIGNING . CLEAR lt_findstrings. APPEND -obj_name TO lt_findstrings. lv_find_obj_cls = -obj_type. CALL FUNCTION 'RS_EU_CROSSREF' EXPORTING i_find_obj_cls = lv_find_obj_cls TABLES i_findstrings = lt_findstrings o_founds = lt_founds i_scope_object_cls = lt_scope EXCEPTIONS not_executed = 1 not_found = 2 illegal_object = 3 no_cross_for_this_object = 4 batch = 5 batchjob_error = 6 wrong_type = 7 object_not_exist = 8 OTHERS = 9. IF sy-subrc <> 0. CONTINUE. ENDIF. LOOP AT lt_founds ASSIGNING . APPEND INITIAL LINE TO lt_edges ASSIGNING . -from = . -to-obj_name = -object. CASE -object_cls. WHEN 'DS' OR 'DT'. -to-obj_type = 'TABL'. WHEN 'DA'. -to-obj_type = 'TTYP'. WHEN OTHERS. _raise 'resolve_ddic, unknown object_cls'. ENDCASE. ENDLOOP. ENDLOOP. DO. lv_before = lines( lt_nodes ). LOOP AT lt_nodes ASSIGNING . lv_index = sy-tabix. READ TABLE lt_edges WITH KEY from-obj_name = -obj_name from-obj_type = -obj_type TRANSPORTING NO FIELDS. IF sy-subrc <> 0. LOOP AT ct_tadir ASSIGNING WHERE obj_name = -obj_name AND object = -obj_type. -korrnum = -korrnum + lv_plus. CONDENSE -korrnum. ENDLOOP. DELETE lt_edges WHERE to-obj_name = -obj_name AND to-obj_type = -obj_type. DELETE lt_nodes INDEX lv_index. EXIT. " make sure the sequence is fixed ENDIF. ENDLOOP. IF lv_before = lines( lt_nodes ). EXIT. ENDIF. lv_plus = lv_plus + 1. ENDDO. ENDMETHOD. "resolve_ddic METHOD delete_obj. DATA: li_obj TYPE REF TO lif_object. li_obj = create_object( is_item ). li_obj->delete( ). ENDMETHOD. "delete METHOD serialize. DATA: lt_files TYPE ty_files_tt, li_obj TYPE REF TO lif_object, lo_files TYPE REF TO lcl_objects_files. CREATE OBJECT lo_files EXPORTING is_item = is_item. li_obj = create_object( is_item ). li_obj->mo_files = lo_files. li_obj->serialize( ). rt_files = lo_files->get_files( ). * check for duplicates lt_files[] = rt_files[]. SORT lt_files BY path ASCENDING filename ASCENDING. DELETE ADJACENT DUPLICATES FROM lt_files COMPARING path filename. IF lines( lt_files ) <> lines( rt_files ). _raise 'Duplicates'. ENDIF. ENDMETHOD. "serialize METHOD prioritize_deser. FIELD-SYMBOLS: LIKE LINE OF it_results. * PROG before internet services, as the services might use the screens LOOP AT it_results ASSIGNING WHERE obj_type = 'PROG'. APPEND TO rt_results. ENDLOOP. * ISAP has to be handled before ISRP LOOP AT it_results ASSIGNING WHERE obj_type = 'IASP'. APPEND TO rt_results. ENDLOOP. LOOP AT it_results ASSIGNING WHERE obj_type <> 'IASP' AND obj_type <> 'PROG'. APPEND TO rt_results. ENDLOOP. ENDMETHOD. METHOD deserialize. DATA: ls_item TYPE ty_item, lv_cancel TYPE abap_bool, li_obj TYPE REF TO lif_object, lo_files TYPE REF TO lcl_objects_files, lt_results TYPE lcl_file_status=>ty_results_tt. FIELD-SYMBOLS: LIKE LINE OF lt_results. lcl_objects_activation=>clear( ). lt_results = lcl_file_status=>status( it_files = it_files iv_package = iv_package ). DELETE lt_results WHERE match = abap_true. SORT lt_results BY obj_type ASCENDING obj_name ASCENDING. DELETE ADJACENT DUPLICATES FROM lt_results COMPARING obj_type obj_name. lt_results = prioritize_deser( lt_results ). LOOP AT lt_results ASSIGNING . show_progress( iv_current = sy-tabix iv_total = lines( lt_results ) iv_obj_name = -obj_name ). CLEAR ls_item. ls_item-obj_type = -obj_type. ls_item-obj_name = -obj_name. * handle namespaces REPLACE ALL OCCURRENCES OF '#' IN ls_item-obj_name WITH '/'. lv_cancel = check_warning( is_item = ls_item iv_package = iv_package ). IF lv_cancel = abap_true. RETURN. ENDIF. CREATE OBJECT lo_files EXPORTING is_item = ls_item. lo_files->set_files( it_files ). li_obj = create_object( ls_item ). li_obj->mo_files = lo_files. li_obj->deserialize( iv_package ). ENDLOOP. lcl_objects_activation=>activate( ). update_package_tree( iv_package ). ENDMETHOD. "deserialize ENDCLASS. "lcl_object IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_hash DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_hash DEFINITION FINAL. PUBLIC SECTION. TYPES: ty_adler32 TYPE x LENGTH 4. CLASS-METHODS adler32 IMPORTING iv_xstring TYPE xstring RETURNING VALUE(rv_checksum) TYPE ty_adler32. CLASS-METHODS sha1 IMPORTING iv_type TYPE ty_type iv_data TYPE xstring RETURNING VALUE(rv_sha1) TYPE ty_sha1 RAISING lcx_exception. CLASS-METHODS sha1_raw IMPORTING iv_data TYPE xstring RETURNING VALUE(rv_sha1) TYPE ty_sha1 RAISING lcx_exception. ENDCLASS. "lcl_hash DEFINITION *----------------------------------------------------------------------* * CLASS lcl_hash IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_hash IMPLEMENTATION. METHOD adler32. CONSTANTS: lc_adler TYPE i VALUE 65521. DATA: lv_index TYPE i, lv_a TYPE i VALUE 1, lv_b TYPE i VALUE 0, lv_x TYPE x LENGTH 2, lv_ca TYPE c LENGTH 4, lv_cb TYPE c LENGTH 4, lv_char8 TYPE c LENGTH 8. DO xstrlen( iv_xstring ) TIMES. lv_index = sy-index - 1. lv_a = ( lv_a + iv_xstring+lv_index(1) ) MOD lc_adler. lv_b = ( lv_b + lv_a ) MOD lc_adler. ENDDO. lv_x = lv_a. lv_ca = lv_x. lv_x = lv_b. lv_cb = lv_x. CONCATENATE lv_cb lv_ca INTO lv_char8. rv_checksum = lv_char8. ENDMETHOD. "adler32 METHOD sha1_raw. DATA: lv_hash TYPE hash160. CALL FUNCTION 'CALCULATE_HASH_FOR_RAW' EXPORTING data = iv_data IMPORTING hash = lv_hash EXCEPTIONS unknown_alg = 1 param_error = 2 internal_error = 3 OTHERS = 4. IF sy-subrc <> 0. _raise 'Error while calculating SHA1'. ENDIF. rv_sha1 = lv_hash. TRANSLATE rv_sha1 TO LOWER CASE. ENDMETHOD. "sha1_raw METHOD sha1. DATA: lv_len TYPE i, lv_char10 TYPE c LENGTH 10, lv_string TYPE string, lv_xstring TYPE xstring. lv_len = xstrlen( iv_data ). lv_char10 = lv_len. CONDENSE lv_char10. CONCATENATE iv_type lv_char10 INTO lv_string SEPARATED BY space. lv_xstring = lcl_convert=>string_to_xstring_utf8( lv_string ). lv_string = lv_xstring. CONCATENATE lv_string '00' INTO lv_string. lv_xstring = lv_string. CONCATENATE lv_xstring iv_data INTO lv_xstring IN BYTE MODE. rv_sha1 = sha1_raw( lv_xstring ). ENDMETHOD. "sha1 ENDCLASS. "lcl_hash IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_pack IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_git_pack IMPLEMENTATION. METHOD type_and_length. DATA: lv_bits TYPE string, lv_type TYPE string, lv_result TYPE string, lv_c TYPE c, lv_offset TYPE i, lv_x4 TYPE x LENGTH 4, lv_x TYPE x LENGTH 1. CASE is_object-type. WHEN gc_type-commit. lv_type = '001'. WHEN gc_type-tree. lv_type = '010'. WHEN gc_type-blob. lv_type = '011'. WHEN gc_type-ref_d. lv_type = '111'. WHEN OTHERS. _raise 'Unexpected object type while encoding pack'. ENDCASE. lv_x4 = xstrlen( is_object-data ). DO 32 TIMES. GET BIT sy-index OF lv_x4 INTO lv_c. CONCATENATE lv_bits lv_c INTO lv_bits. ENDDO. IF lv_bits(28) = '0000000000000000000000000000'. CONCATENATE '0' lv_type lv_bits+28(4) INTO lv_result. ELSEIF lv_bits(21) = '000000000000000000000'. CONCATENATE '1' lv_type lv_bits+28(4) INTO lv_result. CONCATENATE lv_result '0' lv_bits+21(7) INTO lv_result. ELSEIF lv_bits(14) = '00000000000000'. CONCATENATE '1' lv_type lv_bits+28(4) INTO lv_result. CONCATENATE lv_result '1' lv_bits+21(7) INTO lv_result. CONCATENATE lv_result '0' lv_bits+14(7) INTO lv_result. ELSEIF lv_bits(7) = '0000000'. CONCATENATE '1' lv_type lv_bits+28(4) INTO lv_result. CONCATENATE lv_result '1' lv_bits+21(7) INTO lv_result. CONCATENATE lv_result '1' lv_bits+14(7) INTO lv_result. CONCATENATE lv_result '0' lv_bits+7(7) INTO lv_result. ELSE. * todo, this IF can be refactored, use shifting? _raise 'Todo, encoding length'. ENDIF. * convert bit string to xstring CLEAR lv_x. DO strlen( lv_result ) TIMES. lv_offset = sy-index - 1. IF lv_result+lv_offset(1) = '1'. SET BIT ( lv_offset MOD 8 ) + 1 OF lv_x. ENDIF. IF ( lv_offset + 1 ) MOD 8 = 0. CONCATENATE rv_xstring lv_x INTO rv_xstring IN BYTE MODE. CLEAR lv_x. ENDIF. ENDDO. ENDMETHOD. "type_and_length METHOD get_length. DATA: lv_x TYPE x, lv_length_bits TYPE string, lv_bitbyte TYPE ty_bitbyte. lv_x = cv_data(1). lv_bitbyte = lcl_convert=>x_to_bitbyte( lv_x ). cv_data = cv_data+1. lv_length_bits = lv_bitbyte+4. WHILE lv_bitbyte(1) <> '0'. lv_x = cv_data(1). lv_bitbyte = lcl_convert=>x_to_bitbyte( lv_x ). cv_data = cv_data+1. CONCATENATE lv_bitbyte+1 lv_length_bits INTO lv_length_bits. ENDWHILE. ev_length = lcl_convert=>bitbyte_to_int( lv_length_bits ). ENDMETHOD. "get_length METHOD encode_tree. CONSTANTS: lc_null TYPE x VALUE '00'. DATA: lv_string TYPE string, lt_nodes LIKE it_nodes, lv_hex20 TYPE x LENGTH 20, lv_xstring TYPE xstring. FIELD-SYMBOLS: LIKE LINE OF it_nodes. lt_nodes[] = it_nodes[]. * following has to be done, or unpack will fail on server side SORT lt_nodes BY name ASCENDING. LOOP AT lt_nodes ASSIGNING . CONCATENATE -chmod -name INTO lv_string SEPARATED BY space. lv_xstring = lcl_convert=>string_to_xstring_utf8( lv_string ). lv_hex20 = to_upper( -sha1 ). CONCATENATE rv_data lv_xstring lc_null lv_hex20 INTO rv_data IN BYTE MODE. ENDLOOP. ENDMETHOD. "encode_tree METHOD encode_commit. DATA: lv_string TYPE string, lv_tmp TYPE string, lv_tree_lower TYPE string, lv_parent_lower TYPE string. lv_tree_lower = is_commit-tree. TRANSLATE lv_tree_lower TO LOWER CASE. lv_parent_lower = is_commit-parent. TRANSLATE lv_parent_lower TO LOWER CASE. lv_string = ''. CONCATENATE 'tree' lv_tree_lower INTO lv_tmp SEPARATED BY space. "#EC NOTEXT CONCATENATE lv_string lv_tmp gc_newline INTO lv_string. IF NOT is_commit-parent IS INITIAL. CONCATENATE 'parent' lv_parent_lower INTO lv_tmp SEPARATED BY space. "#EC NOTEXT CONCATENATE lv_string lv_tmp gc_newline INTO lv_string. ENDIF. CONCATENATE 'author' is_commit-author INTO lv_tmp SEPARATED BY space. "#EC NOTEXT CONCATENATE lv_string lv_tmp gc_newline INTO lv_string. CONCATENATE 'committer' is_commit-committer INTO lv_tmp SEPARATED BY space. "#EC NOTEXT CONCATENATE lv_string lv_tmp gc_newline INTO lv_string. CONCATENATE lv_string gc_newline is_commit-body INTO lv_string. rv_data = lcl_convert=>string_to_xstring_utf8( lv_string ). ENDMETHOD. "encode_commit METHOD get_type. DATA: lv_char3 TYPE c LENGTH 3, lv_bitbyte TYPE ty_bitbyte. lv_bitbyte = lcl_convert=>x_to_bitbyte( iv_x ). lv_char3 = lv_bitbyte+1. CASE lv_char3. WHEN '001'. rv_type = gc_type-commit. WHEN '010'. rv_type = gc_type-tree. WHEN '011'. rv_type = gc_type-blob. WHEN '111'. rv_type = gc_type-ref_d. WHEN OTHERS. _raise 'Todo, unknown type'. ENDCASE. ENDMETHOD. "get_type METHOD decode_commit. DATA: lv_string TYPE string, lv_mode TYPE string, lv_len TYPE i, lt_string TYPE TABLE OF string. FIELD-SYMBOLS: LIKE LINE OF lt_string. lv_string = lcl_convert=>xstring_to_string_utf8( iv_data ). SPLIT lv_string AT gc_newline INTO TABLE lt_string. lv_mode = 'tree'. "#EC NOTEXT LOOP AT lt_string ASSIGNING . lv_len = strlen( lv_mode ). IF NOT lv_mode IS INITIAL AND (lv_len) = lv_mode. CASE lv_mode. WHEN 'tree'. rs_commit-tree = +5. lv_mode = 'parent'. "#EC NOTEXT WHEN 'parent'. rs_commit-parent = +7. lv_mode = 'author'. "#EC NOTEXT WHEN 'author'. rs_commit-author = +7. lv_mode = 'committer'. "#EC NOTEXT WHEN 'committer'. rs_commit-committer = +10. CLEAR lv_mode. ENDCASE. ELSEIF lv_mode = 'parent' AND (6) = 'author'. "#EC NOTEXT * first commit doesnt have parent rs_commit-author = +7. lv_mode = 'committer'. "#EC NOTEXT ELSE. * body CONCATENATE rs_commit-body INTO rs_commit-body SEPARATED BY gc_newline. ENDIF. ENDLOOP. * strip first newline IF strlen( rs_commit-body ) >= 2. rs_commit-body = rs_commit-body+2. ENDIF. IF rs_commit-author IS INITIAL OR rs_commit-committer IS INITIAL OR rs_commit-tree IS INITIAL. _raise 'multiple parents? not supported'. ENDIF. ENDMETHOD. "decode_commit METHOD delta_header. DATA: lv_bitbyte TYPE ty_bitbyte, lv_bits TYPE string, lv_x TYPE x. lv_bits = ''. DO. lv_x = cv_delta(1). cv_delta = cv_delta+1. lv_bitbyte = lcl_convert=>x_to_bitbyte( lv_x ). CONCATENATE lv_bitbyte+1 lv_bits INTO lv_bits. IF lv_bitbyte(1) = '0'. EXIT. " current loop ENDIF. ENDDO. ev_header = lcl_convert=>bitbyte_to_int( lv_bits ). ENDMETHOD. "delta_header METHOD delta. DATA: lv_delta TYPE xstring, lv_base TYPE xstring, lv_result TYPE xstring, lv_bitbyte TYPE ty_bitbyte, lv_offset TYPE i, lv_message TYPE string, lv_sha1 TYPE ty_sha1, ls_object LIKE LINE OF ct_objects, lv_len TYPE i, lv_x TYPE x. FIELD-SYMBOLS: LIKE LINE OF ct_objects. lv_delta = is_object-data. * find base READ TABLE ct_objects ASSIGNING WITH KEY sha1 = is_object-sha1. IF sy-subrc <> 0. CONCATENATE 'Base not found,' is_object-sha1 INTO lv_message SEPARATED BY space. "#EC NOTEXT _raise lv_message. ELSE. lv_base = -data. ENDIF. * sanity check IF -type = gc_type-ref_d. _raise 'Delta, base eq delta'. ENDIF. * skip the 2 headers delta_header( CHANGING cv_delta = lv_delta ). delta_header( CHANGING cv_delta = lv_delta ). WHILE xstrlen( lv_delta ) > 0. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_bitbyte = lcl_convert=>x_to_bitbyte( lv_x ). IF lv_bitbyte(1) = '1'. " MSB lv_offset = 0. IF lv_bitbyte+7(1) = '1'. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_offset = lv_x. ENDIF. IF lv_bitbyte+6(1) = '1'. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_offset = lv_offset + lv_x * 256. ENDIF. IF lv_bitbyte+5(1) = '1'. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_offset = lv_offset + lv_x * 65536. ENDIF. IF lv_bitbyte+4(1) = '1'. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_offset = lv_offset + lv_x * 16777216. " hmm, overflow? ENDIF. lv_len = 0. IF lv_bitbyte+3(1) = '1'. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_len = lv_x. ENDIF. IF lv_bitbyte+2(1) = '1'. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_len = lv_len + lv_x * 256. ENDIF. IF lv_bitbyte+1(1) = '1'. lv_x = lv_delta(1). lv_delta = lv_delta+1. lv_len = lv_len + lv_x * 65536. ENDIF. IF lv_len = 0. lv_len = 65536. ENDIF. CONCATENATE lv_result lv_base+lv_offset(lv_len) INTO lv_result IN BYTE MODE. ELSE. " lv_bitbyte(1) = '0' * insert from delta lv_len = lv_x. CONCATENATE lv_result lv_delta(lv_len) INTO lv_result IN BYTE MODE. lv_delta = lv_delta+lv_len. ENDIF. ENDWHILE. lv_sha1 = lcl_hash=>sha1( iv_type = -type iv_data = lv_result ). CLEAR ls_object. ls_object-sha1 = lv_sha1. ls_object-type = -type. ls_object-data = lv_result. APPEND ls_object TO ct_objects. ENDMETHOD. "delta METHOD decode_deltas. DATA: ls_object LIKE LINE OF ct_objects, lt_deltas LIKE ct_objects. LOOP AT ct_objects INTO ls_object WHERE type = gc_type-ref_d. DELETE ct_objects INDEX sy-tabix. APPEND ls_object TO lt_deltas. ENDLOOP. LOOP AT lt_deltas INTO ls_object. delta( EXPORTING is_object = ls_object CHANGING ct_objects = ct_objects ). ENDLOOP. ENDMETHOD. "decode_deltas METHOD decode_tree. CONSTANTS: lc_sha_length TYPE i VALUE 20, lc_null TYPE x VALUE '00'. DATA: lv_xstring TYPE xstring, lv_chmod TYPE string, lv_name TYPE string, lv_string TYPE string, lv_len TYPE i, lv_offset TYPE i, lv_cursor TYPE i, ls_node TYPE ty_node, lv_start TYPE i. DO. IF lv_cursor >= xstrlen( iv_data ). EXIT. " current loop ENDIF. IF iv_data+lv_cursor(1) = lc_null. lv_len = lv_cursor - lv_start. lv_xstring = iv_data+lv_start(lv_len). lv_string = lcl_convert=>xstring_to_string_utf8( lv_xstring ). SPLIT lv_string AT space INTO lv_chmod lv_name. lv_offset = lv_cursor + 1. CLEAR ls_node. ls_node-chmod = lv_chmod. IF ls_node-chmod <> gc_chmod-dir AND ls_node-chmod <> gc_chmod-file. _raise 'Unknown chmod'. ENDIF. ls_node-name = lv_name. ls_node-sha1 = iv_data+lv_offset(lc_sha_length). TRANSLATE ls_node-sha1 TO LOWER CASE. APPEND ls_node TO rt_nodes. lv_start = lv_cursor + 1 + lc_sha_length. lv_cursor = lv_start. ELSE. lv_cursor = lv_cursor + 1. ENDIF. ENDDO. ENDMETHOD. "decode_tree METHOD decode. DATA: lv_x TYPE x, lv_data TYPE xstring, lv_type TYPE c LENGTH 6, lv_zlib TYPE x LENGTH 2, lv_objects TYPE i, lv_len TYPE i, lv_sha1 TYPE ty_sha1, lv_ref_delta TYPE ty_sha1, lv_adler32 TYPE lcl_hash=>ty_adler32, lv_compressed TYPE xstring, lv_compressed_len TYPE i, lv_decompress_len TYPE i, lv_decompressed TYPE xstring, lv_xstring TYPE xstring, lv_expected TYPE i, ls_object LIKE LINE OF rt_objects, ls_data TYPE lcl_zlib=>ty_decompress. lv_data = iv_data. * header IF NOT xstrlen( lv_data ) > 4 OR lv_data(4) <> c_pack_start. _raise 'Unexpected pack header'. ENDIF. lv_data = lv_data+4. * version IF lv_data(4) <> c_version. _raise 'Version not supported'. ENDIF. lv_data = lv_data+4. * number of objects lv_xstring = lv_data(4). lv_objects = lcl_convert=>xstring_to_int( lv_xstring ). lv_data = lv_data+4. DO lv_objects TIMES. lv_x = lv_data(1). lv_type = get_type( lv_x ). get_length( IMPORTING ev_length = lv_expected CHANGING cv_data = lv_data ). IF lv_type = gc_type-ref_d. lv_ref_delta = lv_data(20). lv_data = lv_data+20. ENDIF. * strip header, '789C', CMF + FLG lv_zlib = lv_data(2). IF lv_zlib <> c_zlib AND lv_zlib <> c_zlib_hmm. _raise 'Unexpected zlib header'. ENDIF. lv_data = lv_data+2. ******************************* IF lv_zlib = c_zlib. cl_abap_gzip=>decompress_binary( EXPORTING gzip_in = lv_data IMPORTING raw_out = lv_decompressed raw_out_len = lv_decompress_len ). IF lv_expected <> lv_decompress_len. _raise 'Decompression falied'. ENDIF. cl_abap_gzip=>compress_binary( EXPORTING raw_in = lv_decompressed IMPORTING gzip_out = lv_compressed gzip_out_len = lv_compressed_len ). IF lv_compressed(lv_compressed_len) <> lv_data(lv_compressed_len). _raise 'Compressed data doesnt match'. ENDIF. lv_data = lv_data+lv_compressed_len. ELSEIF lv_zlib = c_zlib_hmm. * cl_abap_gzip copmression works for header '789C', but does not work for * '7801', call custom implementation of DEFLATE algorithm. * The custom implementation could handle both, but most likely the kernel * implementation runs faster than the custom ABAP. ls_data = lcl_zlib=>decompress( lv_data ). lv_compressed_len = ls_data-compressed_len. lv_decompressed = ls_data-raw. IF lv_compressed_len IS INITIAL. _raise 'Decompression falied :o/'. ENDIF. lv_data = lv_data+lv_compressed_len. lv_adler32 = lcl_hash=>adler32( lv_decompressed ). IF lv_data(4) <> lv_adler32. lv_data = lv_data+1. ENDIF. IF lv_data(4) <> lv_adler32. lv_data = lv_data+1. ENDIF. IF lv_data(4) <> lv_adler32. _raise 'Wrong Adler checksum'. ENDIF. ENDIF. lv_data = lv_data+4. " skip adler checksum ************************* CLEAR ls_object. IF lv_type = gc_type-ref_d. ls_object-sha1 = lv_ref_delta. TRANSLATE ls_object-sha1 TO LOWER CASE. ELSE. ls_object-sha1 = lcl_hash=>sha1( iv_type = lv_type iv_data = lv_decompressed ). ENDIF. ls_object-type = lv_type. ls_object-data = lv_decompressed. APPEND ls_object TO rt_objects. ENDDO. * check SHA1 at end of pack lv_len = xstrlen( iv_data ) - 20. lv_xstring = iv_data(lv_len). lv_sha1 = lcl_hash=>sha1_raw( lv_xstring ). IF to_upper( lv_sha1 ) <> lv_data. _raise 'SHA1 at end of pack doesnt match'. ENDIF. ENDMETHOD. "decode METHOD encode. DATA: lv_sha1 TYPE x LENGTH 20, lv_adler32 TYPE lcl_hash=>ty_adler32, lv_len TYPE i, lv_compressed TYPE xstring, lv_xstring TYPE xstring. FIELD-SYMBOLS: LIKE LINE OF it_objects. rv_data = c_pack_start. CONCATENATE rv_data c_version INTO rv_data IN BYTE MODE. lv_len = lines( it_objects ). lv_xstring = lcl_convert=>int_to_xstring( iv_i = lv_len iv_length = 4 ). CONCATENATE rv_data lv_xstring INTO rv_data IN BYTE MODE. LOOP AT it_objects ASSIGNING . lv_xstring = type_and_length( ). CONCATENATE rv_data lv_xstring INTO rv_data IN BYTE MODE. cl_abap_gzip=>compress_binary( EXPORTING raw_in = -data IMPORTING gzip_out = lv_compressed ). CONCATENATE rv_data c_zlib lv_compressed INTO rv_data IN BYTE MODE. lv_adler32 = lcl_hash=>adler32( -data ). CONCATENATE rv_data lv_adler32 INTO rv_data IN BYTE MODE. ENDLOOP. lv_sha1 = to_upper( lcl_hash=>sha1_raw( rv_data ) ). CONCATENATE rv_data lv_sha1 INTO rv_data IN BYTE MODE. ENDMETHOD. "encode ENDCLASS. "lcl_pack IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_persistence DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_persistence DEFINITION FINAL. * there is currently no locking, so it is theoretically possible * for a user to overwrite another users changes. * the risk is minimized by always reading before updating PUBLIC SECTION. TYPES: BEGIN OF ty_repo_persi, url TYPE string, branch_name TYPE string, sha1 TYPE ty_sha1, package TYPE devclass, offline TYPE sap_bool, END OF ty_repo_persi. TYPES: ty_repos_persi_tt TYPE STANDARD TABLE OF ty_repo_persi WITH DEFAULT KEY. METHODS list RETURNING VALUE(rt_repos) TYPE ty_repos_persi_tt RAISING lcx_exception. METHODS update IMPORTING iv_url TYPE ty_repo_persi-url iv_branch_name TYPE ty_repo_persi-branch_name iv_branch TYPE ty_sha1 RAISING lcx_exception. METHODS add IMPORTING iv_url TYPE string iv_branch_name TYPE string iv_branch TYPE ty_sha1 OPTIONAL iv_package TYPE devclass iv_offline TYPE sap_bool DEFAULT abap_false RAISING lcx_exception. METHODS delete IMPORTING iv_url TYPE ty_repo_persi-url iv_branch_name TYPE ty_repo_persi-branch_name RAISING lcx_exception. PRIVATE SECTION. METHODS read_text_online RETURNING VALUE(rt_repos) TYPE ty_repos_persi_tt RAISING lcx_exception. METHODS save_text_online IMPORTING it_repos TYPE ty_repos_persi_tt RAISING lcx_exception. METHODS header_online RETURNING VALUE(rs_header) TYPE thead. METHODS read_text_offline RETURNING VALUE(rt_repos) TYPE ty_repos_persi_tt RAISING lcx_exception. METHODS save_text_offline IMPORTING it_repos TYPE ty_repos_persi_tt RAISING lcx_exception. METHODS header_offline RETURNING VALUE(rs_header) TYPE thead. METHODS read_text IMPORTING is_header TYPE thead RETURNING VALUE(rt_lines) TYPE tlinetab RAISING lcx_exception. METHODS save_text IMPORTING is_header TYPE thead it_lines TYPE tlinetab RAISING lcx_exception. ENDCLASS. "lcl_persistence DEFINITION *----------------------------------------------------------------------* * CLASS lcl_persistence IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_persistence IMPLEMENTATION. METHOD save_text. CALL FUNCTION 'SAVE_TEXT' EXPORTING header = is_header TABLES lines = it_lines EXCEPTIONS id = 1 language = 2 name = 3 object = 4 OTHERS = 5. IF sy-subrc <> 0. ROLLBACK WORK. _raise 'error from SAVE_TEXT'. ENDIF. ENDMETHOD. "save_text METHOD header_online. rs_header-tdid = 'ST'. rs_header-tdspras = gc_english. rs_header-tdname = 'ZABAPGIT'. rs_header-tdobject = 'TEXT'. ENDMETHOD. "header METHOD header_offline. rs_header-tdid = 'ST'. rs_header-tdspras = gc_english. rs_header-tdname = 'ZABAPGIT_OFFLINE'. rs_header-tdobject = 'TEXT'. ENDMETHOD. "header_offline METHOD delete. DATA: lt_repos TYPE ty_repos_persi_tt. lt_repos = list( ). DELETE lt_repos WHERE url = iv_url AND branch_name = iv_branch_name. IF sy-subrc <> 0. _raise 'repo not found, delete'. ENDIF. save_text_online( lt_repos ). save_text_offline( lt_repos ). ENDMETHOD. "delete METHOD save_text_online. DATA: lt_lines TYPE TABLE OF tline. FIELD-SYMBOLS: LIKE LINE OF it_repos, LIKE LINE OF lt_lines. LOOP AT it_repos ASSIGNING WHERE offline = abap_false. APPEND INITIAL LINE TO lt_lines ASSIGNING . -tdformat = '*'. -tdline = -url. APPEND INITIAL LINE TO lt_lines ASSIGNING . -tdformat = '*'. -tdline = -branch_name. APPEND INITIAL LINE TO lt_lines ASSIGNING . -tdformat = '*'. -tdline = -sha1. APPEND INITIAL LINE TO lt_lines ASSIGNING . -tdformat = '*'. -tdline = -package. ENDLOOP. save_text( is_header = header_online( ) it_lines = lt_lines ). COMMIT WORK. ENDMETHOD. "save_text METHOD save_text_offline. DATA: lt_lines TYPE TABLE OF tline. FIELD-SYMBOLS: LIKE LINE OF it_repos, LIKE LINE OF lt_lines. LOOP AT it_repos ASSIGNING WHERE offline = abap_true. APPEND INITIAL LINE TO lt_lines ASSIGNING . -tdformat = '*'. -tdline = -url. APPEND INITIAL LINE TO lt_lines ASSIGNING . -tdformat = '*'. -tdline = -package. ENDLOOP. save_text( is_header = header_offline( ) it_lines = lt_lines ). COMMIT WORK. ENDMETHOD. "save_text_offline METHOD add. DATA: lt_repos TYPE ty_repos_persi_tt. FIELD-SYMBOLS: LIKE LINE OF lt_repos. ASSERT NOT iv_url IS INITIAL. ASSERT NOT iv_package IS INITIAL. lt_repos = list( ). READ TABLE lt_repos WITH KEY url = iv_url branch_name = iv_branch_name TRANSPORTING NO FIELDS. IF sy-subrc = 0. _raise 'already inserted'. ENDIF. APPEND INITIAL LINE TO lt_repos ASSIGNING . -url = iv_url. -branch_name = iv_branch_name. -sha1 = iv_branch. -package = iv_package. -offline = iv_offline. save_text_online( lt_repos ). save_text_offline( lt_repos ). ENDMETHOD. "insert METHOD update. DATA: lt_repos TYPE ty_repos_persi_tt. FIELD-SYMBOLS: LIKE LINE OF lt_repos. IF iv_branch IS INITIAL. _raise 'update, sha empty'. ENDIF. lt_repos = list( ). READ TABLE lt_repos ASSIGNING WITH KEY url = iv_url branch_name = iv_branch_name. IF sy-subrc <> 0. _raise 'persist update, repo not found'. ENDIF. -sha1 = iv_branch. save_text_online( lt_repos ). ENDMETHOD. "update METHOD list. CLEAR rt_repos. APPEND LINES OF read_text_online( ) TO rt_repos. APPEND LINES OF read_text_offline( ) TO rt_repos. ENDMETHOD. "list METHOD read_text. CALL FUNCTION 'READ_TEXT' EXPORTING id = is_header-tdid language = is_header-tdspras name = is_header-tdname object = is_header-tdobject TABLES lines = rt_lines EXCEPTIONS id = 1 language = 2 name = 3 not_found = 4 object = 5 reference_check = 6 wrong_access_to_archive = 7 OTHERS = 8. IF sy-subrc = 4. RETURN. ELSEIF sy-subrc <> 0. _raise 'Error from READ_TEXT'. ENDIF. ENDMETHOD. "read_text METHOD read_text_online. DATA: lt_lines TYPE TABLE OF tline, lv_step TYPE i, ls_repo TYPE ty_repo_persi. FIELD-SYMBOLS: LIKE LINE OF lt_lines. lt_lines = read_text( header_online( ) ). IF lines( lt_lines ) = 0. RETURN. ENDIF. IF lines( lt_lines ) MOD 4 <> 0. * if this happens, delete text ZABAPGIT in SO10 or edit the text * manually, so it contains the right information _raise 'Persistence, text broken'. ENDIF. CLEAR ls_repo. LOOP AT lt_lines ASSIGNING . lv_step = lv_step + 1. CASE lv_step. WHEN 4. ls_repo-package = -tdline. IF ls_repo-url IS INITIAL OR ls_repo-branch_name IS INITIAL. _raise 'Persistence, text broken 2'. ENDIF. APPEND ls_repo TO rt_repos. CLEAR ls_repo. lv_step = 0. WHEN 3. ls_repo-sha1 = -tdline. WHEN 2. ls_repo-branch_name = -tdline. WHEN 1. ls_repo-url = -tdline. WHEN OTHERS. ASSERT 1 = 0. ENDCASE. ENDLOOP. ENDMETHOD. "list METHOD read_text_offline. DATA: lt_lines TYPE TABLE OF tline, ls_repo TYPE ty_repo_persi. FIELD-SYMBOLS: LIKE LINE OF lt_lines. lt_lines = read_text( header_offline( ) ). IF lines( lt_lines ) = 0. RETURN. ENDIF. IF lines( lt_lines ) MOD 2 <> 0. * if this happens, delete text ZABAPGIT in SO10 or edit the text * manually, so it contains the right information _raise 'Persistence, text broken'. ENDIF. CLEAR ls_repo. LOOP AT lt_lines ASSIGNING . IF -tdline IS INITIAL. _raise 'Persistence, text broken'. ENDIF. IF ls_repo-url IS INITIAL. ls_repo-url = -tdline. CONTINUE. " current loop ENDIF. ls_repo-package = -tdline. ls_repo-offline = abap_true. APPEND ls_repo TO rt_repos. CLEAR ls_repo. ENDLOOP. ENDMETHOD. "list ENDCLASS. "lcl_persistence IMPLEMENTATION CLASS lcl_repo DEFINITION ABSTRACT. PUBLIC SECTION. TYPES: ty_key TYPE i. METHODS: constructor IMPORTING iv_key TYPE ty_key is_data TYPE lcl_persistence=>ty_repo_persi, get_key RETURNING VALUE(rv_key) TYPE ty_key, get_name RETURNING VALUE(rv_name) TYPE string RAISING lcx_exception, get_package RETURNING VALUE(rv_package) TYPE lcl_persistence=>ty_repo_persi-package, delete RAISING lcx_exception, add RAISING lcx_exception, refresh RAISING lcx_exception, render RETURNING VALUE(rv_html) TYPE string RAISING lcx_exception. PROTECTED SECTION. DATA: mv_key TYPE ty_key, ms_data TYPE lcl_persistence=>ty_repo_persi. ENDCLASS. CLASS lcl_repo_online DEFINITION INHERITING FROM lcl_repo FINAL. PUBLIC SECTION. METHODS: render REDEFINITION, refresh REDEFINITION, constructor IMPORTING iv_key TYPE ty_key is_data TYPE lcl_persistence=>ty_repo_persi RAISING lcx_exception, get_url RETURNING VALUE(rv_url) TYPE lcl_persistence=>ty_repo_persi-url, get_branch_name RETURNING VALUE(rv_name) TYPE lcl_persistence=>ty_repo_persi-branch_name, get_sha1_local RETURNING VALUE(rv_sha1) TYPE lcl_persistence=>ty_repo_persi-sha1, get_sha1_remote RETURNING VALUE(rv_sha1) TYPE lcl_persistence=>ty_repo_persi-sha1, get_files RETURNING VALUE(rt_files) TYPE ty_files_tt, get_objects RETURNING VALUE(rt_objects) TYPE lcl_git_pack=>ty_objects_tt, deserialize RAISING lcx_exception, status RETURNING VALUE(rt_results) TYPE lcl_file_status=>ty_results_tt RAISING lcx_exception, push IMPORTING is_comment TYPE ty_comment it_files TYPE ty_files_tt RAISING lcx_exception. PRIVATE SECTION. DATA: mt_files TYPE ty_files_tt, mt_objects TYPE lcl_git_pack=>ty_objects_tt, mv_branch TYPE ty_sha1. METHODS: set_sha1 IMPORTING iv_sha1 TYPE ty_sha1 RAISING lcx_exception. ENDCLASS. CLASS lcl_repo_offline DEFINITION INHERITING FROM lcl_repo FINAL. PUBLIC SECTION. METHODS: render REDEFINITION. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_porcelain DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_git_porcelain DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS pull IMPORTING io_repo TYPE REF TO lcl_repo_online EXPORTING et_files TYPE ty_files_tt et_objects TYPE lcl_git_pack=>ty_objects_tt ev_branch TYPE ty_sha1 RAISING lcx_exception. CLASS-METHODS push IMPORTING io_repo TYPE REF TO lcl_repo_online is_comment TYPE ty_comment it_files TYPE ty_files_tt RETURNING VALUE(rv_branch) TYPE ty_sha1 RAISING lcx_exception. PRIVATE SECTION. CLASS-METHODS walk IMPORTING it_objects TYPE lcl_git_pack=>ty_objects_tt iv_sha1 TYPE ty_sha1 iv_path TYPE string CHANGING ct_files TYPE ty_files_tt RAISING lcx_exception. CLASS-METHODS root_tree IMPORTING it_objects TYPE lcl_git_pack=>ty_objects_tt iv_branch TYPE ty_sha1 RETURNING VALUE(rt_nodes) TYPE lcl_git_pack=>ty_nodes_tt RAISING lcx_exception. CLASS-METHODS receive_pack IMPORTING is_comment TYPE ty_comment io_repo TYPE REF TO lcl_repo_online it_nodes TYPE lcl_git_pack=>ty_nodes_tt it_files TYPE ty_files_tt iv_branch TYPE ty_sha1 RETURNING VALUE(rv_branch) TYPE ty_sha1 RAISING lcx_exception. ENDCLASS. "lcl_porcelain DEFINITION *----------------------------------------------------------------------* * CLASS lcl_view DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_gui DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS run RAISING lcx_exception. CLASS-METHODS on_event FOR EVENT sapevent OF cl_gui_html_viewer IMPORTING action frame getdata postdata query_table. "#EC NEEDED CLASS-METHODS render_repo_online IMPORTING io_repo TYPE REF TO lcl_repo_online RETURNING VALUE(rv_html) TYPE string RAISING lcx_exception. CLASS-METHODS render_repo_offline IMPORTING io_repo TYPE REF TO lcl_repo_offline RETURNING VALUE(rv_html) TYPE string RAISING lcx_exception. PRIVATE SECTION. CLASS-DATA go_html_viewer TYPE REF TO cl_gui_html_viewer. CLASS-METHODS view IMPORTING iv_html TYPE string. CLASS-METHODS render RETURNING VALUE(rv_html) TYPE string RAISING lcx_exception. CLASS-METHODS render_css RETURNING VALUE(rv_html) TYPE string. CLASS-METHODS render_header RETURNING VALUE(rv_html) TYPE string. CLASS-METHODS render_menu RETURNING VALUE(rv_html) TYPE string. CLASS-METHODS render_footer RETURNING VALUE(rv_html) TYPE string. CLASS-METHODS install IMPORTING iv_url TYPE string RAISING lcx_exception. CLASS-METHODS newoffline RAISING lcx_exception. CLASS-METHODS add IMPORTING is_item TYPE ty_item iv_key TYPE lcl_repo=>ty_key RAISING lcx_exception. CLASS-METHODS uninstall IMPORTING iv_key TYPE lcl_repo=>ty_key RAISING lcx_exception. CLASS-METHODS remove IMPORTING iv_key TYPE lcl_repo=>ty_key RAISING lcx_exception. CLASS-METHODS pull IMPORTING iv_key TYPE lcl_repo=>ty_key RAISING lcx_exception. CLASS-METHODS commit IMPORTING iv_key TYPE lcl_repo=>ty_key RAISING lcx_exception. CLASS-METHODS diff IMPORTING is_result TYPE lcl_file_status=>ty_result iv_key TYPE lcl_repo=>ty_key RAISING lcx_exception. CLASS-METHODS render_diff IMPORTING is_result TYPE lcl_file_status=>ty_result io_diff TYPE REF TO lcl_diff. CLASS-METHODS file_encode IMPORTING iv_key TYPE lcl_repo=>ty_key is_file TYPE lcl_file_status=>ty_result RETURNING VALUE(rv_string) TYPE string. CLASS-METHODS file_decode IMPORTING iv_string TYPE clike EXPORTING ev_key TYPE lcl_repo=>ty_key es_file TYPE lcl_file_status=>ty_result RAISING lcx_exception. CLASS-METHODS popup_comment RETURNING VALUE(rs_comment) TYPE ty_comment RAISING lcx_exception. CLASS-METHODS get_logo_src RETURNING VALUE(rv_src) TYPE string. CLASS-METHODS zipexport RAISING lcx_exception. ENDCLASS. "lcl_gui DEFINITION CLASS lcl_repo_offline IMPLEMENTATION. METHOD render. rv_html = lcl_gui=>render_repo_offline( me ). ENDMETHOD. ENDCLASS. CLASS lcl_repo_srv DEFINITION FINAL. PUBLIC SECTION. TYPES: ty_repo_tt TYPE STANDARD TABLE OF REF TO lcl_repo WITH DEFAULT KEY. CLASS-METHODS class_constructor. CLASS-METHODS list RETURNING VALUE(rt_list) TYPE ty_repo_tt RAISING lcx_exception. CLASS-METHODS refresh IMPORTING iv_show_progress TYPE abap_bool DEFAULT abap_true RAISING lcx_exception. CLASS-METHODS new_online IMPORTING iv_url TYPE string iv_branch_name TYPE string iv_package TYPE devclass RETURNING VALUE(ro_repo) TYPE REF TO lcl_repo_online RAISING lcx_exception. CLASS-METHODS new_offline IMPORTING iv_url TYPE string iv_package TYPE devclass RETURNING VALUE(ro_repo) TYPE REF TO lcl_repo_offline RAISING lcx_exception. CLASS-METHODS add IMPORTING io_repo TYPE REF TO lcl_repo RAISING lcx_exception. CLASS-METHODS delete IMPORTING io_repo TYPE REF TO lcl_repo RAISING lcx_exception. CLASS-METHODS get IMPORTING iv_key TYPE lcl_repo=>ty_key RETURNING VALUE(ro_repo) TYPE REF TO lcl_repo. PRIVATE SECTION. CLASS-DATA: gv_init TYPE abap_bool VALUE abap_false, go_persistence TYPE REF TO lcl_persistence, gt_list TYPE ty_repo_tt. CLASS-METHODS: validate_package IMPORTING iv_package TYPE devclass RAISING lcx_exception, show_progress IMPORTING iv_current TYPE i iv_total TYPE i iv_text TYPE string. ENDCLASS. CLASS lcl_repo_online IMPLEMENTATION. METHOD constructor. super->constructor( iv_key = iv_key is_data = is_data ). refresh( ). ENDMETHOD. METHOD status. rt_results = lcl_file_status=>status( it_files = mt_files iv_package = get_package( ) ). ENDMETHOD. METHOD deserialize. lcl_objects=>deserialize( it_files = mt_files iv_package = get_package( ) ). lcl_repo_srv=>add( me ). set_sha1( mv_branch ). ENDMETHOD. METHOD refresh. lcl_git_porcelain=>pull( EXPORTING io_repo = me IMPORTING et_files = mt_files et_objects = mt_objects ev_branch = mv_branch ). ENDMETHOD. METHOD get_sha1_remote. rv_sha1 = mv_branch. ENDMETHOD. METHOD get_files. rt_files = mt_files. ENDMETHOD. METHOD get_objects. rt_objects = mt_objects. ENDMETHOD. METHOD render. rv_html = lcl_gui=>render_repo_online( me ). ENDMETHOD. METHOD get_url. rv_url = ms_data-url. ENDMETHOD. METHOD get_branch_name. rv_name = ms_data-branch_name. ENDMETHOD. METHOD get_sha1_local. rv_sha1 = ms_data-sha1. ENDMETHOD. METHOD push. DATA: lv_branch TYPE ty_sha1. lv_branch = lcl_git_porcelain=>push( is_comment = is_comment io_repo = me it_files = it_files ). set_sha1( lv_branch ). refresh( ). ENDMETHOD. METHOD set_sha1. DATA: lo_persistence TYPE REF TO lcl_persistence. CREATE OBJECT lo_persistence. lo_persistence->update( iv_url = ms_data-url iv_branch_name = ms_data-branch_name iv_branch = iv_sha1 ). ms_data-sha1 = iv_sha1. ENDMETHOD. ENDCLASS. CLASS lcl_repo IMPLEMENTATION. METHOD constructor. ms_data = is_data. mv_key = iv_key. ENDMETHOD. METHOD render. * to be implemented in subclass ASSERT 1 = 0. ENDMETHOD. METHOD delete. DATA: lo_persistence TYPE REF TO lcl_persistence. CREATE OBJECT lo_persistence. lo_persistence->delete( iv_url = ms_data-url iv_branch_name = ms_data-branch_name ). ENDMETHOD. METHOD refresh. * redefined in LCL_REPO_ONLINE RETURN. ENDMETHOD. METHOD add. DATA: lo_persistence TYPE REF TO lcl_persistence. CREATE OBJECT lo_persistence. lo_persistence->add( iv_url = ms_data-url iv_branch_name = ms_data-branch_name iv_branch = ms_data-sha1 iv_package = ms_data-package iv_offline = ms_data-offline ). ENDMETHOD. METHOD get_package. rv_package = ms_data-package. ENDMETHOD. METHOD get_key. rv_key = mv_key. ENDMETHOD. METHOD get_name. IF ms_data-offline = abap_true. rv_name = ms_data-url. ELSE. rv_name = lcl_url=>name( ms_data-url ). ENDIF. ENDMETHOD. ENDCLASS. CLASS lcl_repo_srv IMPLEMENTATION. METHOD class_constructor. CREATE OBJECT go_persistence. ENDMETHOD. METHOD list. IF gv_init = abap_false. refresh( ). ENDIF. rt_list = gt_list. ENDMETHOD. METHOD get. FIELD-SYMBOLS: LIKE LINE OF gt_list. LOOP AT gt_list ASSIGNING . IF ->get_key( ) = iv_key. ro_repo = . RETURN. ENDIF. ENDLOOP. ASSERT 1 = 0. ENDMETHOD. METHOD refresh. DATA: lt_list TYPE lcl_persistence=>ty_repos_persi_tt, lv_index TYPE i, lo_online TYPE REF TO lcl_repo_online, lo_offline TYPE REF TO lcl_repo_offline. FIELD-SYMBOLS: LIKE LINE OF lt_list. CLEAR gt_list. lt_list = go_persistence->list( ). LOOP AT lt_list ASSIGNING . lv_index = sy-tabix. IF iv_show_progress = abap_true. show_progress( iv_current = sy-tabix iv_total = lines( lt_list ) iv_text = -url ). ENDIF. IF -offline = abap_false. CREATE OBJECT lo_online EXPORTING iv_key = lv_index is_data = . APPEND lo_online TO gt_list. ELSE. CREATE OBJECT lo_offline EXPORTING iv_key = lv_index is_data = . APPEND lo_offline TO gt_list. ENDIF. ENDLOOP. gv_init = abap_true. ENDMETHOD. METHOD new_online. DATA: ls_repo_persi TYPE lcl_persistence=>ty_repo_persi. validate_package( iv_package ). ls_repo_persi-url = iv_url. ls_repo_persi-branch_name = iv_branch_name. ls_repo_persi-package = iv_package. CREATE OBJECT ro_repo EXPORTING iv_key = lines( gt_list ) + 1 is_data = ls_repo_persi. ENDMETHOD. METHOD new_offline. DATA: ls_repo_persi TYPE lcl_persistence=>ty_repo_persi. validate_package( iv_package ). ls_repo_persi-url = iv_url. ls_repo_persi-package = iv_package. ls_repo_persi-offline = abap_true. CREATE OBJECT ro_repo EXPORTING iv_key = lines( gt_list ) + 1 is_data = ls_repo_persi. add( ro_repo ). ENDMETHOD. METHOD add. DATA: lo_repo LIKE LINE OF gt_list. LOOP AT gt_list INTO lo_repo. IF lo_repo->get_key( ) = io_repo->get_key( ). IF lo_repo = io_repo. RETURN. ENDIF. _raise 'identical keys'. ENDIF. ENDLOOP. io_repo->add( ). APPEND io_repo TO gt_list. ENDMETHOD. METHOD show_progress. DATA: lv_text TYPE c LENGTH 100, lv_pct TYPE i, lv_f TYPE f. lv_text = iv_text. lv_f = ( iv_current / iv_total ) * 100. lv_pct = lv_f. IF lv_pct = 100. lv_pct = 99. ENDIF. CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR' EXPORTING percentage = lv_pct text = lv_text. ENDMETHOD. METHOD validate_package. DATA: lv_devclass TYPE tdevc-devclass, lt_repos TYPE lcl_persistence=>ty_repos_persi_tt. IF iv_package IS INITIAL. _raise 'add, package empty'. ENDIF. IF iv_package = '$TMP'. _raise 'not possible to use $TMP, create new (local) package'. ENDIF. SELECT SINGLE devclass FROM tdevc INTO lv_devclass WHERE devclass = iv_package AND as4user <> 'SAP'. "#EC CI_GENBUFF IF sy-subrc <> 0. _raise 'package not found or not allowed'. ENDIF. * make sure its not already in use for a different repository lt_repos = go_persistence->list( ). READ TABLE lt_repos WITH KEY package = iv_package TRANSPORTING NO FIELDS. IF sy-subrc = 0. _raise 'Package already in use'. ENDIF. ENDMETHOD. METHOD delete. io_repo->delete( ). DELETE TABLE gt_list FROM io_repo. ASSERT sy-subrc = 0. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS lcl_transport DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_git_transport DEFINITION FINAL. PUBLIC SECTION. TYPES: BEGIN OF ty_branch_list, sha1 TYPE ty_sha1, name TYPE string, END OF ty_branch_list. TYPES: ty_branch_list_tt TYPE STANDARD TABLE OF ty_branch_list WITH DEFAULT KEY. * remote to local CLASS-METHODS upload_pack IMPORTING io_repo TYPE REF TO lcl_repo_online EXPORTING ev_pack TYPE xstring ev_branch TYPE ty_sha1 RAISING lcx_exception. * local to remote CLASS-METHODS receive_pack IMPORTING io_repo TYPE REF TO lcl_repo_online iv_commit TYPE ty_sha1 iv_pack TYPE xstring RAISING lcx_exception. CLASS-METHODS branches IMPORTING iv_url TYPE string RETURNING VALUE(rt_branch_list) TYPE ty_branch_list_tt RAISING lcx_exception. CLASS-METHODS class_constructor. PRIVATE SECTION. CLASS-DATA: gv_agent TYPE string. CONSTANTS: BEGIN OF c_service, receive TYPE string VALUE 'receive', "#EC NOTEXT upload TYPE string VALUE 'upload', "#EC NOTEXT END OF c_service. CLASS-METHODS branch_list IMPORTING iv_url TYPE string iv_service TYPE string EXPORTING ei_client TYPE REF TO if_http_client et_branch_list TYPE ty_branch_list_tt RAISING lcx_exception. CLASS-METHODS pkt_string IMPORTING iv_string TYPE string RETURNING VALUE(rv_pkt) TYPE string RAISING lcx_exception. CLASS-METHODS find_branch IMPORTING io_repo TYPE REF TO lcl_repo_online iv_service TYPE string EXPORTING ei_client TYPE REF TO if_http_client ev_branch TYPE ty_sha1 RAISING lcx_exception. CLASS-METHODS parse EXPORTING ev_pack TYPE xstring CHANGING cv_data TYPE xstring. CLASS-METHODS length_utf8_hex IMPORTING iv_data TYPE xstring RETURNING VALUE(rv_len) TYPE i. CLASS-METHODS parse_branch_list IMPORTING iv_data TYPE string RETURNING VALUE(rt_list) TYPE ty_branch_list_tt RAISING lcx_exception. CLASS-METHODS set_headers IMPORTING io_repo TYPE REF TO lcl_repo_online iv_service TYPE string ii_client TYPE REF TO if_http_client RAISING lcx_exception. CLASS-METHODS check_http_200 IMPORTING ii_client TYPE REF TO if_http_client RAISING lcx_exception. CLASS-METHODS get_null RETURNING VALUE(rv_c) TYPE char1. ENDCLASS. "lcl_transport DEFINITION *----------------------------------------------------------------------* * CLASS lcl_transport IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_git_transport IMPLEMENTATION. METHOD class_constructor. * bitbucket require agent prefix = "git/" gv_agent = 'git/abapGit ' && gc_abap_version. ENDMETHOD. METHOD set_headers. DATA: lv_value TYPE string. ii_client->request->set_header_field( name = '~request_method' value = 'POST' ). lv_value = lcl_url=>path_name( io_repo->get_url( ) ) && '.git/git-' && iv_service && '-pack'. ii_client->request->set_header_field( name = '~request_uri' value = lv_value ). lv_value = 'application/x-git-' && iv_service && '-pack-request'. "#EC NOTEXT ii_client->request->set_header_field( name = 'Content-Type' value = lv_value ). "#EC NOTEXT lv_value = 'application/x-git-' && iv_service && '-pack-result'. "#EC NOTEXT ii_client->request->set_header_field( name = 'Accept' value = lv_value ). "#EC NOTEXT ENDMETHOD. "set_headers METHOD get_null. DATA: lv_x(4) TYPE x VALUE '00000000', lv_z(2) TYPE c. FIELD-SYMBOLS TYPE c. ASSIGN lv_x TO CASTING. lv_z = . rv_c = lv_z(1). ENDMETHOD. "get_null METHOD check_http_200. DATA: lv_code TYPE i. ii_client->response->get_status( IMPORTING code = lv_code ). CASE lv_code. WHEN 200. RETURN. WHEN 302. _raise 'HTTP redirect, check URL'. WHEN 401. _raise 'HTTP 401, unauthorized'. WHEN 403. _raise 'HTTP 403, forbidden'. WHEN 404. _raise 'HTTP 404, not found'. WHEN 415. _raise 'HTTP 415, unsupported media type'. WHEN OTHERS. _raise 'HTTP error code'. ENDCASE. ENDMETHOD. "http_200 METHOD parse_branch_list. DATA: lt_result TYPE TABLE OF string, lv_hash TYPE ty_sha1, lv_name TYPE string, lv_foo TYPE string ##needed, lv_char TYPE c, lv_data LIKE LINE OF lt_result. FIELD-SYMBOLS: LIKE LINE OF rt_list. SPLIT iv_data AT gc_newline INTO TABLE lt_result. LOOP AT lt_result INTO lv_data. IF sy-tabix = 1. CONTINUE. " current loop ELSEIF sy-tabix = 2 AND strlen( lv_data ) > 49. lv_hash = lv_data+8. lv_name = lv_data+49. lv_char = get_null( ). SPLIT lv_name AT lv_char INTO lv_name lv_foo. ELSEIF sy-tabix > 2 AND strlen( lv_data ) > 45. lv_hash = lv_data+4. lv_name = lv_data+45. ELSEIF sy-tabix = 2 AND strlen( lv_data ) = 8 AND lv_data(8) = '00000000'. _raise 'No branches, create branch manually by adding file'. ELSE. CONTINUE. ENDIF. APPEND INITIAL LINE TO rt_list ASSIGNING . -sha1 = lv_hash. -name = lv_name. ENDLOOP. ENDMETHOD. "parse_branch_list METHOD find_branch. DATA: lt_branch_list TYPE ty_branch_list_tt, ls_branch_list LIKE LINE OF lt_branch_list. branch_list( EXPORTING iv_url = io_repo->get_url( ) iv_service = iv_service IMPORTING ei_client = ei_client et_branch_list = lt_branch_list ). IF io_repo->get_branch_name( ) IS INITIAL. _raise 'branch empty'. ENDIF. READ TABLE lt_branch_list INTO ls_branch_list WITH KEY name = io_repo->get_branch_name( ). IF sy-subrc <> 0. _raise 'Branch not found'. ENDIF. ev_branch = ls_branch_list-sha1. ENDMETHOD. "find_branch METHOD branches. DATA: li_client TYPE REF TO if_http_client. lcl_git_transport=>branch_list( EXPORTING iv_url = iv_url iv_service = c_service-upload IMPORTING ei_client = li_client et_branch_list = rt_branch_list ). li_client->close( ). ENDMETHOD. METHOD branch_list. DATA: lv_data TYPE string, lv_uri TYPE string, lv_text TYPE string. STATICS: sv_authorization TYPE string. cl_http_client=>create_by_url( EXPORTING url = lcl_url=>host( iv_url ) ssl_id = 'ANONYM' IMPORTING client = ei_client ). ei_client->request->set_cdata( '' ). ei_client->request->set_header_field( name = '~request_method' value = 'GET' ). ei_client->request->set_header_field( name = 'user-agent' value = gv_agent ). "#EC NOTEXT lv_uri = lcl_url=>path_name( iv_url ) && '.git/info/refs?service=git-' && iv_service && '-pack'. ei_client->request->set_header_field( name = '~request_uri' value = lv_uri ). IF NOT sv_authorization IS INITIAL. * note this will only work if all repositories uses the same login ei_client->request->set_header_field( name = 'authorization' value = sv_authorization ). "#EC NOTEXT ei_client->propertytype_logon_popup = ei_client->co_disabled. ENDIF. ei_client->send( ). ei_client->receive( EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 OTHERS = 4 ). IF sy-subrc <> 0. CASE sy-subrc. WHEN 1. * make sure: * a) SSL is setup properly in STRUST * b) no firewalls * check trace file in transaction SMICM lv_text = 'HTTP Communication Failure'. "#EC NOTEXT WHEN 2. lv_text = 'HTTP Invalid State'. "#EC NOTEXT WHEN 3. lv_text = 'HTTP Processing failed'. "#EC NOTEXT WHEN OTHERS. lv_text = 'Another error occured'. "#EC NOTEXT ENDCASE. RAISE EXCEPTION TYPE lcx_exception EXPORTING iv_text = lv_text. ENDIF. check_http_200( ei_client ). sv_authorization = ei_client->request->get_header_field( 'authorization' ). "#EC NOTEXT lv_data = ei_client->response->get_cdata( ). et_branch_list = parse_branch_list( lv_data ). ENDMETHOD. "ref_discovery METHOD receive_pack. DATA: li_client TYPE REF TO if_http_client, lv_cmd_pkt TYPE string, lv_line TYPE string, lv_tmp TYPE xstring, lv_xstring TYPE xstring, lv_string TYPE string, lv_buffer TYPE string, lv_branch TYPE ty_sha1. find_branch( EXPORTING io_repo = io_repo iv_service = c_service-receive IMPORTING ei_client = li_client ev_branch = lv_branch ). set_headers( io_repo = io_repo iv_service = c_service-receive ii_client = li_client ). lv_line = lv_branch && ` ` && iv_commit && ` ` && io_repo->get_branch_name( ) && get_null( ) && ` ` && 'report-status agent=' && gv_agent && gc_newline. "#EC NOTEXT lv_cmd_pkt = pkt_string( lv_line ). lv_buffer = lv_cmd_pkt && '0000'. lv_tmp = lcl_convert=>string_to_xstring_utf8( lv_buffer ). CONCATENATE lv_tmp iv_pack INTO lv_xstring IN BYTE MODE. li_client->request->set_data( lv_xstring ). li_client->send( ). li_client->receive( ). check_http_200( li_client ). lv_xstring = li_client->response->get_data( ). li_client->close( ). lv_string = lcl_convert=>xstring_to_string_utf8( lv_xstring ). IF NOT lv_string CP '*unpack ok*'. _raise 'unpack not ok'. ELSEIF lv_string CP '*pre-receive hook declined*'. _raise 'pre-receive hook declined'. ENDIF. ENDMETHOD. "receive_pack METHOD length_utf8_hex. DATA: lv_xstring TYPE xstring, lv_string TYPE string, lv_char4 TYPE c LENGTH 4, lv_x TYPE x LENGTH 2, lo_obj TYPE REF TO cl_abap_conv_in_ce, lv_len TYPE int4. * hmm, can this be done easier? lv_xstring = iv_data(4). lo_obj = cl_abap_conv_in_ce=>create( input = lv_xstring encoding = 'UTF-8' ). lv_len = xstrlen( lv_xstring ). lo_obj->read( EXPORTING n = lv_len IMPORTING data = lv_string ). lv_char4 = lv_string. TRANSLATE lv_char4 TO UPPER CASE. lv_x = lv_char4. rv_len = lv_x. ENDMETHOD. "length_utf8_hex METHOD parse. CONSTANTS: lc_band1 TYPE x VALUE '01'. DATA: lv_len TYPE i, lv_contents TYPE xstring, lv_pack TYPE xstring. WHILE xstrlen( cv_data ) >= 4. lv_len = length_utf8_hex( cv_data ). lv_contents = cv_data(lv_len). IF lv_len = 0. cv_data = cv_data+4. CONTINUE. ELSE. cv_data = cv_data+lv_len. ENDIF. lv_contents = lv_contents+4. IF xstrlen( lv_contents ) > 1 AND lv_contents(1) = lc_band1. CONCATENATE lv_pack lv_contents+1 INTO lv_pack IN BYTE MODE. ENDIF. ENDWHILE. ev_pack = lv_pack. ENDMETHOD. "parse METHOD upload_pack. DATA: li_client TYPE REF TO if_http_client, lv_buffer TYPE string, lv_xstring TYPE xstring, lv_line TYPE string, lv_pkt1 TYPE string, lv_pkt2 TYPE string. find_branch( EXPORTING io_repo = io_repo iv_service = c_service-upload IMPORTING ei_client = li_client ev_branch = ev_branch ). set_headers( io_repo = io_repo iv_service = c_service-upload ii_client = li_client ). lv_line = 'want' && ` ` && ev_branch && ` ` && 'side-band-64k no-progress agent=' && gv_agent && gc_newline. "#EC NOTEXT lv_pkt1 = pkt_string( lv_line ). lv_pkt2 = pkt_string( 'deepen 1' && gc_newline ). "#EC NOTEXT lv_buffer = lv_pkt1 && lv_pkt2 && '0000' && '0009done' && gc_newline. * do not use set_cdata as it modifies the Content-Type header field li_client->request->set_data( lcl_convert=>string_to_xstring_utf8( lv_buffer ) ). li_client->send( ). li_client->receive( ). check_http_200( li_client ). lv_xstring = li_client->response->get_data( ). li_client->close( ). parse( IMPORTING ev_pack = ev_pack CHANGING cv_data = lv_xstring ). ENDMETHOD. "upload_pack METHOD pkt_string. DATA: lv_x TYPE x, lv_len TYPE i. lv_len = strlen( iv_string ). IF lv_len >= 255. _raise 'PKT, todo'. ENDIF. lv_x = lv_len + 4. rv_pkt = rv_pkt && '00' && lv_x && iv_string. ENDMETHOD. "pkt ENDCLASS. "lcl_transport IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_zip DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zip DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS import IMPORTING iv_key TYPE lcl_repo=>ty_key RAISING lcx_exception. CLASS-METHODS export_key IMPORTING iv_key TYPE lcl_repo=>ty_key iv_zip TYPE abap_bool DEFAULT abap_true RAISING lcx_exception. CLASS-METHODS export IMPORTING iv_package TYPE devclass iv_zip TYPE abap_bool DEFAULT abap_true RAISING lcx_exception. PRIVATE SECTION. CLASS-METHODS show_progress IMPORTING iv_current TYPE i iv_total TYPE i iv_obj_name TYPE tadir-obj_name. CLASS-METHODS file_upload RETURNING VALUE(rv_xstr) TYPE xstring RAISING lcx_exception. CLASS-METHODS unzip_file IMPORTING iv_xstr TYPE xstring RETURNING VALUE(rt_files) TYPE ty_files_tt RAISING lcx_exception. CLASS-METHODS filename IMPORTING iv_str TYPE string RETURNING VALUE(rv_filename) TYPE string RAISING lcx_exception. CLASS-METHODS file_download IMPORTING iv_package TYPE devclass iv_xstr TYPE xstring RAISING lcx_exception. CLASS-METHODS files_commit IMPORTING it_files TYPE ty_files_tt RAISING lcx_exception. CLASS-METHODS encode_files IMPORTING it_files TYPE ty_files_tt RETURNING VALUE(rv_xstr) TYPE xstring RAISING lcx_exception. CLASS-METHODS get_message RETURNING VALUE(rv_message) TYPE string RAISING lcx_exception. ENDCLASS. "lcl_zip DEFINITION *----------------------------------------------------------------------* * CLASS lcl_zip IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_zip IMPLEMENTATION. METHOD show_progress. DATA: lv_pct TYPE i, lv_text TYPE string, lv_f TYPE f. lv_f = ( iv_current / iv_total ) * 100. lv_pct = lv_f. lv_text = |{ iv_obj_name } ({ iv_current }/{ iv_total })|. CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR' EXPORTING percentage = lv_pct text = lv_text. ENDMETHOD. "show_progress METHOD get_message. DATA: lv_returncode TYPE c, lt_fields TYPE TABLE OF sval. FIELD-SYMBOLS: LIKE LINE OF lt_fields. APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'ABAPTXT255'. -fieldname = 'LINE'. -fieldtext = 'Commit message'. "#EC NOTEXT -field_obl = abap_true. CALL FUNCTION 'POPUP_GET_VALUES' EXPORTING no_value_check = abap_true popup_title = 'Enter commit message' "#EC NOTEXT IMPORTING returncode = lv_returncode TABLES fields = lt_fields EXCEPTIONS error_in_fields = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Error from POPUP_GET_VALUES'. ENDIF. IF lv_returncode = 'A'. _raise 'cancelled'. ENDIF. READ TABLE lt_fields INDEX 1 ASSIGNING . ASSERT sy-subrc = 0. rv_message = -value. ENDMETHOD. "get_message METHOD file_download. DATA: lt_rawdata TYPE solix_tab, lv_action TYPE i, lv_filename TYPE string, lv_default TYPE string, lv_path TYPE string, lv_fullpath TYPE string. CONCATENATE iv_package '_' sy-datlo '_' sy-timlo INTO lv_default. cl_gui_frontend_services=>file_save_dialog( EXPORTING window_title = 'Export ZIP' default_extension = 'zip' default_file_name = lv_default CHANGING filename = lv_filename path = lv_path fullpath = lv_fullpath user_action = lv_action EXCEPTIONS cntl_error = 1 error_no_gui = 2 not_supported_by_gui = 3 OTHERS = 4 ). "#EC NOTEXT IF sy-subrc <> 0. _raise 'error from file_save_dialog'. ENDIF. IF lv_action = cl_gui_frontend_services=>action_cancel. _raise 'cancelled'. ENDIF. lt_rawdata = cl_bcs_convert=>xstring_to_solix( iv_xstr ). cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = xstrlen( iv_xstr ) filename = lv_fullpath filetype = 'BIN' CHANGING data_tab = lt_rawdata EXCEPTIONS file_write_error = 1 no_batch = 2 gui_refuse_filetransfer = 3 invalid_type = 4 no_authority = 5 unknown_error = 6 header_not_allowed = 7 separator_not_allowed = 8 filesize_not_allowed = 9 header_too_long = 10 dp_error_create = 11 dp_error_send = 12 dp_error_write = 13 unknown_dp_error = 14 access_denied = 15 dp_out_of_memory = 16 disk_full = 17 dp_timeout = 18 file_not_found = 19 dataprovider_exception = 20 control_flush_error = 21 not_supported_by_gui = 22 error_no_gui = 23 OTHERS = 24 ). IF sy-subrc <> 0. _raise 'error from gui_download'. ENDIF. ENDMETHOD. "file_download METHOD encode_files. DATA: lo_zip TYPE REF TO cl_abap_zip, lv_filename TYPE string. FIELD-SYMBOLS: LIKE LINE OF it_files. CREATE OBJECT lo_zip. LOOP AT it_files ASSIGNING . CONCATENATE -path -filename INTO lv_filename. lo_zip->add( name = lv_filename content = -data ). ENDLOOP. rv_xstr = lo_zip->save( ). ENDMETHOD. "encode_files METHOD filename. DATA: lv_path TYPE string. "#EC NEEDED IF iv_str CA '/'. FIND REGEX '(.*/)(.*)' IN iv_str SUBMATCHES lv_path rv_filename. IF sy-subrc <> 0. _raise 'Malformed path'. ENDIF. ELSE. rv_filename = iv_str. ENDIF. TRANSLATE rv_filename TO LOWER CASE. ENDMETHOD. "filename METHOD file_upload. DATA: lt_data TYPE TABLE OF x255, lt_file_table TYPE filetable, ls_file_table LIKE LINE OF lt_file_table, lv_action TYPE i, lv_string TYPE string, lv_rc TYPE i, lv_length TYPE i. cl_gui_frontend_services=>file_open_dialog( EXPORTING window_title = 'Import ZIP' default_extension = 'ZIP' CHANGING file_table = lt_file_table rc = lv_rc user_action = lv_action EXCEPTIONS file_open_dialog_failed = 1 cntl_error = 2 error_no_gui = 3 not_supported_by_gui = 4 OTHERS = 5 ). "#EC NOTEXT IF sy-subrc <> 0. _raise 'error from file_open_dialog'. ENDIF. IF lv_action = cl_gui_frontend_services=>action_cancel. _raise 'cancelled'. ENDIF. READ TABLE lt_file_table INDEX 1 INTO ls_file_table. ASSERT sy-subrc = 0. lv_string = ls_file_table-filename. cl_gui_frontend_services=>gui_upload( EXPORTING filename = lv_string filetype = 'BIN' IMPORTING filelength = lv_length CHANGING data_tab = lt_data EXCEPTIONS file_open_error = 1 file_read_error = 2 no_batch = 3 gui_refuse_filetransfer = 4 invalid_type = 5 no_authority = 6 unknown_error = 7 bad_data_format = 8 header_not_allowed = 9 separator_not_allowed = 10 header_too_long = 11 unknown_dp_error = 12 access_denied = 13 dp_out_of_memory = 14 disk_full = 15 dp_timeout = 16 not_supported_by_gui = 17 error_no_gui = 18 OTHERS = 19 ). IF sy-subrc <> 0. _raise 'error from gui_upload'. ENDIF. CONCATENATE LINES OF lt_data INTO rv_xstr IN BYTE MODE. rv_xstr = rv_xstr(lv_length). ENDMETHOD. "file_upload METHOD unzip_file. DATA: lo_zip TYPE REF TO cl_abap_zip, lv_xstr TYPE xstring, lt_splice TYPE cl_abap_zip=>t_splice_entries. FIELD-SYMBOLS: LIKE LINE OF lt_splice, LIKE LINE OF rt_files. CREATE OBJECT lo_zip. lo_zip->load( EXPORTING zip = iv_xstr EXCEPTIONS zip_parse_error = 1 OTHERS = 2 ). IF sy-subrc <> 0. _raise 'error from zip'. ENDIF. lt_splice = cl_abap_zip=>splice( iv_xstr ). LOOP AT lt_splice ASSIGNING . lo_zip->get( EXPORTING name = -name IMPORTING content = lv_xstr EXCEPTIONS zip_index_error = 1 zip_decompression_error = 2 OTHERS = 3 ). IF sy-subrc <> 0. _raise 'error from zip get'. ENDIF. APPEND INITIAL LINE TO rt_files ASSIGNING . -path = '/'. -filename = filename( -name ). -data = lv_xstr. ENDLOOP. ENDMETHOD. "decode_files METHOD export_key. DATA: lo_repo TYPE REF TO lcl_repo. lo_repo = lcl_repo_srv=>get( iv_key ). export( iv_package = lo_repo->get_package( ) iv_zip = iv_zip ). ENDMETHOD. METHOD import. DATA: lt_files TYPE ty_files_tt, lo_repo TYPE REF TO lcl_repo. lo_repo = lcl_repo_srv=>get( iv_key ). lt_files = unzip_file( file_upload( ) ). lcl_objects=>deserialize( it_files = lt_files iv_package = lo_repo->get_package( ) ). ENDMETHOD. "import METHOD export. DATA: lt_tadir TYPE lcl_tadir=>ty_tadir_tt, ls_item TYPE ty_item, lt_msg TYPE rs_t_msg, lt_files TYPE ty_files_tt, lt_zip TYPE ty_files_tt. FIELD-SYMBOLS: LIKE LINE OF lt_files, LIKE LINE OF lt_msg, LIKE LINE OF lt_tadir. lt_tadir = lcl_tadir=>read( iv_package ). IF lt_tadir IS INITIAL. _raise 'Package is empty'. ENDIF. LOOP AT lt_tadir ASSIGNING . show_progress( iv_current = sy-tabix iv_total = lines( lt_tadir ) iv_obj_name = -obj_name ). CLEAR ls_item. ls_item-obj_type = -object. ls_item-obj_name = -obj_name. IF lcl_objects=>is_supported( ls_item ) = abap_false. APPEND INITIAL LINE TO lt_msg ASSIGNING . -msgty = 'W'. -msgid = '00'. -msgno = '001'. -msgv1 = 'Object type ignored, not supported:' ##NO_TEXT. -msgv2 = ls_item-obj_type. -msgv3 = '-'. -msgv4 = ls_item-obj_name. ELSE. lt_files = lcl_objects=>serialize( ls_item ). LOOP AT lt_files ASSIGNING . -path = -path. ENDLOOP. APPEND LINES OF lt_files TO lt_zip. ENDIF. ENDLOOP. IF lines( lt_msg ) > 0. CALL FUNCTION 'RSDC_SHOW_MESSAGES_POPUP' EXPORTING i_t_msg = lt_msg i_txt = 'Warning' i_with_s_on_empty = abap_false i_one_msg_direct = abap_false i_one_msg_type_s = abap_false ##NO_TEXT. ENDIF. IF iv_zip = abap_true. file_download( iv_package = iv_package iv_xstr = encode_files( lt_zip ) ). ELSE. files_commit( lt_zip ). ENDIF. ENDMETHOD. "export METHOD files_commit. DATA: lv_folder TYPE string, lv_filename TYPE string, lv_par TYPE string, lv_message TYPE string, lt_rawdata TYPE solix_tab. FIELD-SYMBOLS: LIKE LINE OF it_files. cl_gui_frontend_services=>directory_browse( EXPORTING window_title = 'Select folder' CHANGING selected_folder = lv_folder EXCEPTIONS cntl_error = 1 error_no_gui = 2 not_supported_by_gui = 3 OTHERS = 4 ). "#EC NOTEXT IF sy-subrc <> 0. _raise 'error from directory_browser'. ENDIF. IF lv_folder IS INITIAL. RETURN. ENDIF. lv_message = get_message( ). LOOP AT it_files ASSIGNING . lt_rawdata = cl_bcs_convert=>xstring_to_solix( -data ). CONCATENATE lv_folder -path -filename INTO lv_filename. cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = xstrlen( -data ) filename = lv_filename filetype = 'BIN' CHANGING data_tab = lt_rawdata EXCEPTIONS file_write_error = 1 no_batch = 2 gui_refuse_filetransfer = 3 invalid_type = 4 no_authority = 5 unknown_error = 6 header_not_allowed = 7 separator_not_allowed = 8 filesize_not_allowed = 9 header_too_long = 10 dp_error_create = 11 dp_error_send = 12 dp_error_write = 13 unknown_dp_error = 14 access_denied = 15 dp_out_of_memory = 16 disk_full = 17 dp_timeout = 18 file_not_found = 19 dataprovider_exception = 20 control_flush_error = 21 not_supported_by_gui = 22 error_no_gui = 23 OTHERS = 24 ). IF sy-subrc <> 0. _raise 'error from gui_download'. ENDIF. ENDLOOP. * assumption: git command is in PATH cl_gui_frontend_services=>execute( EXPORTING application = 'git' default_directory = lv_folder synchronous = 'X' parameter = 'add *' EXCEPTIONS cntl_error = 1 error_no_gui = 2 bad_parameter = 3 file_not_found = 4 path_not_found = 5 file_extension_unknown = 6 error_execute_failed = 7 synchronous_failed = 8 not_supported_by_gui = 9 OTHERS = 10 ). "#EC NOTEXT IF sy-subrc <> 0. _raise 'error from execute'. ENDIF. * make sure to set git user.email and user.name manually lv_par = 'commit -m "' && lv_message && '"'. "#EC NOTEXT cl_gui_frontend_services=>execute( EXPORTING application = 'git' default_directory = lv_folder synchronous = 'X' parameter = lv_par EXCEPTIONS cntl_error = 1 error_no_gui = 2 bad_parameter = 3 file_not_found = 4 path_not_found = 5 file_extension_unknown = 6 error_execute_failed = 7 synchronous_failed = 8 not_supported_by_gui = 9 OTHERS = 10 ). IF sy-subrc <> 0. _raise 'error from execute'. ENDIF. ENDMETHOD. "files_commit ENDCLASS. "lcl_zip IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_porcelain IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_git_porcelain IMPLEMENTATION. METHOD receive_pack. DATA: lv_tree TYPE xstring, lv_time TYPE lcl_time=>ty_unixtime, lv_commit TYPE xstring, lt_objects TYPE lcl_git_pack=>ty_objects_tt, lv_pack TYPE xstring, ls_object LIKE LINE OF lt_objects, ls_commit TYPE lcl_git_pack=>ty_commit. FIELD-SYMBOLS: LIKE LINE OF it_files. lv_tree = lcl_git_pack=>encode_tree( it_nodes ). * new commit lv_time = lcl_time=>get( ). ls_commit-tree = lcl_hash=>sha1( iv_type = gc_type-tree iv_data = lv_tree ). ls_commit-parent = iv_branch. CONCATENATE is_comment-username space '<' is_comment-email '>' space lv_time INTO ls_commit-author RESPECTING BLANKS. ls_commit-committer = ls_commit-author. ls_commit-body = is_comment-comment. lv_commit = lcl_git_pack=>encode_commit( ls_commit ). CLEAR ls_object. ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-commit iv_data = lv_commit ). ls_object-type = gc_type-commit. ls_object-data = lv_commit. APPEND ls_object TO lt_objects. CLEAR ls_object. ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-tree iv_data = lv_tree ). ls_object-type = gc_type-tree. ls_object-data = lv_tree. APPEND ls_object TO lt_objects. LOOP AT it_files ASSIGNING . CLEAR ls_object. ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -data ). ls_object-type = gc_type-blob. ls_object-data = -data. APPEND ls_object TO lt_objects. ENDLOOP. lv_pack = lcl_git_pack=>encode( lt_objects ). rv_branch = lcl_hash=>sha1( iv_type = gc_type-commit iv_data = lv_commit ). lcl_git_transport=>receive_pack( io_repo = io_repo iv_commit = rv_branch iv_pack = lv_pack ). ENDMETHOD. "receive_pack METHOD push. * todo, only works with root files DATA: lt_nodes TYPE lcl_git_pack=>ty_nodes_tt, lt_files LIKE it_files, lv_sha1 TYPE ty_sha1, lv_index TYPE i. FIELD-SYMBOLS: LIKE LINE OF it_files, LIKE LINE OF lt_nodes. lt_nodes = root_tree( it_objects = io_repo->get_objects( ) iv_branch = io_repo->get_sha1_remote( ) ). lt_files[] = it_files[]. LOOP AT lt_files ASSIGNING . lv_index = sy-tabix. READ TABLE lt_nodes ASSIGNING WITH KEY name = -filename. IF sy-subrc <> 0. * new files APPEND INITIAL LINE TO lt_nodes ASSIGNING . -chmod = gc_chmod-file. -name = -filename. ENDIF. lv_sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -data ). IF -sha1 <> lv_sha1. -sha1 = lv_sha1. ELSE. DELETE lt_files INDEX lv_index. ENDIF. ENDLOOP. IF lt_files[] IS INITIAL. _raise 'no files'. ENDIF. rv_branch = receive_pack( is_comment = is_comment io_repo = io_repo it_nodes = lt_nodes it_files = lt_files iv_branch = io_repo->get_sha1_remote( ) ). ENDMETHOD. "push METHOD root_tree. DATA: ls_object LIKE LINE OF it_objects, ls_commit TYPE lcl_git_pack=>ty_commit. READ TABLE it_objects INTO ls_object WITH KEY sha1 = iv_branch type = gc_type-commit. IF sy-subrc <> 0. _raise 'commit not found'. ENDIF. ls_commit = lcl_git_pack=>decode_commit( ls_object-data ). READ TABLE it_objects INTO ls_object WITH KEY sha1 = ls_commit-tree type = gc_type-tree. IF sy-subrc <> 0. _raise 'tree not found'. ENDIF. rt_nodes = lcl_git_pack=>decode_tree( ls_object-data ). ENDMETHOD. "root_tree METHOD pull. DATA: ls_object LIKE LINE OF et_objects, ls_commit TYPE lcl_git_pack=>ty_commit, lv_pack TYPE xstring. CLEAR et_files. CLEAR et_objects. CLEAR ev_branch. lcl_git_transport=>upload_pack( EXPORTING io_repo = io_repo IMPORTING ev_pack = lv_pack ev_branch = ev_branch ). IF lv_pack IS INITIAL. _raise 'empty pack'. ENDIF. et_objects = lcl_git_pack=>decode( lv_pack ). lcl_git_pack=>decode_deltas( CHANGING ct_objects = et_objects ). READ TABLE et_objects INTO ls_object WITH KEY sha1 = ev_branch type = gc_type-commit. IF sy-subrc <> 0. _raise 'Commit/branch not found'. ENDIF. ls_commit = lcl_git_pack=>decode_commit( ls_object-data ). walk( EXPORTING it_objects = et_objects iv_sha1 = ls_commit-tree iv_path = '/' CHANGING ct_files = et_files ). ENDMETHOD. "pull METHOD walk. DATA: lv_path TYPE string, ls_file LIKE LINE OF ct_files, lt_nodes TYPE lcl_git_pack=>ty_nodes_tt. FIELD-SYMBOLS: LIKE LINE OF it_objects, LIKE LINE OF it_objects, LIKE LINE OF lt_nodes. READ TABLE it_objects ASSIGNING WITH KEY sha1 = iv_sha1 type = gc_type-tree. IF sy-subrc <> 0. _raise 'Walk, tree not found'. ENDIF. lt_nodes = lcl_git_pack=>decode_tree( -data ). LOOP AT lt_nodes ASSIGNING . IF -chmod = gc_chmod-file. READ TABLE it_objects ASSIGNING WITH KEY sha1 = -sha1 type = gc_type-blob. IF sy-subrc <> 0. _raise 'Walk, blob not found'. ENDIF. CLEAR ls_file. ls_file-path = iv_path. ls_file-filename = -name. ls_file-data = -data. APPEND ls_file TO ct_files. ENDIF. ENDLOOP. LOOP AT lt_nodes ASSIGNING WHERE chmod = gc_chmod-dir. CONCATENATE iv_path -name '/' INTO lv_path. walk( EXPORTING it_objects = it_objects iv_sha1 = -sha1 iv_path = lv_path CHANGING ct_files = ct_files ). ENDLOOP. ENDMETHOD. "walk ENDCLASS. "lcl_porcelain IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_view IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_gui IMPLEMENTATION. METHOD zipexport. DATA: lv_returncode TYPE c, lv_package TYPE devclass, lt_fields TYPE TABLE OF sval. FIELD-SYMBOLS: LIKE LINE OF lt_fields. APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'TDEVC'. -fieldname = 'DEVCLASS'. -fieldtext = 'Package'. "#EC NOTEXT CALL FUNCTION 'POPUP_GET_VALUES' EXPORTING no_value_check = abap_true popup_title = 'Export package to ZIP' "#EC NOTEXT IMPORTING returncode = lv_returncode TABLES fields = lt_fields EXCEPTIONS error_in_fields = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Error from POPUP_GET_VALUES'. ENDIF. IF lv_returncode = 'A'. RETURN. ENDIF. READ TABLE lt_fields INDEX 1 ASSIGNING . ASSERT sy-subrc = 0. lv_package = -value. TRANSLATE lv_package TO UPPER CASE. lcl_zip=>export( lv_package ). ENDMETHOD. "zipexport METHOD render_header. rv_html = '' && gc_newline && '' && gc_newline && 'abapGit' && gc_newline && render_css( ) && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline. "#EC NOTEXT ENDMETHOD. "render_head METHOD diff. DATA: lt_remote TYPE ty_files_tt, lt_local TYPE ty_files_tt, ls_item TYPE ty_item, lo_repo TYPE REF TO lcl_repo_online, lo_diff TYPE REF TO lcl_diff. FIELD-SYMBOLS: LIKE LINE OF lt_remote, LIKE LINE OF lt_local. lo_repo ?= lcl_repo_srv=>get( iv_key ). lt_remote = lo_repo->get_files( ). ls_item-obj_type = is_result-obj_type. ls_item-obj_name = is_result-obj_name. lt_local = lcl_objects=>serialize( ls_item ). READ TABLE lt_remote ASSIGNING WITH KEY filename = is_result-filename. IF sy-subrc <> 0. _raise 'not found remotely'. ENDIF. READ TABLE lt_local ASSIGNING WITH KEY filename = is_result-filename. IF sy-subrc <> 0. _raise 'not found locally'. ENDIF. CREATE OBJECT lo_diff EXPORTING iv_local = -data iv_remote = -data. render_diff( is_result = is_result io_diff = lo_diff ). ENDMETHOD. "diff METHOD render_diff. DATA: lv_html TYPE string, lv_local TYPE string, lv_remote TYPE string, lv_clocal TYPE string, lv_cremote TYPE string, ls_count TYPE lcl_diff=>ty_count, lt_diffs TYPE lcl_diff=>ty_diffs_tt. FIELD-SYMBOLS: LIKE LINE OF lt_diffs. lv_html = render_header( ) && '

diff

 Back' && '

' && is_result-obj_type && ' ' && is_result-obj_name && ' ' && is_result-filename && '



'. ls_count = io_diff->stats( ). lv_html = lv_html && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '
Insert' && ls_count-insert && '
Delete' && ls_count-delete && '
Update' && ls_count-update && '

' && gc_newline. lv_html = lv_html && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && ''. lt_diffs = io_diff->get( ). LOOP AT lt_diffs ASSIGNING . lv_local = escape( val = -local format = cl_abap_format=>e_html_attr ). lv_remote = escape( val = -remote format = cl_abap_format=>e_html_attr ). CASE -result. WHEN lcl_diff=>c_diff-insert. lv_clocal = ' style="background:lightgreen;"'. "#EC NOTEXT lv_cremote = ''. WHEN lcl_diff=>c_diff-delete. lv_clocal = ''. lv_cremote = ' style="background:lightpink;"'. "#EC NOTEXT WHEN lcl_diff=>c_diff-update. lv_clocal = ' style="background:lightgreen;"'. "#EC NOTEXT lv_cremote = ' style="background:lightpink;"'. "#EC NOTEXT WHEN OTHERS. lv_clocal = ''. lv_cremote = ''. ENDCASE. lv_html = lv_html && '' && gc_newline && '
' && lv_local && '
' && gc_newline && '
' && gc_newline && '
' && lv_remote && '
' && gc_newline && '
' && gc_newline. ENDLOOP. lv_html = lv_html && '

Local

Remote

 ' && -result && ' 
' && gc_newline. lv_html = lv_html && render_footer( ). view( lv_html ). ENDMETHOD. "render_diff METHOD popup_comment. DATA: lv_returncode TYPE c, lt_fields TYPE TABLE OF sval. FIELD-SYMBOLS: LIKE LINE OF lt_fields. APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'BAPIRTEXT'. -fieldname = 'TEXT'. -fieldtext = 'Username'. "#EC NOTEXT -field_obl = abap_true. -value = lcl_user=>get_username( ). APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'BAPIRTEXT1'. -fieldname = 'TEXT'. -fieldtext = 'E-Mail'. "#EC NOTEXT -field_obl = abap_true. -value = lcl_user=>get_email( ). APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'ABAPTXT255'. -fieldname = 'LINE'. -fieldtext = 'Comment'. "#EC NOTEXT -field_obl = abap_true. CALL FUNCTION 'POPUP_GET_VALUES' EXPORTING no_value_check = abap_true popup_title = 'Enter Git username and email' "#EC NOTEXT IMPORTING returncode = lv_returncode TABLES fields = lt_fields EXCEPTIONS error_in_fields = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Error from POPUP_GET_VALUES'. ENDIF. IF lv_returncode = 'A'. CLEAR rs_comment. RETURN. ENDIF. READ TABLE lt_fields INDEX 1 ASSIGNING . ASSERT sy-subrc = 0. rs_comment-username = -value. lcl_user=>set_username( rs_comment-username ). READ TABLE lt_fields INDEX 2 ASSIGNING . ASSERT sy-subrc = 0. rs_comment-email = -value. lcl_user=>set_email( rs_comment-email ). READ TABLE lt_fields INDEX 3 ASSIGNING . ASSERT sy-subrc = 0. rs_comment-comment = -value. ENDMETHOD. "popup_commit METHOD pull. DATA: lo_repo TYPE REF TO lcl_repo_online. lo_repo ?= lcl_repo_srv=>get( iv_key ). lo_repo->refresh( ). lo_repo->deserialize( ). view( render( ) ). ENDMETHOD. "pull METHOD commit. DATA: lt_results TYPE lcl_file_status=>ty_results_tt, lt_push TYPE ty_files_tt, ls_item TYPE ty_item, ls_comment TYPE ty_comment, lo_repo TYPE REF TO lcl_repo_online, lt_files TYPE ty_files_tt. FIELD-SYMBOLS: LIKE LINE OF lt_results. lo_repo ?= lcl_repo_srv=>get( iv_key ). lt_results = lo_repo->status( ). LOOP AT lt_results ASSIGNING WHERE match = abap_false AND filename <> ''. CLEAR ls_item. ls_item-obj_type = -obj_type. ls_item-obj_name = -obj_name. lt_files = lcl_objects=>serialize( ls_item ). APPEND LINES OF lt_files TO lt_push. ENDLOOP. IF lt_push[] IS INITIAL. _raise 'no changes'. ENDIF. ls_comment = popup_comment( ). IF ls_comment IS INITIAL. RETURN. ENDIF. lo_repo->push( is_comment = ls_comment it_files = lt_push ). view( render( ) ). ENDMETHOD. "commit METHOD file_decode. DATA: lt_fields TYPE tihttpnvp, lv_string TYPE string. FIELD-SYMBOLS: LIKE LINE OF lt_fields, TYPE any. lv_string = iv_string. " type conversion lt_fields = cl_http_utility=>if_http_utility~string_to_fields( lv_string ). LOOP AT lt_fields ASSIGNING . ASSIGN COMPONENT -name OF STRUCTURE es_file TO . IF sy-subrc <> 0. CONTINUE. " more structures might be encoded in same string ENDIF. = -value. ENDLOOP. READ TABLE lt_fields ASSIGNING WITH KEY name = 'KEY'. IF sy-subrc = 0. ev_key = -value. ELSE. CLEAR ev_key. ENDIF. ENDMETHOD. "struct_decode METHOD file_encode. DATA: lt_fields TYPE tihttpnvp, lo_descr_ref TYPE REF TO cl_abap_structdescr, ls_field LIKE LINE OF lt_fields. FIELD-SYMBOLS: LIKE LINE OF lo_descr_ref->components, TYPE any. lo_descr_ref ?= cl_abap_typedescr=>describe_by_data( is_file ). LOOP AT lo_descr_ref->components ASSIGNING . ASSIGN COMPONENT -name OF STRUCTURE is_file TO . ASSERT sy-subrc = 0. ls_field-name = -name. ls_field-value = . APPEND ls_field TO lt_fields. ENDLOOP. ls_field-name = 'KEY'. ls_field-value = iv_key. APPEND ls_field TO lt_fields. rv_string = cl_http_utility=>if_http_utility~fields_to_string( lt_fields ). ENDMETHOD. "encode_struct METHOD on_event. DATA: lx_exception TYPE REF TO lcx_exception, ls_result TYPE lcl_file_status=>ty_result, lv_url TYPE string, lv_key TYPE lcl_repo=>ty_key, ls_item TYPE ty_item. TRY. CASE action. WHEN 'install'. lv_url = getdata. install( lv_url ). WHEN 'explore'. go_html_viewer->show_url( 'http://larshp.github.io/abapGit/explore.html' ). WHEN 'abapgithome'. cl_gui_frontend_services=>execute( document = 'https://github.com/larshp/abapGit' ). WHEN 'add'. file_decode( EXPORTING iv_string = getdata IMPORTING ev_key = lv_key es_file = ls_result ). CLEAR ls_item. MOVE-CORRESPONDING ls_result TO ls_item. add( is_item = ls_item iv_key = lv_key ). WHEN 'uninstall'. lv_key = getdata. uninstall( lv_key ). WHEN 'remove'. lv_key = getdata. remove( lv_key ). WHEN 'refresh'. lcl_repo_srv=>refresh( ). view( render( ) ). WHEN 'commit'. lv_key = getdata. commit( lv_key ). WHEN 'diff'. file_decode( EXPORTING iv_string = getdata IMPORTING ev_key = lv_key es_file = ls_result ). diff( is_result = ls_result iv_key = lv_key ). WHEN 'jump'. file_decode( EXPORTING iv_string = getdata IMPORTING ev_key = lv_key es_file = ls_result ). CLEAR ls_item. MOVE-CORRESPONDING ls_result TO ls_item. lcl_objects=>jump( ls_item ). WHEN 'pull'. lv_key = getdata. pull( lv_key ). WHEN 'newoffline'. newoffline( ). WHEN 'zipimport'. lv_key = getdata. lcl_zip=>import( lv_key ). view( render( ) ). WHEN 'zipexport'. lv_key = getdata. lcl_zip=>export_key( lv_key ). view( render( ) ). WHEN 'files_commit'. lv_key = getdata. lcl_zip=>export_key( iv_key = lv_key iv_zip = abap_false ). view( render( ) ). WHEN 'zipexport_gui'. zipexport( ). WHEN OTHERS. _raise 'Unknown action'. ENDCASE. CATCH lcx_exception INTO lx_exception. MESSAGE lx_exception->mv_text TYPE 'S' DISPLAY LIKE 'E'. ENDTRY. ENDMETHOD. "on_event METHOD uninstall. DATA: lt_tadir TYPE lcl_tadir=>ty_tadir_tt, lv_count TYPE c LENGTH 3, lv_answer TYPE c LENGTH 1, lo_repo TYPE REF TO lcl_repo, lv_package TYPE devclass, lv_question TYPE c LENGTH 100. lo_repo = lcl_repo_srv=>get( iv_key ). lv_package = lo_repo->get_package( ). lt_tadir = lcl_tadir=>read( lv_package ). IF lines( lt_tadir ) > 0. lv_count = lines( lt_tadir ). CONCATENATE 'This will delete all objects in package' lv_package INTO lv_question SEPARATED BY space. "#EC NOTEXT CONCATENATE lv_question '(' lv_count 'objects)' INTO lv_question SEPARATED BY space. "#EC NOTEXT CALL FUNCTION 'POPUP_TO_CONFIRM' EXPORTING titlebar = 'Uninstall' text_question = lv_question text_button_1 = 'Delete' icon_button_1 = 'ICON_DELETE' text_button_2 = 'Cancel' icon_button_2 = 'ICON_CANCEL' default_button = '2' display_cancel_button = abap_false IMPORTING answer = lv_answer EXCEPTIONS text_not_found = 1 OTHERS = 2. "#EC NOTEXT IF sy-subrc <> 0. _raise 'error from POPUP_TO_CONFIRM'. ENDIF. IF lv_answer = '2'. RETURN. ENDIF. lcl_objects=>delete( lt_tadir ). ENDIF. lcl_repo_srv=>delete( lo_repo ). view( render( ) ). ENDMETHOD. "uninstall METHOD remove. DATA: lv_answer TYPE c LENGTH 1, lo_repo TYPE REF TO lcl_repo, lv_package TYPE devclass, lv_question TYPE c LENGTH 100. lo_repo = lcl_repo_srv=>get( iv_key ). lv_package = lo_repo->get_package( ). CONCATENATE 'This will remove the repository reference to the package' lv_package INTO lv_question SEPARATED BY space. "#EC NOTEXT CALL FUNCTION 'POPUP_TO_CONFIRM' EXPORTING titlebar = 'Remove' text_question = lv_question text_button_1 = 'Remove' icon_button_1 = 'ICON_WF_UNLINK' text_button_2 = 'Cancel' icon_button_2 = 'ICON_CANCEL' default_button = '2' display_cancel_button = abap_false IMPORTING answer = lv_answer EXCEPTIONS text_not_found = 1 OTHERS = 2. "#EC NOTEXT IF sy-subrc <> 0. _raise 'error from POPUP_TO_CONFIRM'. ENDIF. IF lv_answer = '2'. RETURN. ENDIF. lcl_repo_srv=>delete( lo_repo ). view( render( ) ). ENDMETHOD. "remove METHOD add. DATA: lt_files TYPE ty_files_tt, ls_comment TYPE ty_comment, lo_repo TYPE REF TO lcl_repo_online, lv_package TYPE devclass, lv_obj_name TYPE tadir-obj_name. lo_repo ?= lcl_repo_srv=>get( iv_key ). lv_package = lo_repo->get_package( ). IF is_item-obj_type = 'SICF'. CONCATENATE is_item-obj_name '%' INTO lv_obj_name. ELSE. lv_obj_name = is_item-obj_name. ENDIF. SELECT SINGLE obj_name FROM tadir INTO lv_obj_name WHERE pgmid = 'R3TR' AND object = is_item-obj_type AND obj_name LIKE lv_obj_name AND devclass = lv_package. "#EC CI_GENBUFF IF sy-subrc <> 0. _raise 'Object not found or in wrong package'. ENDIF. lt_files = lcl_objects=>serialize( is_item ). ls_comment = popup_comment( ). IF ls_comment IS INITIAL. RETURN. ENDIF. lo_repo->push( is_comment = ls_comment it_files = lt_files ). view( render( ) ). ENDMETHOD. "add METHOD newoffline. DATA: lv_returncode TYPE c, lv_url TYPE string, lv_package TYPE devclass, lt_fields TYPE TABLE OF sval. FIELD-SYMBOLS: LIKE LINE OF lt_fields. APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'ABAPTXT255'. -fieldname = 'LINE'. -fieldtext = 'Name'. "#EC NOTEXT APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'TDEVC'. -fieldname = 'DEVCLASS'. -fieldtext = 'Package'. "#EC NOTEXT CALL FUNCTION 'POPUP_GET_VALUES' EXPORTING no_value_check = abap_true popup_title = 'New Offline Project' "#EC NOTEXT IMPORTING returncode = lv_returncode TABLES fields = lt_fields EXCEPTIONS error_in_fields = 1 OTHERS = 2. IF sy-subrc <> 0. _raise 'Error from POPUP_GET_VALUES'. ENDIF. IF lv_returncode = 'A'. RETURN. ENDIF. READ TABLE lt_fields INDEX 1 ASSIGNING . ASSERT sy-subrc = 0. lv_url = -value. READ TABLE lt_fields INDEX 2 ASSIGNING . ASSERT sy-subrc = 0. lv_package = -value. TRANSLATE lv_package TO UPPER CASE. lcl_repo_srv=>new_offline( iv_url = lv_url iv_package = lv_package ). view( render( ) ). ENDMETHOD. "newoffline METHOD install. DATA: lv_returncode TYPE c, lv_url TYPE string, lv_package TYPE devclass, lv_branch_name TYPE string, lv_icon_ok TYPE icon-name, lv_icon_br TYPE icon-name, lo_repo TYPE REF TO lcl_repo_online, lt_fields TYPE TABLE OF sval. FIELD-SYMBOLS: LIKE LINE OF lt_fields. APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'ABAPTXT255'. -fieldname = 'LINE'. -fieldtext = 'Git Clone Url'. "#EC NOTEXT -value = iv_url. APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'TDEVC'. -fieldname = 'DEVCLASS'. -fieldtext = 'Target Package'. "#EC NOTEXT APPEND INITIAL LINE TO lt_fields ASSIGNING . -tabname = 'TEXTL'. -fieldname = 'LINE'. -fieldtext = 'Branch'. "#EC NOTEXT -value = 'refs/heads/master'. "#EC NOTEXT -field_attr = '05'. lv_icon_ok = icon_okay. lv_icon_br = icon_workflow_fork. CALL FUNCTION 'POPUP_GET_VALUES_USER_BUTTONS' EXPORTING popup_title = 'Clone' programname = sy-repid formname = 'BRANCH_POPUP' ok_pushbuttontext = 'OK' icon_ok_push = lv_icon_ok first_pushbutton = 'Select branch' icon_button_1 = lv_icon_br IMPORTING returncode = lv_returncode TABLES fields = lt_fields EXCEPTIONS error_in_fields = 1 OTHERS = 2. "#EC NOTEXT IF sy-subrc <> 0. _raise 'Error from POPUP_GET_VALUES'. ENDIF. IF lv_returncode = 'A'. RETURN. ENDIF. READ TABLE lt_fields INDEX 1 ASSIGNING . ASSERT sy-subrc = 0. lv_url = -value. lcl_url=>name( lv_url ). " validate READ TABLE lt_fields INDEX 2 ASSIGNING . ASSERT sy-subrc = 0. lv_package = -value. TRANSLATE lv_package TO UPPER CASE. READ TABLE lt_fields INDEX 3 ASSIGNING . ASSERT sy-subrc = 0. lv_branch_name = -value. lo_repo = lcl_repo_srv=>new_online( iv_url = lv_url iv_branch_name = lv_branch_name iv_package = lv_package ). lo_repo->status( ). " check for errors lo_repo->deserialize( ). view( render( ) ). ENDMETHOD. "install METHOD render_css. rv_html = '' && gc_newline. ENDMETHOD. "render_css METHOD render_menu. rv_html = || && gc_newline && '

abapGit

 ' && gc_newline && 'Refresh ' && gc_newline && 'Clone ' && gc_newline && 'Explore ' && gc_newline && 'abapGit@GitHub ' && gc_newline && 'New offline project ' && gc_newline && '
' && gc_newline. ENDMETHOD. "render_menu METHOD render. DATA: lt_repos TYPE lcl_repo_srv=>ty_repo_tt, lo_repo LIKE LINE OF lt_repos. lt_repos = lcl_repo_srv=>list( ). rv_html = render_header( ) && render_menu( ). LOOP AT lt_repos INTO lo_repo. rv_html = rv_html && '' && lo_repo->get_name( ) && ' '. ENDLOOP. IF lt_repos[] IS INITIAL. rv_html = rv_html && '
Explore new projects'. ELSE. rv_html = rv_html && '


'. LOOP AT lt_repos INTO lo_repo. rv_html = rv_html && lo_repo->render( ). ENDLOOP. ENDIF. rv_html = rv_html && render_footer( ). ENDMETHOD. "render METHOD render_footer. rv_html = rv_html && '


abapGit Version: ' && gc_abap_version && ' e' && '

'. "#EC NOTEXT rv_html = rv_html && '
' && || && '
'. "#EC NOTEXT rv_html = rv_html && ''. ENDMETHOD. "render_footer METHOD render_repo_offline. DATA: lt_tadir TYPE lcl_tadir=>ty_tadir_tt. FIELD-SYMBOLS: LIKE LINE OF lt_tadir. rv_html = rv_html && '' && '

' && io_repo->get_name( ) && '

 ' && '

' && io_repo->get_package( ) && '

  ' && '
' && '' && 'remove' && ' ' && '' && 'uninstall' && '

'. "#EC NOTEXT rv_html = rv_html && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline. lt_tadir = lcl_tadir=>read( io_repo->get_package( ) ). LOOP AT lt_tadir ASSIGNING . * todo, add jump link like in online rendering rv_html = rv_html && '' && '' && gc_newline && '' && gc_newline. ENDLOOP. rv_html = rv_html && '
Local object
' && -object && ' ' && -obj_name && '
' && gc_newline. rv_html = rv_html && '' && 'Import ZIP' && ' ' && '' && 'Export ZIP' && ' ' && '' && 'Export files and commit' && ' ' && '


'. "#EC NOTEXT ENDMETHOD. "render_repo_offline METHOD render_repo_online. DATA: lv_link TYPE string, lv_status TYPE string, lv_package TYPE string, lv_object TYPE string, lv_index LIKE sy-tabix, lv_file_encode TYPE string, lv_span TYPE i, lt_results TYPE lcl_file_status=>ty_results_tt, ls_next LIKE LINE OF lt_results, ls_item TYPE ty_item, lv_supported TYPE abap_bool. FIELD-SYMBOLS: LIKE LINE OF lt_results. rv_html = rv_html && '' && '

' && io_repo->get_name( ) && '

 ' && '

' && io_repo->get_url( ) && '

  ' && '

' && io_repo->get_branch_name( ) && '

  ' && '

' && io_repo->get_package( ) && '

  ' && '
' && '' && 'remove' && ' ' && '' && 'uninstall' && '
'. "#EC NOTEXT rv_html = rv_html && '
'. lt_results = io_repo->status( ). IF io_repo->get_sha1_remote( ) <> io_repo->get_sha1_local( ). lv_status = 'pull'. "#EC NOTEXT ELSE. READ TABLE lt_results WITH KEY match = abap_false TRANSPORTING NO FIELDS. IF sy-subrc = 0. lv_status = 'commit'. "#EC NOTEXT ELSE. lv_status = 'match'. "#EC NOTEXT ENDIF. ENDIF. rv_html = rv_html && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline. LOOP AT lt_results ASSIGNING . lv_index = sy-tabix. lv_file_encode = file_encode( iv_key = io_repo->get_key( ) is_file = ). CLEAR lv_link. IF lv_status = 'match' AND -filename IS INITIAL. MOVE-CORRESPONDING TO ls_item. lv_supported = lcl_objects=>is_supported( ls_item ). IF lv_supported = abap_true. lv_link = 'add'. ELSE. lv_link = |Object type { ls_item-obj_type } not supported|. ENDIF. ELSEIF -match = abap_false. lv_link = 'diff'. ENDIF. IF lv_span = 0. READ TABLE lt_results INTO ls_next INDEX lv_index. ASSERT sy-subrc = 0. WHILE ls_next-obj_type = -obj_type AND ls_next-obj_name = -obj_name. lv_span = lv_span + 1. lv_index = lv_index + 1. READ TABLE lt_results INTO ls_next INDEX lv_index. IF sy-subrc <> 0. EXIT. " current loop. ENDIF. ENDWHILE. IF -obj_type IS INITIAL. lv_object = ''. lv_package = lv_object. ELSE. lv_object = ''. lv_package = ''. ENDIF. ELSE. CLEAR lv_object. CLEAR lv_package. ENDIF. rv_html = rv_html && '' && gc_newline && lv_object && gc_newline && lv_package && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline && '' && gc_newline. lv_span = lv_span - 1. ENDLOOP. rv_html = rv_html && '
Local objectPackagePathRemote file
 ' && -obj_type && ' ' && -obj_name && '' && -package && '
' && -path && '' && -filename && '' && lv_link && '
' && gc_newline. CASE lv_status. WHEN 'commit'. rv_html = rv_html && 'commit'. WHEN 'pull'. rv_html = rv_html && 'pull'. ENDCASE. lv_status = lcl_sap_package=>check( it_results = lt_results iv_top = io_repo->get_package( ) ). rv_html = rv_html && lv_status && '


'. ENDMETHOD. "render_repo METHOD run. DATA: lt_events TYPE cntl_simple_events, ls_event LIKE LINE OF lt_events. CREATE OBJECT go_html_viewer EXPORTING parent = cl_gui_container=>screen0. CLEAR ls_event. ls_event-eventid = go_html_viewer->m_id_sapevent. ls_event-appl_event = 'x'. APPEND ls_event TO lt_events. go_html_viewer->set_registered_events( lt_events ). SET HANDLER lcl_gui=>on_event FOR go_html_viewer. view( render( ) ). ENDMETHOD. "init METHOD view. DATA: lt_data TYPE TABLE OF text200, lv_html TYPE string, lv_url TYPE text200. lv_html = iv_html. WHILE strlen( lv_html ) > 0. IF strlen( lv_html ) < 200. APPEND lv_html TO lt_data. CLEAR lv_html. ELSE. APPEND lv_html(200) TO lt_data. lv_html = lv_html+200. ENDIF. ENDWHILE. go_html_viewer->load_data( IMPORTING assigned_url = lv_url CHANGING data_table = lt_data ). go_html_viewer->show_url( lv_url ). ENDMETHOD. "view METHOD get_logo_src. rv_src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAX8AAAF/CAMAAACWmjlVAAAA' && 'M1BMVEX////wUDPwUDPwUDPwUDPwUDPwUDPwUDPwUDPwUDPwUDPwUDPwUDPwUDPwUDPwUD' && 'PwUDP3eUwZAAAAEHRSTlMA8DAQ0KDAQGCA4CCQUHCw+BUOAQAACQ5JREFUeF7s1VFKw0AA' && 'RVHTpmkbGzr7X63gn6D1K7ko521g4J5h5u2vbrsv6/jctDy285FH2/Uyja97bgCO2m0d32' && 'y9AThip2X8sPkKYPfdx4s9AOy783O83LzrRyz/PH7Z/A4gzD/GdAIQ5A8A5A8A5M8A5E8B' && '5E8B5E8B5E8B5E8B5E8B5E8B5E8B5E8B5E8B5G8B5O8B5O8B5O8B5O8B5O8B5O8B5O8B5O' && '8B5O8B5O8B5O8B5O8B5O8B5O8B5O8B5O8B5O8B5O8B5O8B5O8B9AcAAIABAGAAugEAYAAA' && 'GAAABgCAAQDw//sCaK/3BUD7ugBI8wNI8wNI8wNI8wNI8wNI8wNI8wNI8wNI8wNI8wNI8w' && 'NI8wNI8wNI8wNI8wNI8wMI83+wcy85EsIwAEQDJAH6A3X/086yZ20hlWTZN6CewPIGKAA3' && 'fwH4+QvAz18Afv4C8PMXgJ+/APz8cYA5P+d5jtkLIJY/DrCM43+b/boL4Kn8MCLURy+AeP' && '44wG/2WQCB/M8BtL0XQCD/cwDtLIBffgNgfRXAA/lh1M+7zfxxgDZ8AD8/BaDmVwG6DODn' && 'dwE2dwn7+W2AFRHAz+8DXCaAn98H6CKAn98H2BEB/Pw+wBQB/Pw+wI4AkDE/fL0XwAfw8y' && '9bqP+BB+Dn9xfAhgCQMD/fFptbAEiYn827wXwAP39vwVkRANLl59OigwCQLj9nuH8XANLl' && 'Zw/3n3gAfn6//wcBIFt+4k96IgBky0/z+vsAfn42r78P4OdnF/vHAfz8fv8bASBbfo5w/4' && 'kH4Of3768FASBbfu5o/jcIANnys0T7f/EA/Pz+ATYQAPLl5wr2fyEA5MtPD69fD8DP73+A' && 'VgEgY35GKwAxP7wLwMzPaAUg5oe1AMz8zFYAYn64CsDMD2sBmPlZtgIQ80MvADM/BbD1P/' && 'buNudxFQjCqAk2Nvgj7H+19/4raTTzjoKGFFQ3K0DnkRNsJ2oGuwcAP3kVe1/CfH4/hoKf' && 'v9JpMQD4+euKBgOAn7/CFocPoMiPtVu5AsA/hf9LLAD45/BPh1QA8M/iX5UCgH8ef6EA4J' && '/IXycA+GfylwkA/qn8VQKAfy5/kQDgn8xfIwD4Z/OXCAD+6fwVAoB/Pn+BAOCf0F8gAPgn' && '9BcIAP4J/QUCgH9Cf4EA4J/QXyAA+Cf0FwgA/gn9BQKAX8B/ogDgF/CfLwD4BfznCwB+Af' && '+mAOuWj/3/decrEQKAf2b/xgDp+iXpfhVCAPBr+CNAw3ptXwsAfj3/9gDLeX0nAPgl/dsD' && 'LGf6QgDwq/q3B1iO0DsA+IX92wO81r4BwC/t3x4gpp4BwK/uX48Bx9mCX8N/ugDg1/dHAP' && '5I87PHoCC+f68Aoed/mXM14o8A/GGGCSesquPfLcDVb6xNEvLvFiCWXnM9jirk3y/A0esT' && 'qCj5dwxQ+sxV3Ks1/3qMdAFs9vwD/wLAN0Cw57/Rj0DYyF3t+b/o4zxxIWZ7/gGk/A+gZM' && '//PcxjuPosxZ7/A1H2CWhbqj1/1OM/BLLoH8eZ5xws+i/j+FeD/mVhztNz/2TeH8v9A5HR' && '/ddPkvrn//rvz58XkdHPPxf1+Zuf/48lEhn9/vdclrc5/9zq//QYbHnTFP3552Py/XsYZp' && 'x5tPT7E6x7kPdf2yenWn//u3WaKrpb8w9xiN/gXnixb8u/PiO8/SoR99XG/MsIb993c/+/' && 'wMr8w//TMJZAxj9E9qf/BnwEkPdvvwd79+JHAH3/9t/g3t34EcCUf3gxBieBnxuA71/XSJ' && 'uCsDVEVvNHAD4/AhjyRwA+PwIY8kcAPj8CWPKvYWd89RICsP3bb4Rz/Q4/Apjyr+uPl8C+' && 'fpMfAfT9sdIfC5zv+mV+BND3x/r92M47VQI/Auj7Y4XtOBesJd5bqAR+BLDij1VSzs++Pz' && 'mnAjQCPwII+PMX+AkB3B/8hADuD35CAPcHPyGA+4OfEMD9wU8I4P7gJwRwf/ATArg/+AkB' && '3B/8hADuD35CAPcHPyGA+4OfEMD9wU8I4P7gJwRwf/ATArg/+AkB3B/8hADuD35CAPcHPy' && 'GA+4OfEMD9wU8I4P7glw5QchzSH/zKAUL+YVzsewh+5QDv+OMG98LnFw4Q7r9tMF5sfuEA' && '69kwMZnALxogxVF3CH7hANuwOwS/cIA07A7BLxxgjbRJFXx+foDw2dCoh8GvHOAmjEpg8/' && 'MDtM+MOgOBXzZAOD/eYCbwywbIvGl1fH5+gBAb/A8Cv2iAq2l/gcCvGeBs8s8EfskAa9vu' && 'TgK/ZICHOC6Hz88PcDb6XwR+wQCFOK+Fz88P8G7eG4FfMEBu9i8Efr0Ad7N/IvDrBdib/S' && '9xfgQY0z8T+PUCLCP6/8feHaQ2DEMBEK0tWZGiOu79T9tFF39RqCHwGYomJ4jfBInwkQXw' && 'AwFwf56fD7AD/gA/EABY/wF+KgDv30B+PgD//6uC/HwA/nmz+NcKUN/+Okn8qwUo4H3JPD' && '8foL/pf3H8fAD+oQvIzwfgF6AO8vMB+AWocvx8AH4C+QD5+QD8DtwS+FcN8Czgz5/n5wMM' && 'cvbL8/MBdnD0wvPzAWoBVx+enw9wEKdfgt8Ag72v1wAd5jfAP+B3D5hp/AZo5RbgTNx6Db' && 'Cdt6//kT91HtDmHwD9KX/6POCYN/ryJ88DWi+/AOYIffnTZ8LXeATAPD/rcsNG/nzA1n4+' && 'QSY/cUBD/vsA8hsA4DeA/BFAfgMA/AaQPwLIbwCA3wDyRwD5DQDwGwDiN4D8EUB+AwD8Bp' && 'A/AshvAIDfAPJHAPkNAPAbAOA3AMBvAIDfABy/AXh+A/D8BpDf65INIP9K1yUbgOc3AM9v' && 'AJ7fADy/AXh+A/D8BuD5DcDzG+D4bu9eUhiGYTAIJ7ai9BFM73/aQpeFamcPheG/wTdeGl' && 'QBGADmNwDMbwCY3wAwvwFgfgPA/AaQ3yM+BgD5DQDzG0B+dM+QH10PmN8AML8BYH4DwPwG' && 'gPkNAPMbAOY3AMxvAJjfADC/AWB+A8D8BoD5DQDzGwDmNwDMbwCY3wAwvwFgfgPA/AaQH1' && '3Pmn9INHn3Qv9x6jN9LX/xX12dFTuzOMvsFqwdX98TY/j2166NIz8RIq/b3z79N8fTabrp' && 'KtbiAAAAAElFTkSuQmCC'. ENDMETHOD. "base64_logo ENDCLASS. "lcl_gui IMPLEMENTATION *&---------------------------------------------------------------------* *& Form run *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* FORM run. DATA: lx_exception TYPE REF TO lcx_exception, lv_ind TYPE t000-ccnocliind. IF sy-langu <> gc_english. WRITE: / 'Use English as logon language'. "#EC NOTEXT RETURN. ENDIF. SELECT SINGLE ccnocliind FROM t000 INTO lv_ind WHERE mandt = sy-mandt. IF sy-subrc = 0 AND lv_ind <> ' ' AND lv_ind <> '1'. " check changes allowed WRITE: / 'Wrong client, changes to repository objects not allowed'. "#EC NOTEXT RETURN. ENDIF. TRY. lcl_gui=>run( ). CATCH lcx_exception INTO lx_exception. MESSAGE lx_exception->mv_text TYPE 'E'. ENDTRY. CALL SELECTION-SCREEN 1001. " trigger screen ENDFORM. "run *&---------------------------------------------------------------------* *& Form branch_popup *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->TT_FIELDS text * -->PV_CODE text * -->CS_ERROR text * -->CV_SHOW_POPUP text * -->RAISING text * -->LCX_EXCEPTION text * -->##CALLED text * -->##NEEDED text *----------------------------------------------------------------------* FORM branch_popup TABLES tt_fields STRUCTURE sval USING pv_code TYPE clike CHANGING cs_error TYPE svale cv_show_popup TYPE c RAISING lcx_exception ##called ##needed. * called dynamically from function module POPUP_GET_VALUES_USER_BUTTONS DATA: lv_url TYPE string, lv_answer TYPE c, lx_error TYPE REF TO lcx_exception, lt_selection TYPE TABLE OF spopli, lt_branches TYPE lcl_git_transport=>ty_branch_list_tt. FIELD-SYMBOLS: LIKE LINE OF tt_fields, LIKE LINE OF lt_branches, LIKE LINE OF lt_selection, LIKE LINE OF tt_fields. CLEAR cs_error. IF pv_code = 'COD1'. cv_show_popup = abap_true. READ TABLE tt_fields ASSIGNING WITH KEY tabname = 'ABAPTXT255'. IF sy-subrc <> 0 OR -value IS INITIAL. MESSAGE 'Fill URL' TYPE 'S' DISPLAY LIKE 'E'. "#EC NOTEXT RETURN. ENDIF. lv_url = -value. TRY. lt_branches = lcl_git_transport=>branches( lv_url ). CATCH lcx_exception INTO lx_error. MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'. RETURN. ENDTRY. LOOP AT lt_branches ASSIGNING . APPEND INITIAL LINE TO lt_selection ASSIGNING . -varoption = -name. ENDLOOP. CALL FUNCTION 'POPUP_TO_DECIDE_LIST' EXPORTING textline1 = 'Select branch' titel = 'Select branch' IMPORTING answer = lv_answer TABLES t_spopli = lt_selection EXCEPTIONS not_enough_answers = 1 too_much_answers = 2 too_much_marks = 3 OTHERS = 4. "#EC NOTEXT IF sy-subrc <> 0. _raise 'Error from POPUP_TO_DECIDE_LIST'. ENDIF. IF lv_answer = 'A'. " cancel RETURN. ENDIF. READ TABLE lt_selection ASSIGNING WITH KEY selflag = abap_true. ASSERT sy-subrc = 0. READ TABLE tt_fields ASSIGNING WITH KEY tabname = 'TEXTL'. ASSERT sy-subrc = 0. -value = -varoption. ENDIF. ENDFORM. "branch_popup CLASS ltcl_convert DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PRIVATE SECTION. METHODS convert_int FOR TESTING RAISING lcx_exception. ENDCLASS. CLASS ltcl_convert IMPLEMENTATION. METHOD convert_int. DATA: lv_xstring TYPE xstring, lv_input TYPE i, lv_result TYPE i. DO 1000 TIMES. lv_input = sy-index. lv_xstring = lcl_convert=>int_to_xstring( iv_i = lv_input iv_length = 4 ). lv_result = lcl_convert=>xstring_to_int( lv_xstring ). cl_abap_unit_assert=>assert_equals( exp = lv_input act = lv_result ). ENDDO. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS ltcl_diff DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_diff DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PRIVATE SECTION. DATA: mt_local TYPE TABLE OF string, mt_remote TYPE TABLE OF string, mt_expected TYPE lcl_diff=>ty_diffs_tt, ms_expected LIKE LINE OF mt_expected. METHODS: setup. METHODS: test. METHODS: diff01 FOR TESTING, diff02 FOR TESTING, diff03 FOR TESTING, diff04 FOR TESTING, diff05 FOR TESTING, diff06 FOR TESTING. ENDCLASS. "ltcl_diff DEFINITION *----------------------------------------------------------------------* * CLASS ltcl_diff IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_diff IMPLEMENTATION. DEFINE _local. APPEND &1 TO mt_local. END-OF-DEFINITION. DEFINE _remote. APPEND &1 TO mt_remote. END-OF-DEFINITION. DEFINE _expected. CLEAR ms_expected. ms_expected-local = &1. ms_expected-result = &2. ms_expected-remote = &3. APPEND ms_expected TO mt_expected. END-OF-DEFINITION. METHOD setup. CLEAR mt_local. CLEAR mt_remote. CLEAR mt_expected. ENDMETHOD. "setup METHOD test. DATA: lv_local TYPE string, lv_xlocal TYPE xstring, lv_remote TYPE string, lv_xremote TYPE xstring, lo_diff TYPE REF TO lcl_diff, lt_diff TYPE lcl_diff=>ty_diffs_tt. CONCATENATE LINES OF mt_local INTO lv_local SEPARATED BY gc_newline. CONCATENATE LINES OF mt_remote INTO lv_remote SEPARATED BY gc_newline. lv_xlocal = lcl_convert=>string_to_xstring_utf8( lv_local ). lv_xremote = lcl_convert=>string_to_xstring_utf8( lv_remote ). CREATE OBJECT lo_diff EXPORTING iv_local = lv_xlocal iv_remote = lv_xremote. lt_diff = lo_diff->get( ). cl_abap_unit_assert=>assert_equals( act = lt_diff exp = mt_expected ). ENDMETHOD. "test METHOD diff01. * insert _local '1'. _expected '1' lcl_diff=>c_diff-insert ''. test( ). ENDMETHOD. "diff01 METHOD diff02. * identical _local '1'. _remote '1'. _expected '1' '' '1'. test( ). ENDMETHOD. "diff02 METHOD diff03. * delete _remote '1'. _expected '' lcl_diff=>c_diff-delete '1'. test( ). ENDMETHOD. "diff03 METHOD diff04. * update _local '1+'. _remote '1'. _expected '1+' lcl_diff=>c_diff-update '1'. test( ). ENDMETHOD. "diff04 METHOD diff05. * identical _local '1'. _local '2'. _remote '1'. _remote '2'. _expected '1' '' '1'. _expected '2' '' '2'. test( ). ENDMETHOD. "diff05 METHOD diff06. _local '1'. _local '2'. _local 'inserted'. _local '3'. _local '4 update'. _remote '1'. _remote '2'. _remote '3'. _remote '4'. _expected '1' '' '1'. _expected '2' '' '2'. _expected 'inserted' lcl_diff=>c_diff-insert ''. _expected '3' '' '3'. _expected '4 update' lcl_diff=>c_diff-update '4'. test( ). ENDMETHOD. "diff06 ENDCLASS. "ltcl_diff IMPLEMENTATION *----------------------------------------------------------------------* * CLASS test DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_git_pack DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PRIVATE SECTION. METHODS: tree FOR TESTING RAISING lcx_exception, commit FOR TESTING RAISING lcx_exception, pack_short FOR TESTING RAISING lcx_exception, pack_long FOR TESTING RAISING lcx_exception, pack_multiple FOR TESTING RAISING lcx_exception. METHODS: object_blob IMPORTING iv_data TYPE xstring RETURNING VALUE(rs_object) TYPE lcl_git_pack=>ty_object RAISING lcx_exception. ENDCLASS. "test DEFINITION *----------------------------------------------------------------------* * CLASS ltcl_url DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_url DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PRIVATE SECTION. METHODS repo_url FOR TESTING RAISING lcx_exception. METHODS repo_error FOR TESTING. ENDCLASS. "ltcl_url DEFINITION *----------------------------------------------------------------------* * CLASS ltcl_serialize DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_serialize DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PRIVATE SECTION. METHODS: check IMPORTING is_item TYPE ty_item RAISING lcx_exception, serialize_tabl FOR TESTING RAISING lcx_exception, serialize_enqu FOR TESTING RAISING lcx_exception, serialize_shlp FOR TESTING RAISING lcx_exception, serialize_view FOR TESTING RAISING lcx_exception, serialize_auth FOR TESTING RAISING lcx_exception, serialize_clas FOR TESTING RAISING lcx_exception, serialize_doma FOR TESTING RAISING lcx_exception, serialize_dtel FOR TESTING RAISING lcx_exception, serialize_fugr FOR TESTING RAISING lcx_exception, serialize_msag FOR TESTING RAISING lcx_exception, serialize_prog FOR TESTING RAISING lcx_exception, serialize_tran FOR TESTING RAISING lcx_exception, serialize_ttyp FOR TESTING RAISING lcx_exception. ENDCLASS. "ltcl_serialize DEFINITION *----------------------------------------------------------------------* * CLASS ltcl_serialize IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_serialize IMPLEMENTATION. METHOD serialize_enqu. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'ENQU'. ls_item-obj_name = 'E_USR04'. check( ls_item ). ENDMETHOD. "lcl_abap_unit METHOD serialize_shlp. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'SHLP'. ls_item-obj_name = 'USER_LOGON'. check( ls_item ). ENDMETHOD. "lcl_abap_unit METHOD serialize_view. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'VIEW'. ls_item-obj_name = 'VUSR02_HEADER'. check( ls_item ). ENDMETHOD. "lcl_abap_unit METHOD serialize_tabl. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'TABL'. ls_item-obj_name = 'USR02'. check( ls_item ). ENDMETHOD. "serialize_table METHOD serialize_auth. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'AUTH'. ls_item-obj_name = 'AREA'. check( ls_item ). ENDMETHOD. METHOD serialize_clas. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'CLAS'. ls_item-obj_name = 'CL_GUI_FRONTEND_SERVICES'. check( ls_item ). ENDMETHOD. METHOD serialize_doma. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'DOMA'. ls_item-obj_name = 'PGMID'. check( ls_item ). ENDMETHOD. METHOD serialize_dtel. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'DTEL'. ls_item-obj_name = 'PGMID'. check( ls_item ). ENDMETHOD. METHOD serialize_fugr. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'FUGR'. ls_item-obj_name = 'SRFC'. check( ls_item ). ENDMETHOD. METHOD serialize_msag. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'MSAG'. ls_item-obj_name = '00'. check( ls_item ). ENDMETHOD. METHOD serialize_prog. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'PROG'. ls_item-obj_name = 'SAPLWBABAP'. check( ls_item ). ENDMETHOD. METHOD serialize_tran. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'TRAN'. ls_item-obj_name = 'SE38'. check( ls_item ). ENDMETHOD. METHOD serialize_ttyp. DATA: ls_item TYPE ty_item. ls_item-obj_type = 'TTYP'. ls_item-obj_name = 'ABAPPROG'. check( ls_item ). ENDMETHOD. METHOD check. DATA: lt_files TYPE ty_files_tt. lt_files = lcl_objects=>serialize( is_item ). cl_abap_unit_assert=>assert_not_initial( lt_files ). ENDMETHOD. ENDCLASS. "ltcl_serialize IMPLEMENTATION *----------------------------------------------------------------------* * CLASS ltcl_url IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_url IMPLEMENTATION. METHOD repo_error. TRY. lcl_url=>host( 'not a real url' ). "#EC NOTEXT cl_abap_unit_assert=>fail( ). CATCH lcx_exception. "#EC NO_HANDLER ENDTRY. ENDMETHOD. "repo_error METHOD repo_url. DATA: lv_host TYPE string. lv_host = lcl_url=>host( 'https://github.com/larshp/Foobar.git' ). cl_abap_unit_assert=>assert_equals( exp = 'https://github.com' act = lv_host ). ENDMETHOD. "repo_url ENDCLASS. "ltcl_url IMPLEMENTATION *----------------------------------------------------------------------* * CLASS ltcl_abap_unit IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_git_pack IMPLEMENTATION. METHOD pack_multiple. CONSTANTS: lc_data TYPE x LENGTH 15 VALUE '123456789ABCDEF545794254754554', lc_sha TYPE ty_sha1 VALUE '5f46cb3c4b7f0b3600b64f744cde614a283a88dc'. DATA: lt_objects TYPE lcl_git_pack=>ty_objects_tt, ls_object LIKE LINE OF lt_objects, lt_nodes TYPE lcl_git_pack=>ty_nodes_tt, ls_node LIKE LINE OF lt_nodes, ls_commit TYPE lcl_git_pack=>ty_commit, lt_result TYPE lcl_git_pack=>ty_objects_tt, lv_data TYPE xstring. * blob lv_data = lc_data. CLEAR ls_object. ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = lv_data ). ls_object-type = gc_type-blob. ls_object-data = lv_data. APPEND ls_object TO lt_objects. * commit CLEAR ls_commit. ls_commit-tree = lc_sha. ls_commit-parent = lc_sha. ls_commit-author = 'John Foobar'. ls_commit-committer = 'John Foobar'. ls_commit-body = 'body'. lv_data = lcl_git_pack=>encode_commit( ls_commit ). CLEAR ls_object. ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-commit iv_data = lv_data ). ls_object-type = gc_type-commit. ls_object-data = lv_data. APPEND ls_object TO lt_objects. * tree CLEAR ls_node. ls_node-chmod = '12456'. ls_node-name = 'foobar.abap'. ls_node-sha1 = lc_sha. APPEND ls_node TO lt_nodes. lv_data = lcl_git_pack=>encode_tree( lt_nodes ). CLEAR ls_object. ls_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-tree iv_data = lv_data ). ls_object-type = gc_type-tree. ls_object-data = lv_data. APPEND ls_object TO lt_objects. CLEAR lv_data. lv_data = lcl_git_pack=>encode( lt_objects ). lt_result = lcl_git_pack=>decode( lv_data ). cl_abap_unit_assert=>assert_equals( exp = lt_objects act = lt_result ). ENDMETHOD. "encode_decode_pack_multiple METHOD object_blob. rs_object-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = iv_data ). rs_object-type = gc_type-blob. rs_object-data = iv_data. ENDMETHOD. METHOD pack_short. CONSTANTS: lc_data TYPE x LENGTH 8 VALUE '0123456789ABCDEF'. DATA: lt_objects TYPE lcl_git_pack=>ty_objects_tt, ls_object LIKE LINE OF lt_objects, lt_result TYPE lcl_git_pack=>ty_objects_tt, lv_data TYPE xstring. lv_data = lc_data. ls_object = object_blob( lv_data ). APPEND ls_object TO lt_objects. CLEAR lv_data. lv_data = lcl_git_pack=>encode( lt_objects ). lt_result = lcl_git_pack=>decode( lv_data ). cl_abap_unit_assert=>assert_equals( exp = lt_objects act = lt_result ). ENDMETHOD. "encode_decode_pack METHOD pack_long. CONSTANTS: lc_data TYPE x LENGTH 8 VALUE '0123456789ABCDEF'. DATA: lt_objects TYPE lcl_git_pack=>ty_objects_tt, ls_object LIKE LINE OF lt_objects, lv_xstring TYPE xstring, lt_result TYPE lcl_git_pack=>ty_objects_tt, lv_data TYPE xstring. lv_xstring = lc_data. DO 20 TIMES. CONCATENATE lv_xstring lv_data INTO lv_data IN BYTE MODE. ENDDO. ls_object = object_blob( lv_data ). APPEND ls_object TO lt_objects. CLEAR lv_data. lv_data = lcl_git_pack=>encode( lt_objects ). lt_result = lcl_git_pack=>decode( lv_data ). cl_abap_unit_assert=>assert_equals( exp = lt_objects act = lt_result ). ENDMETHOD. "encode_decode_pack_long METHOD tree. CONSTANTS: lc_sha TYPE ty_sha1 VALUE '5f46cb3c4b7f0b3600b64f744cde614a283a88dc'. DATA: lt_nodes TYPE lcl_git_pack=>ty_nodes_tt, ls_node LIKE LINE OF lt_nodes, lv_data TYPE xstring, lt_result TYPE lcl_git_pack=>ty_nodes_tt. CLEAR ls_node. ls_node-chmod = gc_chmod-file. ls_node-name = 'foobar.txt'. ls_node-sha1 = lc_sha. APPEND ls_node TO lt_nodes. lv_data = lcl_git_pack=>encode_tree( lt_nodes ). lt_result = lcl_git_pack=>decode_tree( lv_data ). cl_abap_unit_assert=>assert_equals( exp = lt_nodes act = lt_result ). ENDMETHOD. METHOD commit. CONSTANTS: lc_tree TYPE ty_sha1 VALUE '5f46cb3c4b7f0b3600b64f744cde614a283a88dc', lc_parent TYPE ty_sha1 VALUE '1236cb3c4b7f0b3600b64f744cde614a283a88dc'. DATA: ls_commit TYPE lcl_git_pack=>ty_commit, ls_result TYPE lcl_git_pack=>ty_commit, lv_data TYPE xstring. ls_commit-tree = lc_tree. ls_commit-parent = lc_parent. ls_commit-author = 'larshp 1387823471 +0100'. ls_commit-committer = 'larshp 1387823471 +0100'. ls_commit-body = 'very informative'. lv_data = lcl_git_pack=>encode_commit( ls_commit ). ls_result = lcl_git_pack=>decode_commit( lv_data ). cl_abap_unit_assert=>assert_equals( exp = ls_commit act = ls_result ). ENDMETHOD. ENDCLASS. "lcl_abap_unit IMPLEMENTATION CLASS ltcl_object_types DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PRIVATE SECTION. METHODS: is_supported FOR TESTING, not_exist FOR TESTING RAISING lcx_exception. ENDCLASS. CLASS ltcl_object_types IMPLEMENTATION. METHOD is_supported. DATA: ls_item TYPE ty_item, lv_supported TYPE abap_bool, lt_types TYPE lcl_objects=>ty_types_tt. FIELD-SYMBOLS: LIKE LINE OF lt_types. lt_types = lcl_objects=>supported_list( ). LOOP AT lt_types ASSIGNING . CLEAR ls_item. ls_item-obj_type = . lv_supported = lcl_objects=>is_supported( ls_item ). cl_abap_unit_assert=>assert_equals( act = lv_supported exp = abap_true msg = ls_item-obj_type quit = if_aunit_constants=>no ). ENDLOOP. ENDMETHOD. METHOD not_exist. DATA: ls_item TYPE ty_item, lv_exists TYPE abap_bool, lt_types TYPE lcl_objects=>ty_types_tt. FIELD-SYMBOLS: LIKE LINE OF lt_types. lt_types = lcl_objects=>supported_list( ). LOOP AT lt_types ASSIGNING . CLEAR ls_item. ls_item-obj_name = 'ZABAPGIT_FOOBAR'. ls_item-obj_type = . lv_exists = lcl_objects=>exists( ls_item ). cl_abap_unit_assert=>assert_equals( act = lv_exists exp = abap_false msg = ls_item-obj_type quit = if_aunit_constants=>no ). ENDLOOP. ENDMETHOD. ENDCLASS. *----------------------------------------------------------------------* * CLASS ltcl_zlib DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_zlib DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PRIVATE SECTION. METHODS: decompress FOR TESTING RAISING cx_dynamic_check. ENDCLASS. "ltcl_zlib DEFINITION *----------------------------------------------------------------------* * CLASS ltcl_zlib IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS ltcl_zlib IMPLEMENTATION. METHOD decompress. DATA: ls_data TYPE lcl_zlib=>ty_decompress. CONSTANTS: lc_raw TYPE xstring VALUE '48656C6C6F20576F726C64210D0A', lc_compressed TYPE xstring VALUE 'F348CDC9C95708CF2FCA4951E4E5020024E90455'. ls_data = lcl_zlib=>decompress( lc_compressed ). cl_abap_unit_assert=>assert_not_initial( ls_data-raw ). cl_abap_unit_assert=>assert_equals( act = ls_data-raw exp = lc_raw ). ENDMETHOD. "decompress ENDCLASS. CLASS ltcl_dangerous DEFINITION FOR TESTING RISK LEVEL CRITICAL DURATION LONG FINAL. * if this test class does not run, parameters in transaction SAUNIT_CLIENT_SETUP * might need to be adjusted PRIVATE SECTION. CLASS-METHODS: class_setup. METHODS: run FOR TESTING RAISING lcx_exception, check_empty_package RAISING lcx_exception. CONSTANTS: c_package TYPE devclass VALUE '$ABAPGIT_UNIT_TEST'. ENDCLASS. CLASS ltcl_dangerous IMPLEMENTATION. METHOD class_setup. DATA: lv_text TYPE c LENGTH 100, lv_answer TYPE c LENGTH 1. lv_text = 'Objects will be created and deleted, do not run in customer system!'. CALL FUNCTION 'POPUP_TO_CONFIRM' EXPORTING titlebar = 'Warning' text_question = lv_text text_button_1 = 'Run' text_button_2 = 'Cancel' default_button = '2' display_cancel_button = abap_false IMPORTING answer = lv_answer. IF lv_answer = '2'. cl_abap_unit_assert=>fail( 'Cancelled' ). ENDIF. ENDMETHOD. METHOD check_empty_package. DATA: lt_tadir TYPE lcl_tadir=>ty_tadir_tt. lt_tadir = lcl_tadir=>read( c_package ). IF lines( lt_tadir ) > 0. cl_abap_unit_assert=>fail( 'Prerequsite: package should be empty' ). ENDIF. ENDMETHOD. METHOD run. DATA: lo_repo TYPE REF TO lcl_repo_online, lt_tadir TYPE lcl_tadir=>ty_tadir_tt, lv_msg TYPE string, lt_results TYPE lcl_file_status=>ty_results_tt, lt_types TYPE lcl_objects=>ty_types_tt. FIELD-SYMBOLS: LIKE LINE OF lt_results, LIKE LINE OF lt_tadir, LIKE LINE OF lt_types. lt_types = lcl_objects=>supported_list( ). lo_repo = lcl_repo_srv=>new_online( iv_url = 'https://github.com/larshp/abapGit-Unit-Test.git' iv_branch_name = 'refs/heads/master' iv_package = c_package ). lo_repo->status( ). lo_repo->deserialize( ). lt_tadir = lcl_tadir=>read( c_package ). LOOP AT lt_types ASSIGNING . READ TABLE lt_tadir WITH KEY object = TRANSPORTING NO FIELDS. IF sy-subrc <> 0. lv_msg = |Missing object type { }|. cl_abap_unit_assert=>fail( msg = lv_msg level = if_aunit_constants=>tolerable quit = if_aunit_constants=>no ). ENDIF. ENDLOOP. lt_results = lo_repo->status( ). LOOP AT lt_results ASSIGNING WHERE match = abap_false. lv_msg = |Does not match { -obj_type } { -obj_name }|. cl_abap_unit_assert=>fail( msg = lv_msg quit = if_aunit_constants=>no ). ENDLOOP. lcl_objects=>delete( lt_tadir ). lt_tadir = lcl_tadir=>read( c_package ). LOOP AT lt_tadir ASSIGNING . lv_msg = |Not deleted properly { -object } { -obj_name }|. cl_abap_unit_assert=>fail( msg = lv_msg quit = if_aunit_constants=>no ). ENDLOOP. lcl_repo_srv=>delete( lo_repo ). ENDMETHOD. ENDCLASS.