diff --git a/src/objects/core/zcl_abapgit_file_deserialize.clas.abap b/src/objects/core/zcl_abapgit_file_deserialize.clas.abap index aa13dd113..52dc4b90e 100644 --- a/src/objects/core/zcl_abapgit_file_deserialize.clas.abap +++ b/src/objects/core/zcl_abapgit_file_deserialize.clas.abap @@ -209,7 +209,7 @@ CLASS zcl_abapgit_file_deserialize IMPLEMENTATION. WHEN 'IARP'. lt_requires = lt_items. DELETE lt_requires WHERE obj_type <> 'IASP'. - WHEN 'IATU' OR 'IAXU'. + WHEN 'IATU' OR 'IAXU' OR 'IAMU'. lt_requires = lt_items. DELETE lt_requires WHERE obj_type <> 'IASP' AND obj_type <> 'PROG' diff --git a/src/objects/zcl_abapgit_object_iamu.clas.abap b/src/objects/zcl_abapgit_object_iamu.clas.abap index 635709602..1ccc5c865 100644 --- a/src/objects/zcl_abapgit_object_iamu.clas.abap +++ b/src/objects/zcl_abapgit_object_iamu.clas.abap @@ -8,11 +8,19 @@ CLASS zcl_abapgit_object_iamu DEFINITION PUBLIC INHERITING FROM zcl_abapgit_obje attributes TYPE w3mimeattr, source TYPE w3mimetabtype, length TYPE i, + extension TYPE string, END OF ty_internet_appl_comp_binary. DATA: mi_mime_api TYPE REF TO if_w3_api_mime. METHODS: + get_extension + IMPORTING + iv_name TYPE csequence + iv_data TYPE xstring + RETURNING + VALUE(rv_extension) TYPE string, + load_mime_api RAISING zcx_abapgit_exception, @@ -29,7 +37,9 @@ CLASS zcl_abapgit_object_iamu DEFINITION PUBLIC INHERITING FROM zcl_abapgit_obje RAISING zcx_abapgit_exception, - release_lock + lock + IMPORTING + iv_changable TYPE abap_bool RAISING zcx_abapgit_exception. @@ -40,6 +50,41 @@ ENDCLASS. CLASS zcl_abapgit_object_iamu IMPLEMENTATION. + METHOD get_extension. + + CONSTANTS: + lc_jpg TYPE xstring VALUE 'FFD8FF', + lc_png TYPE xstring VALUE '89504E470D0A1A0A', + lc_gif TYPE xstring VALUE '47494638', + lc_bmp TYPE xstring VALUE '424D'. + + DATA lv_len TYPE i. + + " Try to derive type of MIME object from the long name + FIND REGEX '\.(\w)$' IN iv_name SUBMATCHES rv_extension. + IF sy-subrc = 0. + rv_extension = to_lower( rv_extension ). + ELSEIF zcl_abapgit_utils=>is_binary( iv_data ) = abap_true. + " Use magic numbers to detect common file types + lv_len = xstrlen( iv_data ). + IF lv_len > 3 AND iv_data(3) = lc_jpg. + rv_extension = 'jpg'. + ELSEIF lv_len > 8 AND iv_data(8) = lc_png. + rv_extension = 'png'. + ELSEIF lv_len > 4 AND iv_data(4) = lc_gif. + rv_extension = 'git'. + ELSEIF lv_len > 2 AND iv_data(2) = lc_bmp. + rv_extension = 'bmp'. + ELSE. + rv_extension = 'bin'. + ENDIF. + ELSE. + rv_extension = 'txt'. + ENDIF. + + ENDMETHOD. + + METHOD load_mime_api. DATA: ls_mime_name TYPE iacikeym. @@ -65,6 +110,33 @@ CLASS zcl_abapgit_object_iamu IMPLEMENTATION. ENDMETHOD. + METHOD lock. + + " As a side effect this method removes also existing locks + mi_mime_api->if_w3_api_object~set_changeable( + EXPORTING + p_changeable = iv_changable + EXCEPTIONS + action_cancelled = 1 + object_locked_by_other_user = 2 + permission_failure = 3 + object_already_changeable = 4 + object_already_unlocked = 5 + object_just_created = 6 + object_deleted = 7 + object_modified = 8 + object_not_existing = 9 + object_invalid = 10 + error_occured = 11 + OTHERS = 12 ). + + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~set_changeable| ). + ENDIF. + + ENDMETHOD. + + METHOD read. load_mime_api( ). @@ -104,54 +176,66 @@ CLASS zcl_abapgit_object_iamu IMPLEMENTATION. ENDMETHOD. - METHOD release_lock. - - " As a side effect this method removes also existing locks - mi_mime_api->if_w3_api_object~set_changeable( - EXPORTING - p_changeable = abap_false - EXCEPTIONS - action_cancelled = 1 - object_locked_by_other_user = 2 - permission_failure = 3 - object_already_changeable = 4 - object_already_unlocked = 5 - object_just_created = 6 - object_deleted = 7 - object_modified = 8 - object_not_existing = 9 - object_invalid = 10 - error_occured = 11 - OTHERS = 12 ). - - IF sy-subrc <> 0. - zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~set_changeable| ). - ENDIF. - - ENDMETHOD. - - METHOD save. - cl_w3_api_mime=>if_w3_api_mime~create_new( + IF zif_abapgit_object~exists( ) = abap_true. + load_mime_api( ). + lock( abap_true ). + + mi_mime_api->set_source( + EXPORTING + p_source = is_internet_appl_comp_binary-source + p_datalength = is_internet_appl_comp_binary-length + EXCEPTIONS + object_not_changeable = 1 + object_deleted = 2 + object_invalid = 3 + authorize_failure = 4 + invalid_content = 5 + error_occured = 6 + OTHERS = 7 ). + + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise( |Error { sy-subrc } from set_source| ). + ENDIF. + ELSE. + cl_w3_api_mime=>if_w3_api_mime~create_new( + EXPORTING + p_mime_data = is_internet_appl_comp_binary-attributes + p_mime_content = is_internet_appl_comp_binary-source + p_datalength = is_internet_appl_comp_binary-length + IMPORTING + p_mime = mi_mime_api + EXCEPTIONS + object_already_existing = 1 + object_just_created = 2 + not_authorized = 3 + undefined_name = 4 + author_not_existing = 5 + action_cancelled = 6 + error_occured = 7 + OTHERS = 8 ). + + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise( |Error { sy-subrc } from create_new| ). + ENDIF. + ENDIF. + + " Create_new does not update text, so set attributes explicitly + mi_mime_api->set_attributes( EXPORTING - p_mime_data = is_internet_appl_comp_binary-attributes - p_mime_content = is_internet_appl_comp_binary-source - p_datalength = is_internet_appl_comp_binary-length - IMPORTING - p_mime = mi_mime_api + p_attributes = is_internet_appl_comp_binary-attributes EXCEPTIONS - object_already_existing = 1 - object_just_created = 2 - not_authorized = 3 - undefined_name = 4 - author_not_existing = 5 - action_cancelled = 6 - error_occured = 7 - OTHERS = 8 ). + object_not_changeable = 1 + object_deleted = 2 + object_invalid = 3 + author_not_existing = 4 + authorize_failure = 5 + error_occured = 6 + OTHERS = 7 ). IF sy-subrc <> 0. - zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~create_new| ). + zcx_abapgit_exception=>raise( |Error { sy-subrc } from set_attributes| ). ENDIF. mi_mime_api->if_w3_api_object~save( @@ -166,10 +250,10 @@ CLASS zcl_abapgit_object_iamu IMPLEMENTATION. OTHERS = 8 ). IF sy-subrc <> 0. - zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~save| ). + zcx_abapgit_exception=>raise( |Error { sy-subrc } from save| ). ENDIF. - release_lock( ). + lock( abap_false ). ENDMETHOD. @@ -238,6 +322,7 @@ CLASS zcl_abapgit_object_iamu IMPLEMENTATION. METHOD zif_abapgit_object~deserialize. DATA: ls_internet_appl_comp_binary TYPE ty_internet_appl_comp_binary. + DATA lv_xstring TYPE xstring. io_xml->read( EXPORTING @@ -247,6 +332,17 @@ CLASS zcl_abapgit_object_iamu IMPLEMENTATION. ls_internet_appl_comp_binary-attributes-devclass = iv_package. + IF io_xml->get_metadata( )-version = 'v2.0.0'. + lv_xstring = zif_abapgit_object~mo_files->read_raw( ls_internet_appl_comp_binary-extension ). + + zcl_abapgit_convert=>xstring_to_bintab( + EXPORTING + iv_xstr = lv_xstring + IMPORTING + et_bintab = ls_internet_appl_comp_binary-source + ev_size = ls_internet_appl_comp_binary-length ). + ENDIF. + save( ls_internet_appl_comp_binary ). ENDMETHOD. @@ -283,9 +379,8 @@ CLASS zcl_abapgit_object_iamu IMPLEMENTATION. METHOD zif_abapgit_object~get_metadata. - - rs_metadata = get_metadata( ). - + rs_metadata = get_metadata( ). + rs_metadata-version = 'v2.0.0'. " Serialization v2, separate data file ENDMETHOD. @@ -319,9 +414,28 @@ CLASS zcl_abapgit_object_iamu IMPLEMENTATION. METHOD zif_abapgit_object~serialize. DATA: ls_internet_appl_comp_binary TYPE ty_internet_appl_comp_binary. + DATA lv_xstring TYPE xstring. + + FIELD-SYMBOLS: LIKE LINE OF ls_internet_appl_comp_binary-source. ls_internet_appl_comp_binary = read( ). + " Seriazation v2, separate data file + LOOP AT ls_internet_appl_comp_binary-source ASSIGNING . + lv_xstring = lv_xstring && -line. + ENDLOOP. + lv_xstring = lv_xstring(ls_internet_appl_comp_binary-length). + + CLEAR: ls_internet_appl_comp_binary-source, ls_internet_appl_comp_binary-length. + + ls_internet_appl_comp_binary-extension = get_extension( + iv_name = ls_internet_appl_comp_binary-attributes-longname + iv_data = lv_xstring ). + + zif_abapgit_object~mo_files->add_raw( + iv_data = lv_xstring + iv_ext = ls_internet_appl_comp_binary-extension ). + io_xml->add( iv_name = 'IAMU' ig_data = ls_internet_appl_comp_binary ). diff --git a/src/utils/zcl_abapgit_convert.clas.abap b/src/utils/zcl_abapgit_convert.clas.abap index fd5cab34b..72e645d58 100644 --- a/src/utils/zcl_abapgit_convert.clas.abap +++ b/src/utils/zcl_abapgit_convert.clas.abap @@ -93,7 +93,7 @@ CLASS zcl_abapgit_convert DEFINITION CLASS-METHODS language_sap2_to_sap1 IMPORTING - im_lang_sap2 TYPE laiso + im_lang_sap2 TYPE laiso RETURNING VALUE(re_lang_sap1) TYPE sy-langu EXCEPTIONS @@ -110,7 +110,7 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_CONVERT IMPLEMENTATION. +CLASS zcl_abapgit_convert IMPLEMENTATION. METHOD base64_to_xstring. @@ -159,7 +159,7 @@ CLASS ZCL_ABAPGIT_CONVERT IMPLEMENTATION. re_lang_sap2 = rv_spras EXCEPTIONS no_assignment = 1 - OTHERS = 2 ). "#EC CI_SUBRC + OTHERS = 2 ). "#EC CI_SUBRC TRANSLATE rv_spras TO UPPER CASE. @@ -323,6 +323,7 @@ CLASS ZCL_ABAPGIT_CONVERT IMPLEMENTATION. DATA lv_length TYPE i. DATA lv_iterations TYPE i. DATA lv_offset TYPE i. + DATA lv_struct TYPE abap_bool. FIELD-SYMBOLS TYPE any. @@ -331,6 +332,11 @@ CLASS ZCL_ABAPGIT_CONVERT IMPLEMENTATION. ev_size = xstrlen( iv_xstr ). APPEND INITIAL LINE TO et_bintab ASSIGNING . + lv_struct = boolc( + cl_abap_typedescr=>describe_by_data( )->type_kind = cl_abap_typedescr=>typekind_struct1 ). + IF lv_struct = abap_true. + ASSIGN COMPONENT 1 OF STRUCTURE TO . + ENDIF. = iv_xstr. lv_length = cl_abap_typedescr=>describe_by_data( )->length. @@ -339,6 +345,9 @@ CLASS ZCL_ABAPGIT_CONVERT IMPLEMENTATION. DO lv_iterations TIMES. lv_offset = sy-index * lv_length. APPEND INITIAL LINE TO et_bintab ASSIGNING . + IF lv_struct = abap_true. + ASSIGN COMPONENT 1 OF STRUCTURE TO . + ENDIF. = iv_xstr+lv_offset. ENDDO. diff --git a/src/utils/zcl_abapgit_convert.clas.testclasses.abap b/src/utils/zcl_abapgit_convert.clas.testclasses.abap index 6146344f5..4b50711d8 100644 --- a/src/utils/zcl_abapgit_convert.clas.testclasses.abap +++ b/src/utils/zcl_abapgit_convert.clas.testclasses.abap @@ -18,6 +18,7 @@ CLASS ltcl_convert DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FIN METHODS string_to_tab FOR TESTING. METHODS string_to_xstring FOR TESTING RAISING zcx_abapgit_exception. METHODS xstring_to_bintab FOR TESTING. + METHODS xstring_to_bintab_with_field FOR TESTING. ENDCLASS. @@ -51,6 +52,29 @@ CLASS ltcl_convert IMPLEMENTATION. ENDMETHOD. + METHOD xstring_to_bintab_with_field. + + DATA lt_bintab TYPE TABLE OF w3mime. " contains one field named 'LINE' + DATA lv_size TYPE i. + + zcl_abapgit_convert=>xstring_to_bintab( + EXPORTING + iv_xstr = '1122334455' + IMPORTING + ev_size = lv_size + et_bintab = lt_bintab ). + + cl_abap_unit_assert=>assert_equals( + act = lv_size + exp = 5 ). + + cl_abap_unit_assert=>assert_equals( + act = lines( lt_bintab ) + exp = 1 ). + + ENDMETHOD. + + METHOD string_to_xstring. DATA lv_xstr TYPE xstring.