From 392562ef22c8295a55957ac26f7b893dbedf7bb4 Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Mon, 18 Jan 2021 09:37:18 +0100 Subject: [PATCH] update ajson to latest (#4417) --- package.json | 8 +- src/json/zcl_abapgit_ajson.clas.abap | 54 ++-- .../zcl_abapgit_ajson.clas.locals_imp.abap | 103 +++++-- .../zcl_abapgit_ajson.clas.testclasses.abap | 3 - src/json/zcl_abapgit_ajson_mapping.clas.abap | 80 ++++++ ...abapgit_ajson_mapping.clas.locals_def.abap | 71 +++++ ...abapgit_ajson_mapping.clas.locals_imp.abap | 183 ++++++++++++ ...bapgit_ajson_mapping.clas.testclasses.abap | 269 ++++++++++++++++++ src/json/zcl_abapgit_ajson_mapping.clas.xml | 17 ++ src/json/zif_abapgit_ajson_mapping.intf.abap | 27 ++ src/json/zif_abapgit_ajson_mapping.intf.xml | 15 + 11 files changed, 784 insertions(+), 46 deletions(-) create mode 100644 src/json/zcl_abapgit_ajson_mapping.clas.abap create mode 100644 src/json/zcl_abapgit_ajson_mapping.clas.locals_def.abap create mode 100644 src/json/zcl_abapgit_ajson_mapping.clas.locals_imp.abap create mode 100644 src/json/zcl_abapgit_ajson_mapping.clas.testclasses.abap create mode 100644 src/json/zcl_abapgit_ajson_mapping.clas.xml create mode 100644 src/json/zif_abapgit_ajson_mapping.intf.abap create mode 100644 src/json/zif_abapgit_ajson_mapping.intf.xml diff --git a/package.json b/package.json index b42f57ac9..349afd97d 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,10 @@ "url": "git+https://github.com/abapGit/abapGit.git" }, "devDependencies": { - "@abaplint/cli": "^2.64.3", - "@abaplint/transpiler-cli": "^1.1.24", - "@abaplint/runtime": "^1.1.24", + "@abaplint/cli": "^2.64.5", + "@abaplint/transpiler-cli": "^1.1.25", + "@abaplint/runtime": "^1.1.25", "abapmerge": "^0.14.2", - "eslint": "^7.17.0" + "eslint": "^7.18.0" } } diff --git a/src/json/zcl_abapgit_ajson.clas.abap b/src/json/zcl_abapgit_ajson.clas.abap index 9f8ecf876..6d7533645 100644 --- a/src/json/zcl_abapgit_ajson.clas.abap +++ b/src/json/zcl_abapgit_ajson.clas.abap @@ -41,14 +41,17 @@ CLASS zcl_abapgit_ajson DEFINITION CLASS-METHODS parse IMPORTING - !iv_json TYPE string - !iv_freeze TYPE abap_bool DEFAULT abap_false + !iv_json TYPE string + !iv_freeze TYPE abap_bool DEFAULT abap_false + !ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL RETURNING VALUE(ro_instance) TYPE REF TO zcl_abapgit_ajson RAISING zcx_abapgit_ajson_error . CLASS-METHODS create_empty + IMPORTING + !ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL RETURNING VALUE(ro_instance) TYPE REF TO zcl_abapgit_ajson. @@ -60,24 +63,25 @@ CLASS zcl_abapgit_ajson DEFINITION tty_node_stack TYPE STANDARD TABLE OF REF TO zif_abapgit_ajson=>ty_node WITH DEFAULT KEY. DATA mv_read_only TYPE abap_bool. + DATA mi_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping. DATA mv_keep_item_order TYPE abap_bool. METHODS get_item IMPORTING - iv_path TYPE string + iv_path TYPE string RETURNING VALUE(rv_item) TYPE REF TO zif_abapgit_ajson=>ty_node. METHODS prove_path_exists IMPORTING - iv_path TYPE string + iv_path TYPE string RETURNING VALUE(rt_node_stack) TYPE tty_node_stack RAISING zcx_abapgit_ajson_error. METHODS delete_subtree IMPORTING - iv_path TYPE string - iv_name TYPE string + iv_path TYPE string + iv_name TYPE string RETURNING VALUE(rv_deleted) TYPE abap_bool. @@ -90,6 +94,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION. METHOD create_empty. CREATE OBJECT ro_instance. + ro_instance->mi_custom_mapping = ii_custom_mapping. ENDMETHOD. @@ -157,6 +162,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION. CREATE OBJECT ro_instance. CREATE OBJECT lo_parser. ro_instance->mt_json_tree = lo_parser->parse( iv_json ). + ro_instance->mi_custom_mapping = ii_custom_mapping. IF iv_freeze = abap_true. ro_instance->freeze( ). @@ -402,9 +408,11 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION. CLEAR ev_container. lcl_json_to_abap=>bind( + EXPORTING + ii_custom_mapping = mi_custom_mapping CHANGING - c_obj = ev_container - co_instance = lo_to_abap ). + c_obj = ev_container + co_instance = lo_to_abap ). lo_to_abap->to_abap( mt_json_tree ). ENDMETHOD. @@ -479,11 +487,9 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION. METHOD zif_abapgit_ajson_writer~set. - DATA lt_path TYPE string_table. DATA ls_split_path TYPE zif_abapgit_ajson=>ty_path_name. DATA lr_parent TYPE REF TO zif_abapgit_ajson=>ty_node. DATA lt_node_stack TYPE tty_node_stack. - FIELD-SYMBOLS TYPE zif_abapgit_ajson=>ty_node. IF mv_read_only = abap_true. zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ). @@ -504,14 +510,16 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION. IF iv_node_type IS NOT INITIAL. mt_json_tree = lcl_abap_to_json=>insert_with_type( iv_keep_item_order = mv_keep_item_order - iv_data = iv_val - iv_type = iv_node_type - is_prefix = ls_split_path ). + iv_data = iv_val + iv_type = iv_node_type + is_prefix = ls_split_path + ii_custom_mapping = mi_custom_mapping ). ELSE. mt_json_tree = lcl_abap_to_json=>convert( iv_keep_item_order = mv_keep_item_order - iv_data = iv_val - is_prefix = ls_split_path ). + iv_data = iv_val + is_prefix = ls_split_path + ii_custom_mapping = mi_custom_mapping ). ENDIF. RETURN. ENDIF. @@ -539,16 +547,18 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION. IF iv_node_type IS NOT INITIAL. lt_new_nodes = lcl_abap_to_json=>insert_with_type( iv_keep_item_order = mv_keep_item_order - iv_data = iv_val - iv_type = iv_node_type - iv_array_index = lv_array_index - is_prefix = ls_split_path ). + iv_data = iv_val + iv_type = iv_node_type + iv_array_index = lv_array_index + is_prefix = ls_split_path + ii_custom_mapping = mi_custom_mapping ). ELSE. lt_new_nodes = lcl_abap_to_json=>convert( iv_keep_item_order = mv_keep_item_order - iv_data = iv_val - iv_array_index = lv_array_index - is_prefix = ls_split_path ). + iv_data = iv_val + iv_array_index = lv_array_index + is_prefix = ls_split_path + ii_custom_mapping = mi_custom_mapping ). ENDIF. " update data diff --git a/src/json/zcl_abapgit_ajson.clas.locals_imp.abap b/src/json/zcl_abapgit_ajson.clas.locals_imp.abap index dce23c6e8..ae3939d03 100644 --- a/src/json/zcl_abapgit_ajson.clas.locals_imp.abap +++ b/src/json/zcl_abapgit_ajson.clas.locals_imp.abap @@ -504,9 +504,11 @@ CLASS lcl_json_to_abap DEFINITION FINAL. zcx_abapgit_ajson_error. CLASS-METHODS bind + IMPORTING + !ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL CHANGING - c_obj TYPE any - co_instance TYPE REF TO lcl_json_to_abap. + c_obj TYPE any + co_instance TYPE REF TO lcl_json_to_abap. METHODS to_abap IMPORTING @@ -516,6 +518,8 @@ CLASS lcl_json_to_abap DEFINITION FINAL. PRIVATE SECTION. DATA mr_obj TYPE REF TO data. + DATA mi_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping. + ENDCLASS. CLASS lcl_json_to_abap IMPLEMENTATION. @@ -523,6 +527,7 @@ CLASS lcl_json_to_abap IMPLEMENTATION. METHOD bind. CREATE OBJECT co_instance. GET REFERENCE OF c_obj INTO co_instance->mr_obj. + co_instance->mi_custom_mapping = ii_custom_mapping. ENDMETHOD. METHOD to_abap. @@ -599,6 +604,7 @@ CLASS lcl_json_to_abap IMPLEMENTATION. DATA lt_path TYPE string_table. DATA lv_trace TYPE string. + DATA lv_seg LIKE LINE OF lt_path. DATA lv_type TYPE c. DATA lv_size TYPE i. DATA lv_index TYPE i. @@ -617,7 +623,19 @@ CLASS lcl_json_to_abap IMPLEMENTATION. LOOP AT lt_path ASSIGNING . lv_trace = lv_trace && '/' && . - = to_upper( ). + + IF mi_custom_mapping IS BOUND. + lv_seg = mi_custom_mapping->to_abap( iv_path = iv_path + iv_name = ). + ELSE. + CLEAR lv_seg. + ENDIF. + + IF lv_seg IS INITIAL. + lv_seg = to_upper( ). + ELSE. + lv_seg = to_upper( lv_seg ). + ENDIF. ASSIGN r_ref->* TO . ASSERT sy-subrc = 0. @@ -630,12 +648,12 @@ CLASS lcl_json_to_abap IMPLEMENTATION. iv_location = lv_trace ). ELSEIF lv_type = 'h'. " table - IF NOT CO '0123456789'. + IF NOT lv_seg CO '0123456789'. zcx_abapgit_ajson_error=>raise( iv_msg = 'Need index to access tables' iv_location = lv_trace ). ENDIF. - lv_index = . + lv_index = lv_seg. ASSIGN r_ref->* TO . ASSERT sy-subrc = 0. @@ -652,7 +670,7 @@ CLASS lcl_json_to_abap IMPLEMENTATION. ENDIF. ELSEIF lv_type CA 'uv'. " structure - ASSIGN COMPONENT OF STRUCTURE TO . + ASSIGN COMPONENT lv_seg OF STRUCTURE TO . IF sy-subrc <> 0. zcx_abapgit_ajson_error=>raise( iv_msg = 'Path not found' @@ -679,24 +697,26 @@ CLASS lcl_abap_to_json DEFINITION FINAL. CLASS-METHODS convert IMPORTING - iv_data TYPE any - is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL - iv_array_index TYPE i DEFAULT 0 + iv_data TYPE any + is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL + iv_array_index TYPE i DEFAULT 0 + ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL iv_keep_item_order TYPE abap_bool DEFAULT abap_false RETURNING - VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt + VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt RAISING zcx_abapgit_ajson_error. CLASS-METHODS insert_with_type IMPORTING - iv_data TYPE any - iv_type TYPE string - is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL - iv_array_index TYPE i DEFAULT 0 + iv_data TYPE any + iv_type TYPE string + is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL + iv_array_index TYPE i DEFAULT 0 + ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL iv_keep_item_order TYPE abap_bool DEFAULT abap_false RETURNING - VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt + VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt RAISING zcx_abapgit_ajson_error. @@ -705,6 +725,7 @@ CLASS lcl_abap_to_json DEFINITION FINAL. PRIVATE SECTION. CLASS-DATA gv_ajson_absolute_type_name TYPE string. + DATA mi_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping. DATA mv_keep_item_order TYPE abap_bool. METHODS convert_any @@ -742,7 +763,6 @@ CLASS lcl_abap_to_json DEFINITION FINAL. METHODS convert_ref IMPORTING iv_data TYPE any - io_type TYPE REF TO cl_abap_typedescr is_prefix TYPE zif_abapgit_ajson=>ty_path_name iv_index TYPE i DEFAULT 0 iv_item_order TYPE i DEFAULT 0 @@ -808,7 +828,9 @@ CLASS lcl_abap_to_json IMPLEMENTATION. DATA lo_converter TYPE REF TO lcl_abap_to_json. lo_type = cl_abap_typedescr=>describe_by_data( iv_data ). + CREATE OBJECT lo_converter. + lo_converter->mi_custom_mapping = ii_custom_mapping. lo_converter->mv_keep_item_order = iv_keep_item_order. lo_converter->convert_any( @@ -864,7 +886,6 @@ CLASS lcl_abap_to_json IMPLEMENTATION. convert_ref( EXPORTING iv_data = iv_data - io_type = io_type is_prefix = is_prefix iv_index = iv_index iv_item_order = iv_item_order @@ -918,6 +939,15 @@ CLASS lcl_abap_to_json IMPLEMENTATION. -index = iv_index. -order = iv_item_order. + IF mi_custom_mapping IS BOUND. + -name = mi_custom_mapping->to_json( iv_path = is_prefix-path + iv_name = is_prefix-name ). + ENDIF. + + IF -name IS INITIAL. + -name = is_prefix-name. + ENDIF. + IF io_type->absolute_name = '\TYPE-POOL=ABAP\TYPE=ABAP_BOOL' OR io_type->absolute_name = '\TYPE=XFELD'. -type = zif_abapgit_ajson=>node_type-boolean. IF iv_data IS NOT INITIAL. @@ -949,6 +979,15 @@ CLASS lcl_abap_to_json IMPLEMENTATION. -index = iv_index. -order = iv_item_order. + IF mi_custom_mapping IS BOUND. + -name = mi_custom_mapping->to_json( iv_path = is_prefix-path + iv_name = is_prefix-name ). + ENDIF. + + IF -name IS INITIAL. + -name = is_prefix-name. + ENDIF. + IF iv_data IS INITIAL. -type = zif_abapgit_ajson=>node_type-null. -value = 'null'. @@ -985,6 +1024,16 @@ CLASS lcl_abap_to_json IMPLEMENTATION. -name = is_prefix-name. -type = zif_abapgit_ajson=>node_type-object. -index = iv_index. + + IF mi_custom_mapping IS BOUND. + -name = mi_custom_mapping->to_json( iv_path = is_prefix-path + iv_name = is_prefix-name ). + ENDIF. + + IF -name IS INITIAL. + -name = is_prefix-name. + ENDIF. + -order = iv_item_order. ENDIF. @@ -1049,6 +1098,15 @@ CLASS lcl_abap_to_json IMPLEMENTATION. -index = iv_index. -order = iv_item_order. + IF mi_custom_mapping IS BOUND. + -name = mi_custom_mapping->to_json( iv_path = is_prefix-path + iv_name = is_prefix-name ). + ENDIF. + + IF -name IS INITIAL. + -name = is_prefix-name. + ENDIF. + ls_next_prefix-path = is_prefix-path && is_prefix-name && '/'. ASSIGN iv_data TO . @@ -1075,7 +1133,9 @@ CLASS lcl_abap_to_json IMPLEMENTATION. DATA lo_converter TYPE REF TO lcl_abap_to_json. lo_type = cl_abap_typedescr=>describe_by_data( iv_data ). + CREATE OBJECT lo_converter. + lo_converter->mi_custom_mapping = ii_custom_mapping. lo_converter->mv_keep_item_order = iv_keep_item_order. lo_converter->insert_value_with_type( @@ -1125,6 +1185,15 @@ CLASS lcl_abap_to_json IMPLEMENTATION. -type = iv_type. -order = iv_item_order. + IF mi_custom_mapping IS BOUND. + -name = mi_custom_mapping->to_json( iv_path = is_prefix-path + iv_name = is_prefix-name ). + ENDIF. + + IF -name IS INITIAL. + -name = is_prefix-name. + ENDIF. + ENDMETHOD. ENDCLASS. diff --git a/src/json/zcl_abapgit_ajson.clas.testclasses.abap b/src/json/zcl_abapgit_ajson.clas.testclasses.abap index fa08babb9..3a8b242bb 100644 --- a/src/json/zcl_abapgit_ajson.clas.testclasses.abap +++ b/src/json/zcl_abapgit_ajson.clas.testclasses.abap @@ -1468,8 +1468,6 @@ CLASS ltcl_writer_test DEFINITION FINAL PRIVATE SECTION. - CLASS-DATA gv_sample TYPE string. - METHODS set_ajson FOR TESTING RAISING zcx_abapgit_ajson_error. METHODS set_value FOR TESTING RAISING zcx_abapgit_ajson_error. METHODS ignore_empty FOR TESTING RAISING zcx_abapgit_ajson_error. @@ -1907,7 +1905,6 @@ CLASS ltcl_writer_test IMPLEMENTATION. METHOD arrays_negative. DATA lo_cut TYPE REF TO zcl_abapgit_ajson. - DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. DATA li_writer TYPE REF TO zif_abapgit_ajson_writer. lo_cut = zcl_abapgit_ajson=>create_empty( ). diff --git a/src/json/zcl_abapgit_ajson_mapping.clas.abap b/src/json/zcl_abapgit_ajson_mapping.clas.abap new file mode 100644 index 000000000..f35de2ff9 --- /dev/null +++ b/src/json/zcl_abapgit_ajson_mapping.clas.abap @@ -0,0 +1,80 @@ +CLASS zcl_abapgit_ajson_mapping DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + CLASS-METHODS create_camel_case + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields OPTIONAL + iv_first_json_upper TYPE abap_bool DEFAULT abap_true + RETURNING + VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping. + + CLASS-METHODS create_upper_case + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields OPTIONAL + RETURNING + VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping. + + CLASS-METHODS create_lower_case + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields OPTIONAL + RETURNING + VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping. + + CLASS-METHODS create_field_mapping + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields + RETURNING + VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping. + + PROTECTED SECTION. + + PRIVATE SECTION. + +ENDCLASS. + + + +CLASS zcl_abapgit_ajson_mapping IMPLEMENTATION. + + + METHOD create_camel_case. + + CREATE OBJECT ri_mapping TYPE lcl_mapping_camel + EXPORTING + it_mapping_fields = it_mapping_fields + iv_first_json_upper = iv_first_json_upper. + + ENDMETHOD. + + + METHOD create_upper_case. + + CREATE OBJECT ri_mapping TYPE lcl_mapping_to_upper + EXPORTING + it_mapping_fields = it_mapping_fields. + + ENDMETHOD. + + + METHOD create_lower_case. + + CREATE OBJECT ri_mapping TYPE lcl_mapping_to_lower + EXPORTING + it_mapping_fields = it_mapping_fields. + + ENDMETHOD. + + + METHOD create_field_mapping. + + CREATE OBJECT ri_mapping TYPE lcl_mapping_fields + EXPORTING + it_mapping_fields = it_mapping_fields. + + ENDMETHOD. + + +ENDCLASS. diff --git a/src/json/zcl_abapgit_ajson_mapping.clas.locals_def.abap b/src/json/zcl_abapgit_ajson_mapping.clas.locals_def.abap new file mode 100644 index 000000000..bb89d9894 --- /dev/null +++ b/src/json/zcl_abapgit_ajson_mapping.clas.locals_def.abap @@ -0,0 +1,71 @@ +CLASS lcl_mapping_fields DEFINITION. + + PUBLIC SECTION. + INTERFACES zif_abapgit_ajson_mapping. + + ALIASES to_abap FOR zif_abapgit_ajson_mapping~to_abap. + ALIASES to_json FOR zif_abapgit_ajson_mapping~to_json. + + METHODS constructor + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping~ty_mapping_fields OPTIONAL. + + PROTECTED SECTION. + + PRIVATE SECTION. + DATA mt_mapping_fields TYPE zif_abapgit_ajson_mapping~ty_mapping_fields. + +ENDCLASS. + + +CLASS lcl_mapping_to_upper DEFINITION. + + PUBLIC SECTION. + INTERFACES zif_abapgit_ajson_mapping. + + METHODS constructor + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping~ty_mapping_fields OPTIONAL. + + PROTECTED SECTION. + + PRIVATE SECTION. + DATA mi_mapping_fields TYPE REF TO zif_abapgit_ajson_mapping. + +ENDCLASS. + + +CLASS lcl_mapping_to_lower DEFINITION. + + PUBLIC SECTION. + INTERFACES zif_abapgit_ajson_mapping. + + METHODS constructor + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping~ty_mapping_fields OPTIONAL. + + PROTECTED SECTION. + + PRIVATE SECTION. + DATA mi_mapping_fields TYPE REF TO zif_abapgit_ajson_mapping. + +ENDCLASS. + + +CLASS lcl_mapping_camel DEFINITION. + + PUBLIC SECTION. + INTERFACES zif_abapgit_ajson_mapping. + + METHODS constructor + IMPORTING + it_mapping_fields TYPE zif_abapgit_ajson_mapping~ty_mapping_fields OPTIONAL + iv_first_json_upper TYPE abap_bool DEFAULT abap_true. + + PROTECTED SECTION. + + PRIVATE SECTION. + DATA mv_first_json_upper TYPE abap_bool. + DATA mi_mapping_fields TYPE REF TO zif_abapgit_ajson_mapping. + +ENDCLASS. diff --git a/src/json/zcl_abapgit_ajson_mapping.clas.locals_imp.abap b/src/json/zcl_abapgit_ajson_mapping.clas.locals_imp.abap new file mode 100644 index 000000000..23939c581 --- /dev/null +++ b/src/json/zcl_abapgit_ajson_mapping.clas.locals_imp.abap @@ -0,0 +1,183 @@ +CLASS lcl_mapping_fields IMPLEMENTATION. + + + METHOD constructor. + + DATA ls_mapping_field LIKE LINE OF mt_mapping_fields. + + LOOP AT it_mapping_fields INTO ls_mapping_field. + ls_mapping_field-abap = to_upper( ls_mapping_field-abap ). + INSERT ls_mapping_field INTO TABLE mt_mapping_fields. + ENDLOOP. + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_abap. + + DATA ls_mapping_field LIKE LINE OF mt_mapping_fields. + + READ TABLE mt_mapping_fields INTO ls_mapping_field + WITH KEY json COMPONENTS json = iv_name. + IF sy-subrc = 0. + rv_result = ls_mapping_field-abap. + ENDIF. + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_json. + + DATA lv_field TYPE string. + DATA ls_mapping_field LIKE LINE OF mt_mapping_fields. + + lv_field = to_upper( iv_name ). + + READ TABLE mt_mapping_fields INTO ls_mapping_field + WITH KEY abap COMPONENTS abap = lv_field. + IF sy-subrc = 0. + rv_result = ls_mapping_field-json. + ENDIF. + + ENDMETHOD. + + +ENDCLASS. + + +CLASS lcl_mapping_to_upper IMPLEMENTATION. + + + METHOD constructor. + + mi_mapping_fields = zcl_abapgit_ajson_mapping=>create_field_mapping( it_mapping_fields ). + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_abap. + + rv_result = mi_mapping_fields->to_abap( iv_path = iv_path + iv_name = iv_name ). + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_json. + + rv_result = mi_mapping_fields->to_json( iv_path = iv_path + iv_name = iv_name ). + + IF rv_result IS NOT INITIAL. " Mapping found + RETURN. + ENDIF. + + rv_result = to_upper( iv_name ). + + ENDMETHOD. + + +ENDCLASS. + + +CLASS lcl_mapping_to_lower IMPLEMENTATION. + + + METHOD constructor. + + mi_mapping_fields = zcl_abapgit_ajson_mapping=>create_field_mapping( it_mapping_fields ). + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_abap. + + rv_result = mi_mapping_fields->to_abap( iv_path = iv_path + iv_name = iv_name ). + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_json. + + rv_result = mi_mapping_fields->to_json( iv_path = iv_path + iv_name = iv_name ). + + IF rv_result IS NOT INITIAL. " Mapping found + RETURN. + ENDIF. + + rv_result = to_lower( iv_name ). + + ENDMETHOD. + + +ENDCLASS. + + +CLASS lcl_mapping_camel IMPLEMENTATION. + + + METHOD constructor. + + mi_mapping_fields = zcl_abapgit_ajson_mapping=>create_field_mapping( it_mapping_fields ). + mv_first_json_upper = iv_first_json_upper. + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_abap. + + rv_result = mi_mapping_fields->to_abap( iv_path = iv_path + iv_name = iv_name ). + + IF rv_result IS NOT INITIAL. " Mapping found + RETURN. + ENDIF. + + rv_result = iv_name. + + REPLACE ALL OCCURRENCES OF REGEX `([a-z])([A-Z])` IN rv_result WITH `$1_$2`. + + ENDMETHOD. + + + METHOD zif_abapgit_ajson_mapping~to_json. + + TYPES ty_token TYPE c LENGTH 255. + DATA lt_tokens TYPE STANDARD TABLE OF ty_token. + DATA lv_from TYPE i. + FIELD-SYMBOLS LIKE LINE OF lt_tokens. + + rv_result = mi_mapping_fields->to_json( iv_path = iv_path + iv_name = iv_name ). + + IF rv_result IS NOT INITIAL. " Mapping found + RETURN. + ENDIF. + + rv_result = iv_name. + + REPLACE ALL OCCURRENCES OF `__` IN rv_result WITH `*`. + + TRANSLATE rv_result TO LOWER CASE. + TRANSLATE rv_result USING `/_:_~_`. + + IF mv_first_json_upper = abap_true. + lv_from = 1. + ELSE. + lv_from = 2. + ENDIF. + + SPLIT rv_result AT `_` INTO TABLE lt_tokens. + LOOP AT lt_tokens ASSIGNING FROM lv_from. + TRANSLATE (1) TO UPPER CASE. + ENDLOOP. + + CONCATENATE LINES OF lt_tokens INTO rv_result. + REPLACE ALL OCCURRENCES OF `*` IN rv_result WITH `_`. + + ENDMETHOD. + + +ENDCLASS. diff --git a/src/json/zcl_abapgit_ajson_mapping.clas.testclasses.abap b/src/json/zcl_abapgit_ajson_mapping.clas.testclasses.abap new file mode 100644 index 000000000..e648362c5 --- /dev/null +++ b/src/json/zcl_abapgit_ajson_mapping.clas.testclasses.abap @@ -0,0 +1,269 @@ +CLASS ltcl_camel_case DEFINITION FINAL FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + + PRIVATE SECTION. + METHODS: + to_abap FOR TESTING RAISING zcx_abapgit_ajson_error, + to_json FOR TESTING RAISING zcx_abapgit_ajson_error, + to_json_first_lower FOR TESTING RAISING zcx_abapgit_ajson_error. + +ENDCLASS. + + +CLASS ltcl_camel_case IMPLEMENTATION. + + + METHOD to_abap. + + DATA: + lo_ajson TYPE REF TO zcl_abapgit_ajson, + li_mapping TYPE REF TO zif_abapgit_ajson_mapping. + DATA: + BEGIN OF ls_result, + field_data TYPE string, + END OF ls_result. + + li_mapping = zcl_abapgit_ajson_mapping=>create_camel_case( ). + + lo_ajson = zcl_abapgit_ajson=>parse( iv_json = '{"FieldData":"field_value"}' + ii_custom_mapping = li_mapping ). + + lo_ajson->to_abap( IMPORTING ev_container = ls_result ). + + cl_abap_unit_assert=>assert_equals( + act = ls_result-field_data + exp = 'field_value' ). + + ENDMETHOD. + + + METHOD to_json. + + DATA: + lo_ajson TYPE REF TO zcl_abapgit_ajson, + li_mapping TYPE REF TO zif_abapgit_ajson_mapping. + DATA: + BEGIN OF ls_result, + field_data TYPE string, + END OF ls_result. + + li_mapping = zcl_abapgit_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ). + + ls_result-field_data = 'field_value'. + + lo_ajson = zcl_abapgit_ajson=>create_empty( ii_custom_mapping = li_mapping ). + + lo_ajson->set( iv_path = '/' + iv_val = ls_result ). + + cl_abap_unit_assert=>assert_equals( + act = lo_ajson->stringify( ) + exp = '{"fieldData":"field_value"}' ). + + ENDMETHOD. + + + METHOD to_json_first_lower. + + DATA: + lo_ajson TYPE REF TO zcl_abapgit_ajson, + li_mapping TYPE REF TO zif_abapgit_ajson_mapping. + DATA: + BEGIN OF ls_result, + field_data TYPE string, + END OF ls_result. + + li_mapping = zcl_abapgit_ajson_mapping=>create_camel_case( ). + + ls_result-field_data = 'field_value'. + + lo_ajson = zcl_abapgit_ajson=>create_empty( ii_custom_mapping = li_mapping ). + + lo_ajson->set( iv_path = '/' + iv_val = ls_result ). + + cl_abap_unit_assert=>assert_equals( + act = lo_ajson->stringify( ) + exp = '{"FieldData":"field_value"}' ). + + ENDMETHOD. + + +ENDCLASS. + + + +CLASS ltcl_fields DEFINITION FINAL FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + + PRIVATE SECTION. + METHODS: + to_abap FOR TESTING RAISING zcx_abapgit_ajson_error, + to_json FOR TESTING RAISING zcx_abapgit_ajson_error. +ENDCLASS. + + +CLASS ltcl_fields IMPLEMENTATION. + + + METHOD to_abap. + + DATA: + lo_ajson TYPE REF TO zcl_abapgit_ajson, + li_mapping TYPE REF TO zif_abapgit_ajson_mapping, + lt_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields, + ls_mapping_field LIKE LINE OF lt_mapping_fields. + DATA: + BEGIN OF ls_result, + abap_field TYPE string, + field TYPE string, + END OF ls_result. + + CLEAR ls_mapping_field. + ls_mapping_field-abap = 'ABAP_FIELD'. + ls_mapping_field-json = 'json.field'. + INSERT ls_mapping_field INTO TABLE lt_mapping_fields. + + li_mapping = zcl_abapgit_ajson_mapping=>create_field_mapping( lt_mapping_fields ). + + lo_ajson = + zcl_abapgit_ajson=>parse( iv_json = '{"field":"value","json.field":"field_value"}' + ii_custom_mapping = li_mapping ). + + lo_ajson->to_abap( IMPORTING ev_container = ls_result ). + + cl_abap_unit_assert=>assert_equals( + act = ls_result-abap_field + exp = 'field_value' ). + + cl_abap_unit_assert=>assert_equals( + act = ls_result-field + exp = 'value' ). + + ENDMETHOD. + + + METHOD to_json. + + DATA: + lo_ajson TYPE REF TO zcl_abapgit_ajson, + li_mapping TYPE REF TO zif_abapgit_ajson_mapping, + lt_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields, + ls_mapping_field LIKE LINE OF lt_mapping_fields. + DATA: + BEGIN OF ls_result, + abap_field TYPE string, + field TYPE string, + END OF ls_result. + + CLEAR ls_mapping_field. + ls_mapping_field-abap = 'ABAP_FIELD'. + ls_mapping_field-json = 'json.field'. + INSERT ls_mapping_field INTO TABLE lt_mapping_fields. + + li_mapping = zcl_abapgit_ajson_mapping=>create_field_mapping( lt_mapping_fields ). + + ls_result-abap_field = 'field_value'. + ls_result-field = 'value'. + + lo_ajson = zcl_abapgit_ajson=>create_empty( ii_custom_mapping = li_mapping ). + + lo_ajson->set( iv_path = '/' + iv_val = ls_result ). + + cl_abap_unit_assert=>assert_equals( + act = lo_ajson->stringify( ) + exp = '{"field":"value","json.field":"field_value"}' ). + + ENDMETHOD. + + +ENDCLASS. + + + +CLASS ltcl_to_lower DEFINITION FINAL FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + + PRIVATE SECTION. + METHODS: + to_json FOR TESTING RAISING zcx_abapgit_ajson_error. +ENDCLASS. + + +CLASS ltcl_to_lower IMPLEMENTATION. + + + METHOD to_json. + + DATA: + lo_ajson TYPE REF TO zcl_abapgit_ajson, + li_mapping TYPE REF TO zif_abapgit_ajson_mapping. + DATA: + BEGIN OF ls_result, + field_data TYPE string, + END OF ls_result. + + li_mapping = zcl_abapgit_ajson_mapping=>create_lower_case( ). + + ls_result-field_data = 'field_value'. + + lo_ajson = zcl_abapgit_ajson=>create_empty( ii_custom_mapping = li_mapping ). + + lo_ajson->set( iv_path = '/' + iv_val = ls_result ). + + cl_abap_unit_assert=>assert_equals( + act = lo_ajson->stringify( ) + exp = '{"field_data":"field_value"}' ). + + ENDMETHOD. + + +ENDCLASS. + + + +CLASS ltcl_to_upper DEFINITION FINAL FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + + PRIVATE SECTION. + METHODS: + to_json FOR TESTING RAISING zcx_abapgit_ajson_error. +ENDCLASS. + + +CLASS ltcl_to_upper IMPLEMENTATION. + + + METHOD to_json. + + DATA: + lo_ajson TYPE REF TO zcl_abapgit_ajson, + li_mapping TYPE REF TO zif_abapgit_ajson_mapping. + DATA: + BEGIN OF ls_result, + field_data TYPE string, + END OF ls_result. + + li_mapping = zcl_abapgit_ajson_mapping=>create_upper_case( ). + + ls_result-field_data = 'field_value'. + + lo_ajson = zcl_abapgit_ajson=>create_empty( ii_custom_mapping = li_mapping ). + + lo_ajson->set( iv_path = '/' + iv_val = ls_result ). + + cl_abap_unit_assert=>assert_equals( + act = lo_ajson->stringify( ) + exp = '{"FIELD_DATA":"field_value"}' ). + + ENDMETHOD. + + +ENDCLASS. diff --git a/src/json/zcl_abapgit_ajson_mapping.clas.xml b/src/json/zcl_abapgit_ajson_mapping.clas.xml new file mode 100644 index 000000000..c3dc3e1d6 --- /dev/null +++ b/src/json/zcl_abapgit_ajson_mapping.clas.xml @@ -0,0 +1,17 @@ + + + + + + ZCL_ABAPGIT_AJSON_MAPPING + E + JSON Mapping + 1 + X + X + X + X + + + + diff --git a/src/json/zif_abapgit_ajson_mapping.intf.abap b/src/json/zif_abapgit_ajson_mapping.intf.abap new file mode 100644 index 000000000..6d7b1fc38 --- /dev/null +++ b/src/json/zif_abapgit_ajson_mapping.intf.abap @@ -0,0 +1,27 @@ +INTERFACE zif_abapgit_ajson_mapping + PUBLIC. + + TYPES: + BEGIN OF ty_mapping_field, + abap TYPE string, + json TYPE string, + END OF ty_mapping_field, + ty_mapping_fields TYPE STANDARD TABLE OF ty_mapping_field + WITH UNIQUE SORTED KEY abap COMPONENTS abap + WITH UNIQUE SORTED KEY json COMPONENTS json. + + METHODS to_abap + IMPORTING + !iv_path TYPE string + !iv_name TYPE string + RETURNING + VALUE(rv_result) TYPE string. + + METHODS to_json + IMPORTING + !iv_path TYPE string + !iv_name TYPE string + RETURNING + VALUE(rv_result) TYPE string. + +ENDINTERFACE. diff --git a/src/json/zif_abapgit_ajson_mapping.intf.xml b/src/json/zif_abapgit_ajson_mapping.intf.xml new file mode 100644 index 000000000..b8ec82a29 --- /dev/null +++ b/src/json/zif_abapgit_ajson_mapping.intf.xml @@ -0,0 +1,15 @@ + + + + + + ZIF_ABAPGIT_AJSON_MAPPING + E + AJSON Mapping + 2 + 1 + X + + + +