ajson, Automatic Update (#5695)

This commit is contained in:
github-actions[bot] 2022-07-25 10:34:08 +02:00 committed by GitHub
parent 9ce3b76d54
commit 229548a208
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 187 additions and 112 deletions

View File

@ -73,9 +73,6 @@ CLASS zcl_abapgit_ajson DEFINITION
PRIVATE SECTION.
TYPES:
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.
@ -90,15 +87,19 @@ CLASS zcl_abapgit_ajson DEFINITION
IMPORTING
iv_path TYPE string
RETURNING
VALUE(rt_node_stack) TYPE tty_node_stack
VALUE(rr_end_node) TYPE REF TO zif_abapgit_ajson=>ty_node
RAISING
zcx_abapgit_ajson_error.
METHODS delete_subtree
IMPORTING
iv_path TYPE string
iv_name TYPE string
ir_parent TYPE REF TO zif_abapgit_ajson=>ty_node OPTIONAL
RETURNING
VALUE(rv_deleted) TYPE abap_bool.
VALUE(rs_top_node) TYPE zif_abapgit_ajson=>ty_node.
METHODS read_only_watchdog
RAISING
zcx_abapgit_ajson_error.
ENDCLASS.
@ -146,36 +147,30 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD delete_subtree.
DATA lv_parent_path TYPE string.
DATA lv_parent_path_len TYPE i.
FIELD-SYMBOLS <node> LIKE LINE OF mt_json_tree.
READ TABLE mt_json_tree ASSIGNING <node>
DATA lr_parent LIKE ir_parent.
READ TABLE mt_json_tree INTO rs_top_node
WITH KEY
path = iv_path
name = iv_name.
IF sy-subrc = 0. " Found ? delete !
IF <node>-children > 0. " only for objects and arrays
lv_parent_path = iv_path && iv_name && '/'.
lv_parent_path_len = strlen( lv_parent_path ).
LOOP AT mt_json_tree ASSIGNING <node>.
IF strlen( <node>-path ) >= lv_parent_path_len
AND substring( val = <node>-path
len = lv_parent_path_len ) = lv_parent_path.
DELETE mt_json_tree INDEX sy-tabix.
ENDIF.
ENDLOOP.
ENDIF.
IF sy-subrc <> 0.
RETURN. " Not found ? nothing to delete !
ENDIF.
DELETE mt_json_tree WHERE path = iv_path AND name = iv_name.
rv_deleted = abap_true.
DELETE mt_json_tree INDEX sy-tabix. " where path = iv_path and name = iv_name.
DATA ls_path TYPE zif_abapgit_ajson=>ty_path_name.
ls_path = lcl_utils=>split_path( iv_path ).
READ TABLE mt_json_tree ASSIGNING <node>
WITH KEY
path = ls_path-path
name = ls_path-name.
IF sy-subrc = 0.
<node>-children = <node>-children - 1.
IF rs_top_node-children > 0. " only for objects and arrays
lv_parent_path = iv_path && iv_name && '/*'.
DELETE mt_json_tree WHERE path CP lv_parent_path.
ENDIF.
" decrement parent children
IF ir_parent IS SUPPLIED.
ir_parent->children = ir_parent->children - 1.
ELSE.
lr_parent = get_item( iv_path ).
IF lr_parent IS NOT INITIAL.
lr_parent->children = lr_parent->children - 1.
ENDIF.
ENDIF.
@ -219,8 +214,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD prove_path_exists.
DATA lt_path TYPE string_table.
DATA lr_node LIKE LINE OF rt_node_stack.
DATA lr_node_parent LIKE LINE OF rt_node_stack.
DATA lr_node_parent LIKE rr_end_node.
DATA lv_cur_path TYPE string.
DATA lv_cur_name TYPE string.
DATA ls_new_node LIKE LINE OF mt_json_tree.
@ -229,8 +223,8 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
DELETE lt_path WHERE table_line IS INITIAL.
DO.
lr_node_parent = lr_node.
READ TABLE mt_json_tree REFERENCE INTO lr_node
lr_node_parent = rr_end_node.
READ TABLE mt_json_tree REFERENCE INTO rr_end_node
WITH KEY
path = lv_cur_path
name = lv_cur_name.
@ -247,9 +241,8 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ls_new_node-path = lv_cur_path.
ls_new_node-name = lv_cur_name.
ls_new_node-type = zif_abapgit_ajson=>node_type-object.
INSERT ls_new_node INTO TABLE mt_json_tree REFERENCE INTO lr_node.
INSERT ls_new_node INTO TABLE mt_json_tree REFERENCE INTO rr_end_node.
ENDIF.
INSERT lr_node INTO rt_node_stack INDEX 1.
lv_cur_path = lv_cur_path && lv_cur_name && '/'.
READ TABLE lt_path INDEX sy-index INTO lv_cur_name.
IF sy-subrc <> 0.
@ -257,8 +250,13 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDIF.
ENDDO.
ASSERT lv_cur_path = iv_path. " Just in case
ENDMETHOD.
METHOD read_only_watchdog.
IF mv_read_only = abap_true.
zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ).
ENDIF.
ENDMETHOD.
@ -303,10 +301,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~clear.
IF mv_read_only = abap_true.
zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ).
ENDIF.
read_only_watchdog( ).
CLEAR mt_json_tree.
ENDMETHOD.
@ -314,9 +309,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~delete.
IF mv_read_only = abap_true.
zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ).
ENDIF.
read_only_watchdog( ).
DATA ls_split_path TYPE zif_abapgit_ajson=>ty_path_name.
ls_split_path = lcl_utils=>split_path( iv_path ).
@ -331,13 +324,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~exists.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lv_item = get_item( iv_path ).
IF lv_item IS NOT INITIAL.
rv_exists = abap_true.
ENDIF.
rv_exists = boolc( get_item( iv_path ) IS NOT INITIAL ).
ENDMETHOD.
@ -354,10 +341,10 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~get.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lv_item = get_item( iv_path ).
IF lv_item IS NOT INITIAL.
rv_value = lv_item->value.
DATA lr_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lr_item = get_item( iv_path ).
IF lr_item IS NOT INITIAL.
rv_value = lr_item->value.
ENDIF.
ENDMETHOD.
@ -365,13 +352,13 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~get_boolean.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lv_item = get_item( iv_path ).
IF lv_item IS INITIAL OR lv_item->type = zif_abapgit_ajson=>node_type-null.
DATA lr_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lr_item = get_item( iv_path ).
IF lr_item IS INITIAL OR lr_item->type = zif_abapgit_ajson=>node_type-null.
RETURN.
ELSEIF lv_item->type = zif_abapgit_ajson=>node_type-boolean.
rv_value = boolc( lv_item->value = 'true' ).
ELSEIF lv_item->value IS NOT INITIAL.
ELSEIF lr_item->type = zif_abapgit_ajson=>node_type-boolean.
rv_value = boolc( lr_item->value = 'true' ).
ELSEIF lr_item->value IS NOT INITIAL.
rv_value = abap_true.
ENDIF.
@ -380,16 +367,16 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~get_date.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
DATA lr_item TYPE REF TO zif_abapgit_ajson=>ty_node.
DATA lv_y TYPE c LENGTH 4.
DATA lv_m TYPE c LENGTH 2.
DATA lv_d TYPE c LENGTH 2.
lv_item = get_item( iv_path ).
lr_item = get_item( iv_path ).
IF lv_item IS NOT INITIAL AND lv_item->type = zif_abapgit_ajson=>node_type-string.
IF lr_item IS NOT INITIAL AND lr_item->type = zif_abapgit_ajson=>node_type-string.
FIND FIRST OCCURRENCE OF REGEX '^(\d{4})-(\d{2})-(\d{2})(T|$)'
IN lv_item->value
IN lr_item->value
SUBMATCHES lv_y lv_m lv_d.
CONCATENATE lv_y lv_m lv_d INTO rv_value.
ENDIF.
@ -399,10 +386,10 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~get_integer.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lv_item = get_item( iv_path ).
IF lv_item IS NOT INITIAL AND lv_item->type = zif_abapgit_ajson=>node_type-number.
rv_value = lv_item->value.
DATA lr_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lr_item = get_item( iv_path ).
IF lr_item IS NOT INITIAL AND lr_item->type = zif_abapgit_ajson=>node_type-number.
rv_value = lr_item->value.
ENDIF.
ENDMETHOD.
@ -410,10 +397,10 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~get_node_type.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lv_item = get_item( iv_path ).
IF lv_item IS NOT INITIAL.
rv_node_type = lv_item->type.
DATA lr_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lr_item = get_item( iv_path ).
IF lr_item IS NOT INITIAL.
rv_node_type = lr_item->type.
ENDIF.
ENDMETHOD.
@ -421,10 +408,10 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~get_number.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lv_item = get_item( iv_path ).
IF lv_item IS NOT INITIAL AND lv_item->type = zif_abapgit_ajson=>node_type-number.
rv_value = lv_item->value.
DATA lr_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lr_item = get_item( iv_path ).
IF lr_item IS NOT INITIAL AND lr_item->type = zif_abapgit_ajson=>node_type-number.
rv_value = lr_item->value.
ENDIF.
ENDMETHOD.
@ -432,10 +419,10 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~get_string.
DATA lv_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lv_item = get_item( iv_path ).
IF lv_item IS NOT INITIAL AND lv_item->type <> zif_abapgit_ajson=>node_type-null.
rv_value = lv_item->value.
DATA lr_item TYPE REF TO zif_abapgit_ajson=>ty_node.
lr_item = get_item( iv_path ).
IF lr_item IS NOT INITIAL AND lr_item->type <> zif_abapgit_ajson=>node_type-null.
rv_value = lr_item->value.
ENDIF.
ENDMETHOD.
@ -493,9 +480,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
DATA lr_parent TYPE REF TO zif_abapgit_ajson=>ty_node.
DATA lr_new_node TYPE REF TO zif_abapgit_ajson=>ty_node.
IF mv_read_only = abap_true.
zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ).
ENDIF.
read_only_watchdog( ).
lr_parent = get_item( iv_path ).
@ -536,11 +521,9 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
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.
DATA ls_deleted_node TYPE zif_abapgit_ajson=>ty_node.
IF mv_read_only = abap_true.
zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ).
ENDIF.
read_only_watchdog( ).
ri_json = me.
@ -576,14 +559,14 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDIF.
" Ensure whole path exists
lt_node_stack = prove_path_exists( ls_split_path-path ).
READ TABLE lt_node_stack INDEX 1 INTO lr_parent.
ASSERT sy-subrc = 0.
lr_parent = prove_path_exists( ls_split_path-path ).
ASSERT lr_parent IS NOT INITIAL.
" delete if exists with subtree
delete_subtree(
iv_path = ls_split_path-path
iv_name = ls_split_path-name ).
ls_deleted_node = delete_subtree(
ir_parent = lr_parent
iv_path = ls_split_path-path
iv_name = ls_split_path-name ).
" convert to json
DATA lt_new_nodes TYPE zif_abapgit_ajson=>ty_nodes_tt.
@ -599,6 +582,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
lt_new_nodes = lcl_abap_to_json=>insert_with_type(
iv_format_datetime = mv_format_datetime
iv_keep_item_order = mv_keep_item_order
iv_item_order = ls_deleted_node-order
iv_data = iv_val
iv_type = iv_node_type
iv_array_index = lv_array_index
@ -608,13 +592,14 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
lt_new_nodes = lcl_abap_to_json=>convert(
iv_format_datetime = mv_format_datetime
iv_keep_item_order = mv_keep_item_order
iv_item_order = ls_deleted_node-order
iv_data = iv_val
iv_array_index = lv_array_index
is_prefix = ls_split_path
ii_custom_mapping = mi_custom_mapping ).
ENDIF.
" update data
" update nodes
IF lines( lt_new_nodes ) > 0.
lr_parent->children = lr_parent->children + 1.
INSERT LINES OF lt_new_nodes INTO TABLE mt_json_tree.
@ -751,12 +736,11 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~touch_array.
DATA lr_node TYPE REF TO zif_abapgit_ajson=>ty_node.
DATA ls_deleted_node TYPE zif_abapgit_ajson=>ty_node.
DATA ls_new_node LIKE LINE OF mt_json_tree.
DATA ls_split_path TYPE zif_abapgit_ajson=>ty_path_name.
IF mv_read_only = abap_true.
zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ).
ENDIF.
read_only_watchdog( ).
ls_split_path = lcl_utils=>split_path( iv_path ).
IF ls_split_path IS INITIAL. " Assign root, exceptional processing
@ -768,7 +752,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDIF.
IF iv_clear = abap_true.
delete_subtree(
ls_deleted_node = delete_subtree(
iv_path = ls_split_path-path
iv_name = ls_split_path-name ).
ELSE.
@ -778,16 +762,19 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
IF lr_node IS INITIAL. " Or node was cleared
DATA lr_parent TYPE REF TO zif_abapgit_ajson=>ty_node.
DATA lt_node_stack TYPE tty_node_stack.
lr_parent = prove_path_exists( ls_split_path-path ).
ASSERT lr_parent IS NOT INITIAL.
lt_node_stack = prove_path_exists( ls_split_path-path ).
READ TABLE lt_node_stack INDEX 1 INTO lr_parent.
ASSERT sy-subrc = 0.
lr_parent->children = lr_parent->children + 1.
ls_new_node-path = ls_split_path-path.
ls_new_node-name = ls_split_path-name.
ls_new_node-type = zif_abapgit_ajson=>node_type-array.
IF mv_keep_item_order = abap_true AND ls_deleted_node IS NOT INITIAL.
ls_new_node-order = ls_deleted_node-order.
ENDIF.
INSERT ls_new_node INTO TABLE mt_json_tree.
ELSEIF lr_node->type <> zif_abapgit_ajson=>node_type-array.

View File

@ -1058,6 +1058,7 @@ CLASS lcl_abap_to_json DEFINITION FINAL.
ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
iv_keep_item_order TYPE abap_bool DEFAULT abap_false
iv_format_datetime TYPE abap_bool DEFAULT abap_false
iv_item_order TYPE i DEFAULT 0
RETURNING
VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt
RAISING
@ -1072,6 +1073,7 @@ CLASS lcl_abap_to_json DEFINITION FINAL.
ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
iv_keep_item_order TYPE abap_bool DEFAULT abap_false
iv_format_datetime TYPE abap_bool DEFAULT abap_false
iv_item_order TYPE i DEFAULT 0
RETURNING
VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt
RAISING
@ -1212,10 +1214,11 @@ CLASS lcl_abap_to_json IMPLEMENTATION.
lo_converter->convert_any(
EXPORTING
iv_data = iv_data
io_type = lo_type
is_prefix = is_prefix
iv_index = iv_array_index
iv_data = iv_data
io_type = lo_type
is_prefix = is_prefix
iv_index = iv_array_index
iv_item_order = iv_item_order
CHANGING
ct_nodes = rt_nodes ).
@ -1614,11 +1617,12 @@ CLASS lcl_abap_to_json IMPLEMENTATION.
lo_converter->insert_value_with_type(
EXPORTING
iv_data = iv_data
iv_type = iv_type
io_type = lo_type
is_prefix = is_prefix
iv_index = iv_array_index
iv_data = iv_data
iv_type = iv_type
io_type = lo_type
is_prefix = is_prefix
iv_index = iv_array_index
iv_item_order = iv_item_order
CHANGING
ct_nodes = rt_nodes ).

View File

@ -1881,6 +1881,8 @@ CLASS ltcl_writer_test DEFINITION FINAL
METHODS read_only FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_array_obj FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_with_type FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS overwrite_w_keep_order_touch FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS overwrite_w_keep_order_set FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_with_type_slice
IMPORTING
@ -2908,6 +2910,86 @@ CLASS ltcl_writer_test IMPLEMENTATION.
ENDMETHOD.
METHOD overwrite_w_keep_order_set.
DATA li_cut TYPE REF TO zif_abapgit_ajson.
DATA:
BEGIN OF ls_dummy,
b TYPE i,
a TYPE i,
END OF ls_dummy.
li_cut = zcl_abapgit_ajson=>create_empty(
)->set(
iv_ignore_empty = abap_false
iv_path = '/'
iv_val = ls_dummy ).
cl_abap_unit_assert=>assert_equals(
act = li_cut->stringify( )
exp = '{"a":0,"b":0}' ). " ordered by path, name
li_cut = zcl_abapgit_ajson=>create_empty(
)->keep_item_order(
)->set(
iv_ignore_empty = abap_false
iv_path = '/'
iv_val = ls_dummy ).
cl_abap_unit_assert=>assert_equals(
act = li_cut->stringify( )
exp = '{"b":0,"a":0}' ). " ordered by structure order
li_cut->set(
iv_path = '/a'
iv_val = 1 ).
cl_abap_unit_assert=>assert_equals(
act = li_cut->stringify( )
exp = '{"b":0,"a":1}' ). " still ordered after overwrite
ENDMETHOD.
METHOD overwrite_w_keep_order_touch.
DATA li_cut TYPE REF TO zif_abapgit_ajson.
DATA:
BEGIN OF ls_dummy,
b TYPE i,
a TYPE string_table,
END OF ls_dummy.
li_cut = zcl_abapgit_ajson=>create_empty(
)->set(
iv_ignore_empty = abap_false
iv_path = '/'
iv_val = ls_dummy ).
cl_abap_unit_assert=>assert_equals(
act = li_cut->stringify( )
exp = '{"a":[],"b":0}' ). " ordered by path, name
li_cut = zcl_abapgit_ajson=>create_empty(
)->keep_item_order(
)->set(
iv_ignore_empty = abap_false
iv_path = '/'
iv_val = ls_dummy ).
cl_abap_unit_assert=>assert_equals(
act = li_cut->stringify( )
exp = '{"b":0,"a":[]}' ). " ordered by structure order
li_cut->touch_array(
iv_path = '/a'
iv_clear = abap_true ).
cl_abap_unit_assert=>assert_equals(
act = li_cut->stringify( )
exp = '{"b":0,"a":[]}' ). " still ordered after touch with clear
ENDMETHOD.
ENDCLASS.

View File

@ -150,6 +150,8 @@
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "set_bool_int"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "set_bool_tab"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "set_obj_w_date_time"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "overwrite_w_keep_order_touch"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "overwrite_w_keep_order_set"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "set_tab_hashed", "note": "runtime error, SortByLengthZero"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_integrated", "method": "reader", "note": "keyword? Path not found @/false"},